diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index d7e2ce198c..6b982a8a13 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -160,6 +160,8 @@ VP9EncoderImpl::VP9EncoderImpl(const cricket::VideoCodec& codec) num_temporal_layers_(0), num_spatial_layers_(0), num_active_spatial_layers_(0), + layer_deactivation_requires_key_frame_(webrtc::field_trial::IsEnabled( + "WebRTC-Vp9IssueKeyFrameOnLayerDeactivation")), is_svc_(false), inter_layer_pred_(InterLayerPredMode::kOn), external_ref_control_( @@ -212,8 +214,12 @@ bool VP9EncoderImpl::SetSvcRates( config_->rc_target_bitrate = bitrate_allocation.get_sum_kbps(); if (ExplicitlyConfiguredSpatialLayers()) { + const bool layer_activation_requires_key_frame = + inter_layer_pred_ == InterLayerPredMode::kOff || + inter_layer_pred_ == InterLayerPredMode::kOnKeyPic; + for (size_t sl_idx = 0; sl_idx < num_spatial_layers_; ++sl_idx) { - const bool was_layer_enabled = (config_->ss_target_bitrate[sl_idx] > 0); + const bool was_layer_active = (config_->ss_target_bitrate[sl_idx] > 0); config_->ss_target_bitrate[sl_idx] = bitrate_allocation.GetSpatialLayerSum(sl_idx) / 1000; @@ -222,16 +228,16 @@ bool VP9EncoderImpl::SetSvcRates( bitrate_allocation.GetTemporalLayerSum(sl_idx, tl_idx) / 1000; } - const bool is_layer_enabled = (config_->ss_target_bitrate[sl_idx] > 0); - if (is_layer_enabled && !was_layer_enabled) { - if (inter_layer_pred_ == InterLayerPredMode::kOff || - inter_layer_pred_ == InterLayerPredMode::kOnKeyPic) { - // TODO(wemb:1526): remove key frame request when issue is fixed. - force_key_frame_ = true; - } + const bool is_active_layer = (config_->ss_target_bitrate[sl_idx] > 0); + if (!was_layer_active && is_active_layer && + layer_activation_requires_key_frame) { + force_key_frame_ = true; + } else if (was_layer_active && !is_active_layer && + layer_deactivation_requires_key_frame_) { + force_key_frame_ = true; } - if (!was_layer_enabled) { + if (!was_layer_active) { // Reset frame rate controller if layer is resumed after pause. framerate_controller_[sl_idx].Reset(); } diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h index a8ea011d64..d8ce1ff2ab 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.h +++ b/modules/video_coding/codecs/vp9/vp9_impl.h @@ -115,6 +115,7 @@ class VP9EncoderImpl : public VP9Encoder { uint8_t num_temporal_layers_; uint8_t num_spatial_layers_; // Number of configured SLs uint8_t num_active_spatial_layers_; // Number of actively encoded SLs + bool layer_deactivation_requires_key_frame_; bool is_svc_; InterLayerPredMode inter_layer_pred_; bool external_ref_control_; diff --git a/video/full_stack_tests.cc b/video/full_stack_tests.cc index 5e3facde6a..049df6f32e 100644 --- a/video/full_stack_tests.cc +++ b/video/full_stack_tests.cc @@ -816,6 +816,8 @@ TEST(FullStackTest, VP9SVC_3SL_Low) { #if !defined(WEBRTC_MAC) TEST(FullStackTest, VP9KSVC_3SL_High) { + webrtc::test::ScopedFieldTrials override_trials( + AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -829,6 +831,8 @@ TEST(FullStackTest, VP9KSVC_3SL_High) { } TEST(FullStackTest, VP9KSVC_3SL_Medium) { + webrtc::test::ScopedFieldTrials override_trials( + AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -842,6 +846,8 @@ TEST(FullStackTest, VP9KSVC_3SL_Medium) { } TEST(FullStackTest, VP9KSVC_3SL_Low) { + webrtc::test::ScopedFieldTrials override_trials( + AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -855,6 +861,8 @@ TEST(FullStackTest, VP9KSVC_3SL_Low) { } TEST(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted) { + webrtc::test::ScopedFieldTrials override_trials( + AppendFieldTrials("WebRTC-Vp9IssueKeyFrameOnLayerDeactivation/Enabled/")); auto fixture = CreateVideoQualityTestFixture(); ParamsWithLogging simulcast; simulcast.call.send_side_bwe = true; @@ -862,9 +870,10 @@ TEST(FullStackTest, VP9KSVC_3SL_Medium_Network_Restricted) { simulcast.analyzer = {"vp9ksvc_3sl_medium_network_restricted", 0.0, 0.0, kFullStackTestDurationSecs}; simulcast.ss[0] = { - std::vector(), 0, 3, 1, InterLayerPredMode::kOnKeyPic, + std::vector(), 0, 3, -1, InterLayerPredMode::kOnKeyPic, std::vector(), false}; simulcast.config->link_capacity_kbps = 1000; + simulcast.config->queue_delay_ms = 100; fixture->RunWithAnalyzer(simulcast); } #endif // !defined(WEBRTC_MAC)