Use default ResolutionBitrateLimits for simulcast with one active stream if not configured

Bug: none
Change-Id: I049dd0924adc43ce249a8eda63cdcb13da42b030
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/208541
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33343}
diff --git a/rtc_base/experiments/encoder_info_settings.cc b/rtc_base/experiments/encoder_info_settings.cc
index a952c05..e0a186e 100644
--- a/rtc_base/experiments/encoder_info_settings.cc
+++ b/rtc_base/experiments/encoder_info_settings.cc
@@ -32,6 +32,25 @@
 
 }  // namespace
 
+// Default bitrate limits for simulcast with one active stream:
+// {frame_size_pixels, min_start_bitrate_bps, min_bitrate_bps, max_bitrate_bps}.
+std::vector<VideoEncoder::ResolutionBitrateLimits>
+EncoderInfoSettings::GetDefaultSinglecastBitrateLimits() {
+  return {{320 * 180, 0, 30000, 300000},
+          {480 * 270, 200000, 30000, 500000},
+          {640 * 360, 300000, 30000, 800000},
+          {960 * 540, 500000, 30000, 1500000},
+          {1280 * 720, 900000, 30000, 2500000}};
+}
+
+absl::optional<VideoEncoder::ResolutionBitrateLimits>
+EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+    int frame_size_pixels) {
+  VideoEncoder::EncoderInfo info;
+  info.resolution_bitrate_limits = GetDefaultSinglecastBitrateLimits();
+  return info.GetEncoderBitrateLimitsForResolution(frame_size_pixels);
+}
+
 EncoderInfoSettings::EncoderInfoSettings(std::string name)
     : requested_resolution_alignment_("requested_resolution_alignment"),
       apply_alignment_to_all_simulcast_layers_(
diff --git a/rtc_base/experiments/encoder_info_settings.h b/rtc_base/experiments/encoder_info_settings.h
index 16ee9f9..64bc88c 100644
--- a/rtc_base/experiments/encoder_info_settings.h
+++ b/rtc_base/experiments/encoder_info_settings.h
@@ -41,6 +41,11 @@
     return resolution_bitrate_limits_;
   }
 
+  static std::vector<VideoEncoder::ResolutionBitrateLimits>
+  GetDefaultSinglecastBitrateLimits();
+  static absl::optional<VideoEncoder::ResolutionBitrateLimits>
+  GetDefaultSinglecastBitrateLimitsForResolution(int frame_size_pixels);
+
  protected:
   explicit EncoderInfoSettings(std::string name);
 
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 1c92f36..f296f44 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -308,6 +308,7 @@
     "../rtc_base:timeutils",
     "../rtc_base/experiments:alr_experiment",
     "../rtc_base/experiments:balanced_degradation_settings",
+    "../rtc_base/experiments:encoder_info_settings",
     "../rtc_base/experiments:field_trial_parser",
     "../rtc_base/experiments:quality_rampup_experiment",
     "../rtc_base/experiments:quality_scaler_settings",
@@ -712,6 +713,7 @@
       "../rtc_base:task_queue_for_test",
       "../rtc_base:threading",
       "../rtc_base/experiments:alr_experiment",
+      "../rtc_base/experiments:encoder_info_settings",
       "../rtc_base/synchronization:mutex",
       "../rtc_base/task_utils:to_queued_task",
       "../system_wrappers",
diff --git a/video/quality_scaling_tests.cc b/video/quality_scaling_tests.cc
index f1b6567..6130e83 100644
--- a/video/quality_scaling_tests.cc
+++ b/video/quality_scaling_tests.cc
@@ -15,6 +15,7 @@
 #include "modules/video_coding/codecs/h264/include/h264.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
 #include "modules/video_coding/codecs/vp9/include/vp9.h"
+#include "rtc_base/experiments/encoder_info_settings.h"
 #include "test/call_test.h"
 #include "test/field_trial.h"
 #include "test/frame_generator_capturer.h"
@@ -24,7 +25,7 @@
 constexpr int kWidth = 1280;
 constexpr int kHeight = 720;
 constexpr int kLowStartBps = 100000;
-constexpr int kHighStartBps = 600000;
+constexpr int kHighStartBps = 1000000;
 constexpr size_t kTimeoutMs = 10000;  // Some tests are expected to time out.
 
 void SetEncoderSpecific(VideoEncoderConfig* encoder_config,
@@ -56,6 +57,10 @@
 
   const std::string kPrefix = "WebRTC-Video-QualityScaling/Enabled-";
   const std::string kEnd = ",0,0,0.9995,0.9999,1/";
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+      kSinglecastLimits720p =
+          EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+              1280 * 720);
 };
 
 void QualityScalingTest::RunTest(const std::string& payload_name,
@@ -210,10 +215,41 @@
   // qp_low:1, qp_high:127 -> kNormalQp
   test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
 
-  RunTest("VP8", {false, false, true}, kLowStartBps,
+  RunTest("VP8", {false, false, true},
+          kSinglecastLimits720p->min_start_bitrate_bps - 1,
           /*automatic_resize=*/true, /*expect_adaptation=*/true);
 }
 
+TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp8) {
+  // qp_low:1, qp_high:127 -> kNormalQp
+  test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
+
+  RunTest("VP8", {false, false, true},
+          kSinglecastLimits720p->min_start_bitrate_bps,
+          /*automatic_resize=*/true, /*expect_adaptation=*/false);
+}
+
+TEST_F(QualityScalingTest,
+       NoAdaptDownForLowStartBitrateIfDefaultLimitsDisabled_Vp8) {
+  // qp_low:1, qp_high:127 -> kNormalQp
+  test::ScopedFieldTrials field_trials(
+      kPrefix + "1,127,0,0,0,0" + kEnd +
+      "WebRTC-DefaultBitrateLimitsKillSwitch/Enabled/");
+
+  RunTest("VP8", {false, false, true},
+          kSinglecastLimits720p->min_start_bitrate_bps - 1,
+          /*automatic_resize=*/true, /*expect_adaptation=*/false);
+}
+
+TEST_F(QualityScalingTest,
+       NoAdaptDownForLowStartBitrate_OneStreamSinglecastLimitsNotUsed_Vp8) {
+  // qp_low:1, qp_high:127 -> kNormalQp
+  test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
+
+  RunTest("VP8", {true}, kSinglecastLimits720p->min_start_bitrate_bps - 1,
+          /*automatic_resize=*/true, /*expect_adaptation=*/false);
+}
+
 TEST_F(QualityScalingTest, NoAdaptDownForHighQp_LowestStreamActive_Vp8) {
   // qp_low:1, qp_high:1 -> kHighQp
   test::ScopedFieldTrials field_trials(kPrefix + "1,1,0,0,0,0" + kEnd);
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index ae58725..cc6f365 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -38,6 +38,7 @@
 #include "rtc_base/constructor_magic.h"
 #include "rtc_base/event.h"
 #include "rtc_base/experiments/alr_experiment.h"
+#include "rtc_base/experiments/encoder_info_settings.h"
 #include "rtc_base/experiments/rate_control_settings.h"
 #include "rtc_base/location.h"
 #include "rtc_base/logging.h"
@@ -339,6 +340,22 @@
   return layers_allocation;
 }
 
+VideoEncoder::EncoderInfo GetEncoderInfoWithBitrateLimitUpdate(
+    const VideoEncoder::EncoderInfo& info,
+    const VideoEncoderConfig& encoder_config,
+    bool default_limits_allowed) {
+  if (!default_limits_allowed || !info.resolution_bitrate_limits.empty() ||
+      encoder_config.simulcast_layers.size() <= 1) {
+    return info;
+  }
+  // Bitrate limits are not configured and more than one layer is used, use
+  // the default limits (bitrate limits are not used for simulcast).
+  VideoEncoder::EncoderInfo new_info = info;
+  new_info.resolution_bitrate_limits =
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimits();
+  return new_info;
+}
+
 int NumActiveStreams(const std::vector<VideoStream>& streams) {
   int num_active = 0;
   for (const auto& stream : streams) {
@@ -606,6 +623,8 @@
                                degradation_preference_manager_.get()),
       video_source_sink_controller_(/*sink=*/this,
                                     /*source=*/nullptr),
+      default_limits_allowed_(
+          !field_trial::IsEnabled("WebRTC-DefaultBitrateLimitsKillSwitch")),
       encoder_queue_(task_queue_factory->CreateTaskQueue(
           "EncoderQueue",
           TaskQueueFactory::Priority::NORMAL)) {
@@ -919,13 +938,14 @@
             << ", max=" << encoder_config_.max_bitrate_bps
             << "). The app bitrate limits will be used.";
       }
-    } else {
-      ApplyEncoderBitrateLimitsIfSingleActiveStream(
-          encoder_->GetEncoderInfo(), encoder_config_.simulcast_layers,
-          &streams);
     }
   }
 
+  ApplyEncoderBitrateLimitsIfSingleActiveStream(
+      GetEncoderInfoWithBitrateLimitUpdate(
+          encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_),
+      encoder_config_.simulcast_layers, &streams);
+
   VideoCodec codec;
   if (!VideoCodecInitializer::SetupCodec(encoder_config_, streams, &codec)) {
     RTC_LOG(LS_ERROR) << "Failed to create encoder configuration.";
@@ -936,10 +956,10 @@
     // thus some cropping might be needed.
     crop_width_ = last_frame_info_->width - codec.width;
     crop_height_ = last_frame_info_->height - codec.height;
-    if (encoder_bitrate_limits_) {
-      ApplyVp9BitrateLimits(encoder_->GetEncoderInfo(), encoder_config_,
-                            &codec);
-    }
+    ApplyVp9BitrateLimits(GetEncoderInfoWithBitrateLimitUpdate(
+                              encoder_->GetEncoderInfo(), encoder_config_,
+                              default_limits_allowed_),
+                          encoder_config_, &codec);
   }
 
   char log_stream_buf[4 * 1024];
@@ -1177,8 +1197,10 @@
 }
 
 void VideoStreamEncoder::OnEncoderSettingsChanged() {
-  EncoderSettings encoder_settings(encoder_->GetEncoderInfo(),
-                                   encoder_config_.Copy(), send_codec_);
+  EncoderSettings encoder_settings(
+      GetEncoderInfoWithBitrateLimitUpdate(
+          encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_),
+      encoder_config_.Copy(), send_codec_);
   stream_resource_manager_.SetEncoderSettings(encoder_settings);
   input_state_provider_.OnEncoderSettingsChanged(encoder_settings);
   bool is_screenshare = encoder_settings.encoder_config().content_type ==
@@ -2075,8 +2097,9 @@
           encoder_target_bitrate_bps_.value());
 
   absl::optional<VideoEncoder::ResolutionBitrateLimits> encoder_bitrate_limits =
-      encoder_->GetEncoderInfo().GetEncoderBitrateLimitsForResolution(
-          pixel_count);
+      GetEncoderInfoWithBitrateLimitUpdate(
+          encoder_->GetEncoderInfo(), encoder_config_, default_limits_allowed_)
+          .GetEncoderBitrateLimitsForResolution(pixel_count);
 
   if (encoder_bitrate_limits.has_value()) {
     // Use bitrate limits provided by encoder.
diff --git a/video/video_stream_encoder.h b/video/video_stream_encoder.h
index 26d71d0..b1c3bd8 100644
--- a/video/video_stream_encoder.h
+++ b/video/video_stream_encoder.h
@@ -440,6 +440,9 @@
   VideoSourceSinkController video_source_sink_controller_
       RTC_GUARDED_BY(main_queue_);
 
+  // Default bitrate limits in EncoderInfoSettings allowed.
+  const bool default_limits_allowed_;
+
   // Public methods are proxied to the task queues. The queues must be destroyed
   // first to make sure no tasks run that use other members.
   rtc::TaskQueue encoder_queue_;
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index d74ebe8..5583ba5 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -37,6 +37,7 @@
 #include "modules/video_coding/utility/quality_scaler.h"
 #include "modules/video_coding/utility/simulcast_rate_allocator.h"
 #include "rtc_base/event.h"
+#include "rtc_base/experiments/encoder_info_settings.h"
 #include "rtc_base/gunit.h"
 #include "rtc_base/logging.h"
 #include "rtc_base/ref_counted_object.h"
@@ -2092,6 +2093,70 @@
 }
 
 TEST_F(VideoStreamEncoderTest,
+       DefaultEncoderMaxAndMinBitratesUsedForTwoStreamsHighestActive) {
+  // Two streams, highest stream active.
+  VideoEncoderConfig config;
+  const int kNumStreams = 2;
+  test::FillEncoderConfiguration(kVideoCodecVP8, kNumStreams, &config);
+  config.max_bitrate_bps = 0;
+  config.simulcast_layers[0].active = false;
+  config.simulcast_layers[1].active = true;
+  config.video_stream_factory =
+      new rtc::RefCountedObject<cricket::EncoderStreamFactory>(
+          "VP8", /*max qp*/ 56, /*screencast*/ false,
+          /*screenshare enabled*/ false);
+  video_stream_encoder_->ConfigureEncoder(config.Copy(), kMaxPayloadLength);
+
+  // Default bitrate limits for 270p should be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+      kDefaultLimits270p =
+          EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+              480 * 270);
+  video_source_.IncomingCapturedFrame(CreateFrame(1, 480, 270));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, kNumStreams);
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits270p->min_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].minBitrate * 1000);
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits270p->max_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].maxBitrate * 1000);
+
+  // Default bitrate limits for 360p should be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+      kDefaultLimits360p =
+          EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+              640 * 360);
+  video_source_.IncomingCapturedFrame(CreateFrame(2, 640, 360));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits360p->min_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].minBitrate * 1000);
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits360p->max_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].maxBitrate * 1000);
+
+  // Resolution b/w 270p and 360p. The default limits for 360p should be used.
+  video_source_.IncomingCapturedFrame(
+      CreateFrame(3, (640 + 480) / 2, (360 + 270) / 2));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits360p->min_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].minBitrate * 1000);
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits360p->max_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].maxBitrate * 1000);
+
+  // Default bitrate limits for 540p should be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+      kDefaultLimits540p =
+          EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+              960 * 540);
+  video_source_.IncomingCapturedFrame(CreateFrame(4, 960, 540));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits540p->min_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].minBitrate * 1000);
+  EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits540p->max_bitrate_bps),
+            fake_encoder_.video_codec().simulcastStream[1].maxBitrate * 1000);
+
+  video_stream_encoder_->Stop();
+}
+
+TEST_F(VideoStreamEncoderTest,
        EncoderMaxAndMinBitratesUsedForThreeStreamsMiddleActive) {
   const VideoEncoder::ResolutionBitrateLimits kEncoderLimits270p(
       480 * 270, 34 * 1000, 12 * 1000, 1234 * 1000);
@@ -5439,6 +5504,141 @@
 }
 
 TEST_F(VideoStreamEncoderTest,
+       DefaultMaxAndMinBitratesUsedIfMiddleStreamActive) {
+  VideoEncoderConfig video_encoder_config;
+  test::FillEncoderConfiguration(PayloadStringToCodecType("VP9"), 1,
+                                 &video_encoder_config);
+  VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
+  vp9_settings.numberOfSpatialLayers = 3;
+  // Since only one layer is active - automatic resize should be enabled.
+  vp9_settings.automaticResizeOn = true;
+  video_encoder_config.encoder_specific_settings =
+      new rtc::RefCountedObject<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
+          vp9_settings);
+  video_encoder_config.max_bitrate_bps = kSimulcastTargetBitrateBps;
+  video_encoder_config.content_type =
+      VideoEncoderConfig::ContentType::kRealtimeVideo;
+  // Simulcast layers are used to indicate which spatial layers are active.
+  video_encoder_config.simulcast_layers.resize(3);
+  video_encoder_config.simulcast_layers[0].active = false;
+  video_encoder_config.simulcast_layers[1].active = true;
+  video_encoder_config.simulcast_layers[2].active = false;
+
+  video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
+                                          kMaxPayloadLength);
+  video_stream_encoder_->WaitUntilTaskQueueIsIdle();
+
+  // The default bitrate limits for 360p should be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(640 *
+                                                                          360);
+  video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);
+  EXPECT_EQ(fake_encoder_.video_codec().codecType,
+            VideoCodecType::kVideoCodecVP9);
+  EXPECT_EQ(fake_encoder_.video_codec().VP9()->numberOfSpatialLayers, 2);
+  EXPECT_TRUE(fake_encoder_.video_codec().spatialLayers[0].active);
+  EXPECT_EQ(640, fake_encoder_.video_codec().spatialLayers[0].width);
+  EXPECT_EQ(360, fake_encoder_.video_codec().spatialLayers[0].height);
+  EXPECT_EQ(static_cast<uint32_t>(kLimits360p->min_bitrate_bps),
+            fake_encoder_.video_codec().spatialLayers[0].minBitrate * 1000);
+  EXPECT_EQ(static_cast<uint32_t>(kLimits360p->max_bitrate_bps),
+            fake_encoder_.video_codec().spatialLayers[0].maxBitrate * 1000);
+
+  // The default bitrate limits for 270p should be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits270p =
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(480 *
+                                                                          270);
+  video_source_.IncomingCapturedFrame(CreateFrame(2, 960, 540));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);
+  EXPECT_EQ(fake_encoder_.video_codec().codecType,
+            VideoCodecType::kVideoCodecVP9);
+  EXPECT_EQ(fake_encoder_.video_codec().VP9()->numberOfSpatialLayers, 2);
+  EXPECT_TRUE(fake_encoder_.video_codec().spatialLayers[0].active);
+  EXPECT_EQ(480, fake_encoder_.video_codec().spatialLayers[0].width);
+  EXPECT_EQ(270, fake_encoder_.video_codec().spatialLayers[0].height);
+  EXPECT_EQ(static_cast<uint32_t>(kLimits270p->min_bitrate_bps),
+            fake_encoder_.video_codec().spatialLayers[0].minBitrate * 1000);
+  EXPECT_EQ(static_cast<uint32_t>(kLimits270p->max_bitrate_bps),
+            fake_encoder_.video_codec().spatialLayers[0].maxBitrate * 1000);
+
+  video_stream_encoder_->Stop();
+}
+
+TEST_F(VideoStreamEncoderTest, DefaultMaxAndMinBitratesNotUsedIfDisabled) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-DefaultBitrateLimitsKillSwitch/Enabled/");
+  VideoEncoderConfig video_encoder_config;
+  test::FillEncoderConfiguration(PayloadStringToCodecType("VP9"), 1,
+                                 &video_encoder_config);
+  VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
+  vp9_settings.numberOfSpatialLayers = 3;
+  // Since only one layer is active - automatic resize should be enabled.
+  vp9_settings.automaticResizeOn = true;
+  video_encoder_config.encoder_specific_settings =
+      new rtc::RefCountedObject<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
+          vp9_settings);
+  video_encoder_config.max_bitrate_bps = kSimulcastTargetBitrateBps;
+  video_encoder_config.content_type =
+      VideoEncoderConfig::ContentType::kRealtimeVideo;
+  // Simulcast layers are used to indicate which spatial layers are active.
+  video_encoder_config.simulcast_layers.resize(3);
+  video_encoder_config.simulcast_layers[0].active = false;
+  video_encoder_config.simulcast_layers[1].active = true;
+  video_encoder_config.simulcast_layers[2].active = false;
+
+  // Reset encoder for field trials to take effect.
+  ConfigureEncoder(video_encoder_config.Copy());
+
+  video_stream_encoder_->ConfigureEncoder(video_encoder_config.Copy(),
+                                          kMaxPayloadLength);
+  video_stream_encoder_->WaitUntilTaskQueueIsIdle();
+
+  // The default bitrate limits for 360p should not be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(640 *
+                                                                          360);
+  video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);
+  EXPECT_EQ(fake_encoder_.video_codec().codecType,
+            VideoCodecType::kVideoCodecVP9);
+  EXPECT_EQ(fake_encoder_.video_codec().VP9()->numberOfSpatialLayers, 2);
+  EXPECT_TRUE(fake_encoder_.video_codec().spatialLayers[0].active);
+  EXPECT_EQ(640, fake_encoder_.video_codec().spatialLayers[0].width);
+  EXPECT_EQ(360, fake_encoder_.video_codec().spatialLayers[0].height);
+  EXPECT_NE(static_cast<uint32_t>(kLimits360p->max_bitrate_bps),
+            fake_encoder_.video_codec().spatialLayers[0].maxBitrate * 1000);
+
+  video_stream_encoder_->Stop();
+}
+
+TEST_F(VideoStreamEncoderTest, SinglecastBitrateLimitsNotUsedForOneStream) {
+  ResetEncoder("VP9", /*num_streams=*/1, /*num_temporal_layers=*/1,
+               /*num_spatial_layers=*/1, /*screenshare=*/false);
+
+  // The default singlecast bitrate limits for 720p should not be used.
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits720p =
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(1280 *
+                                                                          720);
+  video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
+  EXPECT_FALSE(WaitForFrame(1000));
+  EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);
+  EXPECT_EQ(fake_encoder_.video_codec().codecType,
+            VideoCodecType::kVideoCodecVP9);
+  EXPECT_EQ(fake_encoder_.video_codec().VP9()->numberOfSpatialLayers, 1);
+  EXPECT_TRUE(fake_encoder_.video_codec().spatialLayers[0].active);
+  EXPECT_EQ(1280, fake_encoder_.video_codec().spatialLayers[0].width);
+  EXPECT_EQ(720, fake_encoder_.video_codec().spatialLayers[0].height);
+  EXPECT_NE(static_cast<uint32_t>(kLimits720p->max_bitrate_bps),
+            fake_encoder_.video_codec().spatialLayers[0].maxBitrate * 1000);
+
+  video_stream_encoder_->Stop();
+}
+
+TEST_F(VideoStreamEncoderTest,
        EncoderMaxAndMinBitratesNotUsedIfLowestStreamActive) {
   const VideoEncoder::ResolutionBitrateLimits kEncoderLimits180p(
       320 * 180, 34 * 1000, 12 * 1000, 1234 * 1000);