From d92288f5babdafe409880ebd170d9a6feb0b9600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Spr=C3=A5ng?= Date: Wed, 4 Jul 2018 10:07:40 +0200 Subject: [PATCH] Add experimental shortened 2-temporal-layer setting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also adjust to base-layer fraction for the shortened 3-tl pattern to be 60%, just like the 2-tl setting. This CL removes direct use of the allocation matrix and moves it behind a static getter. Bug: webrtc:9477 Change-Id: Ifd7d1edffa0555024fd252834357b926997d13b5 Reviewed-on: https://webrtc-review.googlesource.com/86681 Commit-Queue: Erik Språng Reviewed-by: Rasmus Brandt Cr-Commit-Position: refs/heads/master@{#23834} --- media/engine/simulcast.cc | 13 +-- .../codecs/vp8/default_temporal_layers.cc | 79 +++++++++++++------ modules/video_coding/media_opt_util.cc | 4 +- .../utility/simulcast_rate_allocator.cc | 31 +++++++- .../utility/simulcast_rate_allocator.h | 12 +-- modules/video_coding/video_sender_unittest.cc | 12 ++- 6 files changed, 105 insertions(+), 46 deletions(-) diff --git a/media/engine/simulcast.cc b/media/engine/simulcast.cc index 77c7dbdf53..722890c6dd 100644 --- a/media/engine/simulcast.cc +++ b/media/engine/simulcast.cc @@ -245,13 +245,14 @@ std::vector GetNormalSimulcastLayers( int num_temporal_layers = DefaultNumberOfTemporalLayers(s); if (s == 0 && num_temporal_layers != 3) { // If alternative number temporal layers is selected, adjust the - // bitrate of the lowest simulcast stream so that absolute bitrate for the - // base temporal layer matches the bitrate for the base temporal layer - // with the default 3 simulcast streams. Otherwise we risk a higher - // threshold for receiving a feed at all. + // bitrate of the lowest simulcast stream so that absolute bitrate for + // the base temporal layer matches the bitrate for the base temporal + // layer with the default 3 simulcast streams. Otherwise we risk a + // higher threshold for receiving a feed at all. const float rate_factor = - webrtc::kLayerRateAllocation[3][0] / - webrtc::kLayerRateAllocation[num_temporal_layers][0]; + webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 0) / + webrtc::SimulcastRateAllocator::GetTemporalRateAllocation( + num_temporal_layers, 0); layers[s].max_bitrate_bps = static_cast(layers[s].max_bitrate_bps * rate_factor); layers[s].target_bitrate_bps = diff --git a/modules/video_coding/codecs/vp8/default_temporal_layers.cc b/modules/video_coding/codecs/vp8/default_temporal_layers.cc index 986c5ad9f0..03c582a84f 100644 --- a/modules/video_coding/codecs/vp8/default_temporal_layers.cc +++ b/modules/video_coding/codecs/vp8/default_temporal_layers.cc @@ -93,7 +93,11 @@ std::vector GetTemporalLayerSync(size_t num_layers) { case 1: return {false}; case 2: - return {false, true, false, false, false, false, false, false}; + if (field_trial::IsEnabled("WebRTC-UseShortVP8TL2Pattern")) { + return {false, true, false, false}; + } else { + return {false, true, false, false, false, false, false, false}; + } case 3: if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) { return {false, true, true, false}; @@ -135,30 +139,55 @@ std::vector GetTemporalPattern(size_t num_layers) { // that the 'alt' buffer reference is effectively the last keyframe. // TL0 also references and updates the 'last' buffer. // TL1 also references 'last' and references and updates 'golden'. - return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, - TemporalLayers::kNone, - TemporalLayers::kReference), - TemporalLayers::FrameConfig(TemporalLayers::kReference, - TemporalLayers::kUpdate, - TemporalLayers::kReference), - TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, - TemporalLayers::kNone, - TemporalLayers::kReference), - TemporalLayers::FrameConfig(TemporalLayers::kReference, - TemporalLayers::kReferenceAndUpdate, - TemporalLayers::kReference), - TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, - TemporalLayers::kNone, - TemporalLayers::kReference), - TemporalLayers::FrameConfig(TemporalLayers::kReference, - TemporalLayers::kReferenceAndUpdate, - TemporalLayers::kReference), - TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, - TemporalLayers::kNone, - TemporalLayers::kReference), - TemporalLayers::FrameConfig( - TemporalLayers::kReference, TemporalLayers::kReference, - TemporalLayers::kReference, TemporalLayers::kFreezeEntropy)}; + if (field_trial::IsEnabled("WebRTC-UseShortVP8TL2Pattern")) { + // Shortened 4-frame pattern: + // 1---1 1---1 ... + // / / / / + // 0---0---0---0 ... + return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kNone, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReference, + TemporalLayers::kUpdate, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kNone, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReference, + TemporalLayers::kReference, + TemporalLayers::kReference, + TemporalLayers::kFreezeEntropy)}; + } else { + // "Default" 8-frame pattern: + // 1---1---1---1 1---1---1---1 ... + // / / / / / / / / + // 0---0---0---0---0---0---0---0 ... + return {TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kNone, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReference, + TemporalLayers::kUpdate, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kNone, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReference, + TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kNone, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReference, + TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReferenceAndUpdate, + TemporalLayers::kNone, + TemporalLayers::kReference), + TemporalLayers::FrameConfig(TemporalLayers::kReference, + TemporalLayers::kReference, + TemporalLayers::kReference, + TemporalLayers::kFreezeEntropy)}; + } case 3: if (field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) { // This field trial is intended to check if it is worth using a shorter diff --git a/modules/video_coding/media_opt_util.cc b/modules/video_coding/media_opt_util.cc index 776dd9d29d..ca9620f85e 100644 --- a/modules/video_coding/media_opt_util.cc +++ b/modules/video_coding/media_opt_util.cc @@ -400,7 +400,9 @@ bool VCMFecMethod::ProtectionFactor(const VCMProtectionParameters* parameters) { int VCMFecMethod::BitsPerFrame(const VCMProtectionParameters* parameters) { // When temporal layers are available FEC will only be applied on the base // layer. - const float bitRateRatio = kLayerRateAllocation[parameters->numLayers - 1][0]; + const float bitRateRatio = + webrtc::SimulcastRateAllocator::GetTemporalRateAllocation( + parameters->numLayers, 0); float frameRateRatio = powf(1 / 2.0, parameters->numLayers - 1); float bitRate = parameters->bitRate * bitRateRatio; float frameRate = parameters->frameRate * frameRateRatio; diff --git a/modules/video_coding/utility/simulcast_rate_allocator.cc b/modules/video_coding/utility/simulcast_rate_allocator.cc index b33b1e8568..8e98c8d721 100644 --- a/modules/video_coding/utility/simulcast_rate_allocator.cc +++ b/modules/video_coding/utility/simulcast_rate_allocator.cc @@ -17,8 +17,37 @@ #include "common_types.h" // NOLINT(build/include) #include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" namespace webrtc { +namespace { +// Ratio allocation between temporal streams: +// Values as required for the VP8 codec (accumulating). +static const float + kLayerRateAllocation[kMaxTemporalStreams][kMaxTemporalStreams] = { + {1.0f, 1.0f, 1.0f, 1.0f}, // 1 layer + {0.6f, 1.0f, 1.0f, 1.0f}, // 2 layers {60%, 40%} + {0.4f, 0.6f, 1.0f, 1.0f}, // 3 layers {40%, 20%, 40%} + {0.25f, 0.4f, 0.6f, 1.0f} // 4 layers {25%, 15%, 20%, 40%} +}; + +static const float kShort3TlRateAllocation[kMaxTemporalStreams] = { + 0.6f, 0.8f, 1.0f, 1.0f // 3 layers {60%, 20%, 20%} +}; +} // namespace + +float SimulcastRateAllocator::GetTemporalRateAllocation(int num_layers, + int temporal_id) { + RTC_CHECK_GT(num_layers, 0); + RTC_CHECK_LE(num_layers, kMaxTemporalStreams); + RTC_CHECK_GE(temporal_id, 0); + RTC_CHECK_LT(temporal_id, num_layers); + if (num_layers == 3 && + field_trial::IsEnabled("WebRTC-UseShortVP8TL3Pattern")) { + return kShort3TlRateAllocation[temporal_id]; + } + return kLayerRateAllocation[num_layers - 1][temporal_id]; +} SimulcastRateAllocator::SimulcastRateAllocator(const VideoCodec& codec) : codec_(codec) {} @@ -190,7 +219,7 @@ std::vector SimulcastRateAllocator::DefaultTemporalLayerAllocation( std::vector bitrates; for (size_t i = 0; i < num_temporal_layers; ++i) { float layer_bitrate = - bitrate_kbps * kLayerRateAllocation[num_temporal_layers - 1][i]; + bitrate_kbps * GetTemporalRateAllocation(num_temporal_layers, i); bitrates.push_back(static_cast(layer_bitrate + 0.5)); } diff --git a/modules/video_coding/utility/simulcast_rate_allocator.h b/modules/video_coding/utility/simulcast_rate_allocator.h index daa1523e00..5aaf515606 100644 --- a/modules/video_coding/utility/simulcast_rate_allocator.h +++ b/modules/video_coding/utility/simulcast_rate_allocator.h @@ -24,16 +24,6 @@ namespace webrtc { -// Ratio allocation between temporal streams: -// Values as required for the VP8 codec (accumulating). -static const float - kLayerRateAllocation[kMaxSimulcastStreams][kMaxTemporalStreams] = { - {1.0f, 1.0f, 1.0f, 1.0f}, // 1 layer - {0.6f, 1.0f, 1.0f, 1.0f}, // 2 layers {60%, 40%} - {0.4f, 0.6f, 1.0f, 1.0f}, // 3 layers {40%, 20%, 40%} - {0.25f, 0.4f, 0.6f, 1.0f} // 4 layers {25%, 15%, 20%, 40%} -}; - class SimulcastRateAllocator : public VideoBitrateAllocator { public: explicit SimulcastRateAllocator(const VideoCodec& codec); @@ -42,6 +32,8 @@ class SimulcastRateAllocator : public VideoBitrateAllocator { uint32_t framerate) override; const VideoCodec& GetCodec() const; + static float GetTemporalRateAllocation(int num_layers, int temporal_id); + private: void DistributeAllocationToSimulcastLayers( uint32_t total_bitrate_bps, diff --git a/modules/video_coding/video_sender_unittest.cc b/modules/video_coding/video_sender_unittest.cc index 7d729664bc..c391510ec1 100644 --- a/modules/video_coding/video_sender_unittest.cc +++ b/modules/video_coding/video_sender_unittest.cc @@ -471,9 +471,15 @@ class TestVideoSenderWithVp8 : public TestVideoSender { #define MAYBE_FixedTemporalLayersStrategy FixedTemporalLayersStrategy #endif TEST_F(TestVideoSenderWithVp8, MAYBE_FixedTemporalLayersStrategy) { - const int low_b = codec_bitrate_kbps_ * kLayerRateAllocation[2][0]; - const int mid_b = codec_bitrate_kbps_ * kLayerRateAllocation[2][1]; - const int high_b = codec_bitrate_kbps_ * kLayerRateAllocation[2][2]; + const int low_b = + codec_bitrate_kbps_ * + webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 0); + const int mid_b = + codec_bitrate_kbps_ * + webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 1); + const int high_b = + codec_bitrate_kbps_ * + webrtc::SimulcastRateAllocator::GetTemporalRateAllocation(3, 2); { Vp8StreamInfo expected = {{7.5, 15.0, 30.0}, {low_b, mid_b, high_b}}; EXPECT_THAT(SimulateWithFramerate(30.0), MatchesVp8StreamInfo(expected));