Fix inference of scalability mode Only look at active streams. Bug: b/517029078, b/507191231, webrtc:510393737 Change-Id: Ia03be3d299968eb897ffc94b9acfdb1f69c0eda2 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/476680 Reviewed-by: Erik Språng <sprang@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47849}
diff --git a/modules/video_coding/video_codec_initializer.cc b/modules/video_coding/video_codec_initializer.cc index 7b3579d..91b6fb2 100644 --- a/modules/video_coding/video_codec_initializer.cc +++ b/modules/video_coding/video_codec_initializer.cc
@@ -103,9 +103,10 @@ int max_framerate = 0; - std::optional<ScalabilityMode> scalability_mode = streams[0].scalability_mode; + std::optional<ScalabilityMode> scalability_mode; const size_t num_streams = std::min(streams.size(), static_cast<size_t>(kMaxSimulcastStreams)); + int num_active_streams = 0; for (size_t i = 0; i < num_streams; ++i) { SimulcastStream* sim_stream = &video_codec.simulcastStream[i]; RTC_DCHECK_GT(streams[i].width, 0); @@ -149,14 +150,14 @@ // TODO(bugs.webrtc.org/11607): Since scalability mode is a top-level // setting on VideoCodec, setting it makes sense only if it is the same for // all active simulcast streams. - if (streams[i].active && - streams[0].scalability_mode != streams[i].scalability_mode) { - scalability_mode.reset(); - // For VP8, top-level scalability mode doesn't matter, since configuration - // is based on the per-simulcast stream configuration of temporal layers. - if (video_codec.codecType != kVideoCodecVP8) { + if (streams[i].active) { + if (num_active_streams == 0) { + scalability_mode = streams[i].scalability_mode; + } else if (scalability_mode != streams[i].scalability_mode) { RTC_LOG(LS_WARNING) << "Inconsistent scalability modes configured."; + scalability_mode.reset(); } + ++num_active_streams; } }
diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc index 73ccfaf..9a2e3ce 100644 --- a/modules/video_coding/video_codec_initializer_unittest.cc +++ b/modules/video_coding/video_codec_initializer_unittest.cc
@@ -756,4 +756,54 @@ } #endif +TEST_F(VideoCodecInitializerTest, + SimulcastInconsistentScalabilityModesWithFirstInactive) { + VideoEncoderConfig config; + config.simulcast_layers.resize(3); + config.simulcast_layers[0].active = false; + config.simulcast_layers[1].active = true; + config.simulcast_layers[2].active = true; + config.codec_type = VideoCodecType::kVideoCodecVP8; + + streams_ = {DefaultStream(), DefaultStream(), DefaultStream()}; + streams_[0].active = false; + streams_[0].scalability_mode = ScalabilityMode::kL1T3; + streams_[1].active = true; + streams_[1].scalability_mode = ScalabilityMode::kL1T2; + streams_[2].active = true; + streams_[2].scalability_mode = ScalabilityMode::kL1T1; + + VideoCodec codec = + VideoCodecInitializer::SetupCodec(env_.field_trials(), config, streams_); + + // Top level scalability mode should be cleared since active streams have + // different scalability modes. + EXPECT_EQ(codec.GetScalabilityMode(), std::nullopt); +} + +TEST_F(VideoCodecInitializerTest, + SimulcastConsistentScalabilityModesWithFirstInactive) { + VideoEncoderConfig config; + config.simulcast_layers.resize(3); + config.simulcast_layers[0].active = false; + config.simulcast_layers[1].active = true; + config.simulcast_layers[2].active = true; + config.codec_type = VideoCodecType::kVideoCodecVP8; + + streams_ = {DefaultStream(), DefaultStream(), DefaultStream()}; + streams_[0].active = false; + streams_[0].scalability_mode = ScalabilityMode::kL1T3; + streams_[1].active = true; + streams_[1].scalability_mode = ScalabilityMode::kL1T2; + streams_[2].active = true; + streams_[2].scalability_mode = ScalabilityMode::kL1T2; + + VideoCodec codec = + VideoCodecInitializer::SetupCodec(env_.field_trials(), config, streams_); + + // Top level scalability mode should be kL1T2 since active streams have the + // same scalability mode. + EXPECT_EQ(codec.GetScalabilityMode(), ScalabilityMode::kL1T2); +} + } // namespace webrtc
diff --git a/video/config/video_encoder_config.cc b/video/config/video_encoder_config.cc index 8eef969..5ec2b15 100644 --- a/video/config/video_encoder_config.cc +++ b/video/config/video_encoder_config.cc
@@ -14,6 +14,7 @@ #include <string> #include "api/video/video_codec_type.h" +#include "api/video_codecs/scalability_mode.h" #include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/video_codec.h" #include "rtc_base/checks.h" @@ -52,6 +53,9 @@ ss << ", scale_down_to: " << scale_resolution_down_to->width << "x" << scale_resolution_down_to->height; } + if (scalability_mode.has_value()) { + ss << ", scalability_mode: " << ScalabilityModeToString(*scalability_mode); + } ss << '}'; return ss.Release(); }