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();
 }