diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 0c3a3de01e..435ad6c104 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -403,6 +403,21 @@ int NumActiveStreams(const webrtc::RtpParameters& rtp_parameters) { return res; } +absl::optional NumSpatialLayersFromEncoding( + const webrtc::RtpParameters& rtp_parameters, + size_t idx) { + if (idx >= rtp_parameters.encodings.size()) + return absl::nullopt; + + absl::optional scalability_mode = + webrtc::ScalabilityModeFromString( + rtp_parameters.encodings[idx].scalability_mode.value_or("")); + return scalability_mode + ? absl::optional( + ScalabilityModeToNumSpatialLayers(*scalability_mode)) + : absl::nullopt; +} + std::map MergeInfoAboutOutboundRtpSubstreams( const std::map& @@ -525,7 +540,14 @@ WebRtcVideoChannel::WebRtcVideoSendStream::ConfigureVideoEncoderSettings( // VP9 denoising is disabled by default. vp9_settings.denoisingOn = codec_default_denoising ? true : denoising; - vp9_settings.automaticResizeOn = automatic_resize; + // Disable automatic resize if more than one spatial layer is requested. + bool vp9_automatic_resize = automatic_resize; + absl::optional num_spatial_layers = + NumSpatialLayersFromEncoding(rtp_parameters_, /*idx=*/0); + if (num_spatial_layers && *num_spatial_layers > 1) { + vp9_automatic_resize = false; + } + vp9_settings.automaticResizeOn = vp9_automatic_resize; if (!is_screencast) { webrtc::FieldTrialFlag interlayer_pred_experiment_enabled("Enabled"); webrtc::FieldTrialEnum inter_layer_pred_mode( diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc index da95927a68..231fc84f6d 100644 --- a/media/engine/webrtc_video_engine_unittest.cc +++ b/media/engine/webrtc_video_engine_unittest.cc @@ -3536,19 +3536,51 @@ TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; EXPECT_TRUE(vp9_settings.denoisingOn) << "VP9 denoising should be on by default."; + EXPECT_TRUE(vp9_settings.automaticResizeOn) + << "Automatic resize on for one active stream."; stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false); ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; EXPECT_FALSE(vp9_settings.denoisingOn); - // Frame dropping always on for real time video. - EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled); + EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled) + << "Frame dropping always on for real time video."; + EXPECT_TRUE(vp9_settings.automaticResizeOn); stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true); ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; EXPECT_TRUE(vp9_settings.denoisingOn); EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled); + EXPECT_TRUE(vp9_settings.automaticResizeOn); + + webrtc::RtpParameters rtp_parameters = + channel_->GetRtpSendParameters(last_ssrc_); + EXPECT_THAT( + rtp_parameters.encodings, + ElementsAre(Field(&webrtc::RtpEncodingParameters::scalability_mode, + absl::nullopt))); + rtp_parameters.encodings[0].scalability_mode = "L2T1"; + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok()); + + ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; + EXPECT_TRUE(vp9_settings.denoisingOn); + EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled); + EXPECT_FALSE(vp9_settings.automaticResizeOn) + << "Automatic resize off for multiple spatial layers."; + + rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_); + EXPECT_THAT(rtp_parameters.encodings, + ElementsAre(Field( + &webrtc::RtpEncodingParameters::scalability_mode, "L2T1"))); + rtp_parameters.encodings[0].scalability_mode = "L1T1"; + EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok()); + + ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; + EXPECT_TRUE(vp9_settings.denoisingOn); + EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled); + EXPECT_TRUE(vp9_settings.automaticResizeOn) + << "Automatic resize on for one spatial layer."; // In screen-share mode, denoising is forced off. VideoOptions options; @@ -3559,14 +3591,17 @@ TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) { ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; EXPECT_FALSE(vp9_settings.denoisingOn); - // Frame dropping always on for screen sharing. - EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled); + EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled) + << "Frame dropping always on for screen sharing."; + EXPECT_FALSE(vp9_settings.automaticResizeOn) + << "Automatic resize off for screencast."; stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false); ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set."; EXPECT_FALSE(vp9_settings.denoisingOn); EXPECT_TRUE(stream->GetEncoderConfig().frame_drop_enabled); + EXPECT_FALSE(vp9_settings.automaticResizeOn); EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr)); } diff --git a/modules/video_coding/svc/scalability_mode_util.cc b/modules/video_coding/svc/scalability_mode_util.cc index ff7ecb4b40..1cbdeb6cf2 100644 --- a/modules/video_coding/svc/scalability_mode_util.cc +++ b/modules/video_coding/svc/scalability_mode_util.cc @@ -139,6 +139,43 @@ absl::string_view ScalabilityModeToString(ScalabilityMode scalability_mode) { RTC_CHECK_NOTREACHED(); } +int ScalabilityModeToNumSpatialLayers(ScalabilityMode scalability_mode) { + switch (scalability_mode) { + case ScalabilityMode::kL1T1: + case ScalabilityMode::kL1T2: + case ScalabilityMode::kL1T2h: + case ScalabilityMode::kL1T3: + case ScalabilityMode::kL1T3h: + return 1; + case ScalabilityMode::kL2T1: + case ScalabilityMode::kL2T1h: + case ScalabilityMode::kL2T1_KEY: + case ScalabilityMode::kL2T2: + case ScalabilityMode::kL2T2h: + case ScalabilityMode::kL2T2_KEY: + case ScalabilityMode::kL2T2_KEY_SHIFT: + case ScalabilityMode::kL2T3: + case ScalabilityMode::kL2T3h: + case ScalabilityMode::kL2T3_KEY: + return 2; + case ScalabilityMode::kL3T1: + case ScalabilityMode::kL3T1h: + case ScalabilityMode::kL3T1_KEY: + case ScalabilityMode::kL3T2: + case ScalabilityMode::kL3T2h: + case ScalabilityMode::kL3T2_KEY: + case ScalabilityMode::kL3T3: + case ScalabilityMode::kL3T3h: + case ScalabilityMode::kL3T3_KEY: + return 3; + case ScalabilityMode::kS2T1: + return 2; + case ScalabilityMode::kS3T3: + return 3; + } + RTC_CHECK_NOTREACHED(); +} + int ScalabilityModeToNumTemporalLayers(ScalabilityMode scalability_mode) { switch (scalability_mode) { case ScalabilityMode::kL1T1: diff --git a/modules/video_coding/svc/scalability_mode_util.h b/modules/video_coding/svc/scalability_mode_util.h index 4b1c6763d8..faff4cf500 100644 --- a/modules/video_coding/svc/scalability_mode_util.h +++ b/modules/video_coding/svc/scalability_mode_util.h @@ -22,6 +22,8 @@ absl::optional ScalabilityModeFromString( absl::string_view ScalabilityModeToString(ScalabilityMode scalability_mode); +int ScalabilityModeToNumSpatialLayers(ScalabilityMode scalability_mode); + int ScalabilityModeToNumTemporalLayers(ScalabilityMode scalability_mode); } // namespace webrtc