Unstable BWE due to improper bit rate padding for VP9.
Bug: webrtc:9345 Change-Id: I5b1e0b4ed7a8c1d0b942b09433017cac6d53c64b Reviewed-on: https://webrtc-review.googlesource.com/79000 Commit-Queue: Michael Horowitz <mhoro@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23496}
This commit is contained in:
parent
a7087e37f1
commit
277a656263
@ -14,6 +14,7 @@
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
|
||||
#include "modules/video_coding/codecs/vp9/svc_rate_allocator.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -63,6 +64,7 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
||||
num_spatial_layers =
|
||||
std::min({num_spatial_layers, num_layers_fit_horz, num_layers_fit_vert});
|
||||
|
||||
float top_fraction = 0.;
|
||||
for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) {
|
||||
SpatialLayer spatial_layer = {0};
|
||||
spatial_layer.width = input_width >> (num_spatial_layers - sl_idx - 1);
|
||||
@ -77,17 +79,24 @@ std::vector<SpatialLayer> ConfigureSvcNormalVideo(size_t input_width,
|
||||
// TODO(ssilkin): Add to the comment PSNR/SSIM we get at encoding certain
|
||||
// video to min/max bitrate specified by those formulas.
|
||||
const size_t num_pixels = spatial_layer.width * spatial_layer.height;
|
||||
const size_t min_bitrate =
|
||||
int min_bitrate =
|
||||
static_cast<int>((600. * std::sqrt(num_pixels) - 95000.) / 1000.);
|
||||
spatial_layer.minBitrate = std::max(min_bitrate, kMinVp9SvcBitrateKbps);
|
||||
min_bitrate = std::max(min_bitrate, 0);
|
||||
spatial_layer.minBitrate =
|
||||
std::max(static_cast<size_t>(min_bitrate), kMinVp9SvcBitrateKbps);
|
||||
spatial_layer.maxBitrate =
|
||||
static_cast<int>((1.6 * num_pixels + 50 * 1000) / 1000);
|
||||
spatial_layer.targetBitrate =
|
||||
(spatial_layer.maxBitrate + spatial_layer.minBitrate) / 2;
|
||||
|
||||
(spatial_layer.minBitrate + spatial_layer.maxBitrate) / 2;
|
||||
spatial_layers.push_back(spatial_layer);
|
||||
top_fraction += std::pow(kSpatialLayeringRateScalingFactor, sl_idx);
|
||||
}
|
||||
|
||||
// Compute spatial_layers[num_spatial_layers - 1].targetBitrate, which is
|
||||
// used to set max_padding_bitrate_. Set max_padding_bitrate_ equal to the
|
||||
// minimum total bit rate required to support all spatial layers.
|
||||
spatial_layers[num_spatial_layers - 1].targetBitrate =
|
||||
static_cast<unsigned int>(
|
||||
spatial_layers[num_spatial_layers - 1].minBitrate * top_fraction);
|
||||
return spatial_layers;
|
||||
}
|
||||
|
||||
|
||||
@ -18,10 +18,8 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
const float kSpatialLayeringRateScalingFactor = 0.55f;
|
||||
const float kTemporalLayeringRateScalingFactor = 0.55f;
|
||||
} // namespace
|
||||
|
||||
SvcRateAllocator::SvcRateAllocator(const VideoCodec& codec) : codec_(codec) {
|
||||
RTC_DCHECK_EQ(codec.codecType, kVideoCodecVP9);
|
||||
|
||||
@ -20,6 +20,9 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
extern const float kSpatialLayeringRateScalingFactor;
|
||||
extern const float kTemporalLayeringRateScalingFactor;
|
||||
|
||||
class SvcRateAllocator : public VideoBitrateAllocator {
|
||||
public:
|
||||
explicit SvcRateAllocator(const VideoCodec& codec);
|
||||
|
||||
@ -813,6 +813,20 @@ TEST_F(FullStackTest, VP9KSVC_3SL_Low) {
|
||||
std::vector<SpatialLayer>(), false};
|
||||
RunTest(simulcast);
|
||||
}
|
||||
|
||||
TEST_F(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted) {
|
||||
VideoQualityTest::Params simulcast;
|
||||
simulcast.call.send_side_bwe = true;
|
||||
simulcast.video[0] = kSvcVp9Video;
|
||||
simulcast.analyzer = {"vp9ksvc_3sl_medium_network_restricted", 0.0, 0.0,
|
||||
kFullStackTestDurationSecs};
|
||||
simulcast.ss[0] = {
|
||||
std::vector<VideoStream>(), 0, 3, 1, InterLayerPredMode::kOnKeyPic,
|
||||
std::vector<SpatialLayer>(), false};
|
||||
simulcast.pipe.link_capacity_kbps = 1000;
|
||||
RunTest(simulcast);
|
||||
}
|
||||
|
||||
#endif // !defined(RTC_DISABLE_VP9)
|
||||
|
||||
// Android bots can't handle FullHD, so disable the test.
|
||||
|
||||
@ -633,8 +633,15 @@ void VideoSendStreamImpl::OnEncoderConfigurationChanged(
|
||||
encoder_max_bitrate_bps_ =
|
||||
std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
|
||||
encoder_max_bitrate_bps_);
|
||||
max_padding_bitrate_ = CalculateMaxPadBitrateBps(
|
||||
streams, min_transmit_bitrate_bps, config_->suspend_below_min_bitrate);
|
||||
|
||||
const VideoCodecType codec_type =
|
||||
PayloadStringToCodecType(config_->rtp.payload_name);
|
||||
if (codec_type == kVideoCodecVP9) {
|
||||
max_padding_bitrate_ = streams[0].target_bitrate_bps;
|
||||
} else {
|
||||
max_padding_bitrate_ = CalculateMaxPadBitrateBps(
|
||||
streams, min_transmit_bitrate_bps, config_->suspend_below_min_bitrate);
|
||||
}
|
||||
|
||||
// Clear stats for disabled layers.
|
||||
for (size_t i = streams.size(); i < config_->rtp.ssrcs.size(); ++i) {
|
||||
|
||||
@ -514,6 +514,28 @@ void VideoStreamEncoder::ReconfigureEncoder() {
|
||||
RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
|
||||
}
|
||||
|
||||
// Set min_bitrate_bps, max_bitrate_bps, and max padding bit rate for VP9.
|
||||
if (encoder_config_.codec_type == kVideoCodecVP9) {
|
||||
RTC_DCHECK_EQ(1U, streams.size());
|
||||
int max_encoder_bitrate_kbps = 0;
|
||||
for (int i = 0; i < codec.VP9()->numberOfSpatialLayers; ++i) {
|
||||
max_encoder_bitrate_kbps += codec.spatialLayers[i].maxBitrate;
|
||||
}
|
||||
// Lower max bitrate to the level codec actually can produce.
|
||||
streams[0].max_bitrate_bps =
|
||||
std::min(streams[0].max_bitrate_bps, max_encoder_bitrate_kbps * 1000);
|
||||
streams[0].min_bitrate_bps = codec.spatialLayers[0].minBitrate * 1000;
|
||||
// Pass along the value of maximum padding bit rate from
|
||||
// spatialLayers[].targetBitrate to streams[0].target_bitrate_bps.
|
||||
// TODO(ssilkin): There should be some margin between max padding bitrate
|
||||
// and max encoder bitrate. With the current logic they can be equal.
|
||||
streams[0].target_bitrate_bps =
|
||||
std::min(static_cast<unsigned int>(streams[0].max_bitrate_bps),
|
||||
codec.spatialLayers[codec.VP9()->numberOfSpatialLayers - 1]
|
||||
.targetBitrate *
|
||||
1000);
|
||||
}
|
||||
|
||||
codec.startBitrate =
|
||||
std::max(encoder_start_bitrate_bps_ / 1000, codec.minBitrate);
|
||||
codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user