From fafeac3517a8c2c702bf3f65dfe4ac0493eb5874 Mon Sep 17 00:00:00 2001 From: Sergey Silkin Date: Fri, 13 Apr 2018 16:36:39 +0200 Subject: [PATCH] Use codec's bitrate limits if SVC is off. Adding SVC rate allocator and layering configurator caused regression for VP9 non-SVC senders. SVC bitrate limits, which were supposed to be used only when spatial layering is enabled, are applied when encoding single spatial layer. E.g. for VP9 360p sender maximum bitrate is limited to 500kbps. This fixes the regression. If sender is configured to send VP9 single layer then codec's bitrate limits are applied to this layer. Bug: webrtc:9151, chromium:831093 Change-Id: Ia1ae4087155ad7917a3443304a21532f1e68ea65 Reviewed-on: https://webrtc-review.googlesource.com/69813 Commit-Queue: Sergey Silkin Reviewed-by: Michael Horowitz Reviewed-by: Rasmus Brandt Cr-Commit-Position: refs/heads/master@{#22862} --- .../video_coding/codecs/vp9/svc_rate_allocator.cc | 6 +++++- modules/video_coding/video_codec_initializer.cc | 7 +++++++ .../video_coding/video_codec_initializer_unittest.cc | 12 ++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/video_coding/codecs/vp9/svc_rate_allocator.cc b/modules/video_coding/codecs/vp9/svc_rate_allocator.cc index 4e72790f7f..48d22fdfb1 100644 --- a/modules/video_coding/codecs/vp9/svc_rate_allocator.cc +++ b/modules/video_coding/codecs/vp9/svc_rate_allocator.cc @@ -35,6 +35,10 @@ BitrateAllocation SvcRateAllocator::GetAllocation(uint32_t total_bitrate_bps, size_t num_temporal_layers = codec_.VP9().numberOfTemporalLayers; RTC_CHECK(num_temporal_layers > 0); + if (codec_.maxBitrate != 0) { + total_bitrate_bps = std::min(total_bitrate_bps, codec_.maxBitrate * 1000); + } + if (codec_.mode == kScreensharing) { // At screen sharing bitrate allocation is handled by VP9 encoder wrapper. bitrate_allocation.SetBitrate(0, 0, total_bitrate_bps); @@ -62,7 +66,7 @@ BitrateAllocation SvcRateAllocator::GetAllocation(uint32_t total_bitrate_bps, size_t excess_rate = 0; for (size_t sl_idx = 0; sl_idx < num_spatial_layers; ++sl_idx) { RTC_DCHECK_GT(codec_.spatialLayers[sl_idx].maxBitrate, 0); - RTC_DCHECK_GT(codec_.spatialLayers[sl_idx].maxBitrate, + RTC_DCHECK_GE(codec_.spatialLayers[sl_idx].maxBitrate, codec_.spatialLayers[sl_idx].minBitrate); const size_t min_bitrate_bps = diff --git a/modules/video_coding/video_codec_initializer.cc b/modules/video_coding/video_codec_initializer.cc index e340b46b6f..a0ec33f98d 100644 --- a/modules/video_coding/video_codec_initializer.cc +++ b/modules/video_coding/video_codec_initializer.cc @@ -222,6 +222,13 @@ VideoCodec VideoCodecInitializer::VideoEncoderConfigToVideoCodec( GetSvcConfig(video_codec.width, video_codec.height, video_codec.VP9()->numberOfSpatialLayers, video_codec.VP9()->numberOfTemporalLayers); + + const bool no_spatial_layering = (spatial_layers.size() == 1); + if (no_spatial_layering) { + // Use codec's bitrate limits. + spatial_layers.back().minBitrate = video_codec.minBitrate; + spatial_layers.back().maxBitrate = video_codec.maxBitrate; + } } RTC_DCHECK(!spatial_layers.empty()); diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc index 4a39399660..2bb67cb439 100644 --- a/modules/video_coding/video_codec_initializer_unittest.cc +++ b/modules/video_coding/video_codec_initializer_unittest.cc @@ -272,4 +272,16 @@ TEST_F(VideoCodecInitializerTest, Vp9SvcAdjustedLayering) { EXPECT_EQ(codec_out_.VP9()->numberOfSpatialLayers, 2u); } +TEST_F(VideoCodecInitializerTest, + Vp9SingleSpatialLayerMaxBitrateIsEqualToCodecMaxBitrate) { + SetUpFor(VideoCodecType::kVideoCodecVP9, 1, 3, false); + VideoStream stream = DefaultStream(); + stream.num_temporal_layers = 3; + streams_.push_back(stream); + + EXPECT_TRUE(InitializeCodec()); + EXPECT_EQ(codec_out_.spatialLayers[0].maxBitrate, + kDefaultMaxBitrateBps / 1000); +} + } // namespace webrtc