Add VP9-specific default resolution bitrate limits

Bug: none
Change-Id: Ifb6f962f04b1f05d20f80a721b1f41904e0a7e99
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/209702
Reviewed-by: Åsa Persson <asapersson@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33389}
diff --git a/rtc_base/experiments/encoder_info_settings.cc b/rtc_base/experiments/encoder_info_settings.cc
index e0a186e..9e1a519 100644
--- a/rtc_base/experiments/encoder_info_settings.cc
+++ b/rtc_base/experiments/encoder_info_settings.cc
@@ -35,7 +35,17 @@
 // 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() {
+EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
+    VideoCodecType codec_type) {
+  // Specific limits for VP9. Other codecs use VP8 limits.
+  if (codec_type == kVideoCodecVP9) {
+    return {{320 * 180, 0, 30000, 150000},
+            {480 * 270, 120000, 30000, 300000},
+            {640 * 360, 190000, 30000, 420000},
+            {960 * 540, 350000, 30000, 1000000},
+            {1280 * 720, 480000, 30000, 1500000}};
+  }
+
   return {{320 * 180, 0, 30000, 300000},
           {480 * 270, 200000, 30000, 500000},
           {640 * 360, 300000, 30000, 800000},
@@ -45,9 +55,11 @@
 
 absl::optional<VideoEncoder::ResolutionBitrateLimits>
 EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+    VideoCodecType codec_type,
     int frame_size_pixels) {
   VideoEncoder::EncoderInfo info;
-  info.resolution_bitrate_limits = GetDefaultSinglecastBitrateLimits();
+  info.resolution_bitrate_limits =
+      GetDefaultSinglecastBitrateLimits(codec_type);
   return info.GetEncoderBitrateLimitsForResolution(frame_size_pixels);
 }
 
diff --git a/rtc_base/experiments/encoder_info_settings.h b/rtc_base/experiments/encoder_info_settings.h
index 64bc88c..9cbb587 100644
--- a/rtc_base/experiments/encoder_info_settings.h
+++ b/rtc_base/experiments/encoder_info_settings.h
@@ -42,9 +42,11 @@
   }
 
   static std::vector<VideoEncoder::ResolutionBitrateLimits>
-  GetDefaultSinglecastBitrateLimits();
+  GetDefaultSinglecastBitrateLimits(VideoCodecType codec_type);
+
   static absl::optional<VideoEncoder::ResolutionBitrateLimits>
-  GetDefaultSinglecastBitrateLimitsForResolution(int frame_size_pixels);
+  GetDefaultSinglecastBitrateLimitsForResolution(VideoCodecType codec_type,
+                                                 int frame_size_pixels);
 
  protected:
   explicit EncoderInfoSettings(std::string name);
diff --git a/test/encoder_settings.cc b/test/encoder_settings.cc
index f90931a..1248d8f 100644
--- a/test/encoder_settings.cc
+++ b/test/encoder_settings.cc
@@ -68,10 +68,9 @@
             : DefaultVideoStreamFactory::kMaxBitratePerStream[i];
     max_bitrate_bps = std::min(bitrate_left_bps, max_bitrate_bps);
 
-    int target_bitrate_bps =
-        stream.target_bitrate_bps > 0
-            ? stream.target_bitrate_bps
-            : DefaultVideoStreamFactory::kMaxBitratePerStream[i];
+    int target_bitrate_bps = stream.target_bitrate_bps > 0
+                                 ? stream.target_bitrate_bps
+                                 : max_bitrate_bps;
     target_bitrate_bps = std::min(max_bitrate_bps, target_bitrate_bps);
 
     if (stream.min_bitrate_bps > 0) {
@@ -91,7 +90,8 @@
     }
     stream_settings[i].target_bitrate_bps = target_bitrate_bps;
     stream_settings[i].max_bitrate_bps = max_bitrate_bps;
-    stream_settings[i].active = stream.active;
+    stream_settings[i].active =
+        encoder_config.number_of_streams == 1 || stream.active;
 
     bitrate_left_bps -= stream_settings[i].target_bitrate_bps;
   }
diff --git a/video/quality_scaling_tests.cc b/video/quality_scaling_tests.cc
index 6130e83..0da9b69 100644
--- a/video/quality_scaling_tests.cc
+++ b/video/quality_scaling_tests.cc
@@ -58,9 +58,15 @@
   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 =
+      kSinglecastLimits720pVp8 =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+              kVideoCodecVP8,
               1280 * 720);
+  const absl::optional<VideoEncoder::ResolutionBitrateLimits>
+      kSinglecastLimits360pVp9 =
+          EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+              kVideoCodecVP9,
+              640 * 360);
 };
 
 void QualityScalingTest::RunTest(const std::string& payload_name,
@@ -133,6 +139,8 @@
       if (payload_name_ == "VP9") {
         // Simulcast layers indicates which spatial layers are active.
         encoder_config->simulcast_layers.resize(streams_active_.size());
+        encoder_config->simulcast_layers[0].max_bitrate_bps =
+            encoder_config->max_bitrate_bps;
       }
       double scale_factor = 1.0;
       for (int i = streams_active_.size() - 1; i >= 0; --i) {
@@ -216,7 +224,7 @@
   test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
 
   RunTest("VP8", {false, false, true},
-          kSinglecastLimits720p->min_start_bitrate_bps - 1,
+          kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
           /*automatic_resize=*/true, /*expect_adaptation=*/true);
 }
 
@@ -225,7 +233,7 @@
   test::ScopedFieldTrials field_trials(kPrefix + "1,127,0,0,0,0" + kEnd);
 
   RunTest("VP8", {false, false, true},
-          kSinglecastLimits720p->min_start_bitrate_bps,
+          kSinglecastLimits720pVp8->min_start_bitrate_bps,
           /*automatic_resize=*/true, /*expect_adaptation=*/false);
 }
 
@@ -237,7 +245,7 @@
       "WebRTC-DefaultBitrateLimitsKillSwitch/Enabled/");
 
   RunTest("VP8", {false, false, true},
-          kSinglecastLimits720p->min_start_bitrate_bps - 1,
+          kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
           /*automatic_resize=*/true, /*expect_adaptation=*/false);
 }
 
@@ -246,7 +254,7 @@
   // 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,
+  RunTest("VP8", {true}, kSinglecastLimits720pVp8->min_start_bitrate_bps - 1,
           /*automatic_resize=*/true, /*expect_adaptation=*/false);
 }
 
@@ -336,10 +344,21 @@
   test::ScopedFieldTrials field_trials(kPrefix + "0,0,1,255,0,0" + kEnd +
                                        "WebRTC-VP9QualityScaler/Enabled/");
 
-  RunTest("VP9", {false, true, false}, kLowStartBps,
+  RunTest("VP9", {false, true, false},
+          kSinglecastLimits360pVp9->min_start_bitrate_bps - 1,
           /*automatic_resize=*/true, /*expect_adaptation=*/true);
 }
 
+TEST_F(QualityScalingTest, NoAdaptDownForLowStartBitrateIfBitrateEnough_Vp9) {
+  // qp_low:1, qp_high:255 -> kNormalQp
+  test::ScopedFieldTrials field_trials(kPrefix + "0,0,1,255,0,0" + kEnd +
+                                       "WebRTC-VP9QualityScaler/Enabled/");
+
+  RunTest("VP9", {false, true, false},
+          kSinglecastLimits360pVp9->min_start_bitrate_bps,
+          /*automatic_resize=*/true, /*expect_adaptation=*/false);
+}
+
 #if defined(WEBRTC_USE_H264)
 TEST_F(QualityScalingTest, AdaptsDownForHighQp_H264) {
   // qp_low:1, qp_high:1 -> kHighQp
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index cc6f365..b894bd5 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -352,7 +352,8 @@
   // the default limits (bitrate limits are not used for simulcast).
   VideoEncoder::EncoderInfo new_info = info;
   new_info.resolution_bitrate_limits =
-      EncoderInfoSettings::GetDefaultSinglecastBitrateLimits();
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimits(
+          encoder_config.codec_type);
   return new_info;
 }
 
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index dda0dbe..0142aca 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -2111,7 +2111,7 @@
   const absl::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultLimits270p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
-              480 * 270);
+              kVideoCodecVP8, 480 * 270);
   video_source_.IncomingCapturedFrame(CreateFrame(1, 480, 270));
   EXPECT_FALSE(WaitForFrame(1000));
   EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, kNumStreams);
@@ -2124,7 +2124,7 @@
   const absl::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultLimits360p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
-              640 * 360);
+              kVideoCodecVP8, 640 * 360);
   video_source_.IncomingCapturedFrame(CreateFrame(2, 640, 360));
   EXPECT_FALSE(WaitForFrame(1000));
   EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits360p->min_bitrate_bps),
@@ -2145,7 +2145,7 @@
   const absl::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultLimits540p =
           EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
-              960 * 540);
+              kVideoCodecVP8, 960 * 540);
   video_source_.IncomingCapturedFrame(CreateFrame(4, 960, 540));
   EXPECT_FALSE(WaitForFrame(1000));
   EXPECT_EQ(static_cast<uint32_t>(kDefaultLimits540p->min_bitrate_bps),
@@ -5530,8 +5530,8 @@
 
   // The default bitrate limits for 360p should be used.
   const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
-      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(640 *
-                                                                          360);
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+          kVideoCodecVP9, 640 * 360);
   video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
   EXPECT_FALSE(WaitForFrame(1000));
   EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);
@@ -5548,8 +5548,8 @@
 
   // The default bitrate limits for 270p should be used.
   const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits270p =
-      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(480 *
-                                                                          270);
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+          kVideoCodecVP9, 480 * 270);
   video_source_.IncomingCapturedFrame(CreateFrame(2, 960, 540));
   EXPECT_FALSE(WaitForFrame(1000));
   EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);
@@ -5598,13 +5598,12 @@
 
   // The default bitrate limits for 360p should not be used.
   const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits360p =
-      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(640 *
-                                                                          360);
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+          kVideoCodecVP9, 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().codecType, 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);
@@ -5621,8 +5620,8 @@
 
   // The default singlecast bitrate limits for 720p should not be used.
   const absl::optional<VideoEncoder::ResolutionBitrateLimits> kLimits720p =
-      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(1280 *
-                                                                          720);
+      EncoderInfoSettings::GetDefaultSinglecastBitrateLimitsForResolution(
+          kVideoCodecVP9, 1280 * 720);
   video_source_.IncomingCapturedFrame(CreateFrame(1, 1280, 720));
   EXPECT_FALSE(WaitForFrame(1000));
   EXPECT_EQ(fake_encoder_.video_codec().numberOfSimulcastStreams, 1);