Use encoding max bitrate if configured when applying bitrate limits.

Currently the min of the default bitrate and configured bitrate is used.

Add default bitrate limits for 1080p.

Bug: b/396641469
Change-Id: Iabf243627a6dcbaa1e2f14d4f201c9482f3958d5
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/377123
Reviewed-by: Sergey Silkin <ssilkin@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43923}
diff --git a/rtc_base/experiments/encoder_info_settings.cc b/rtc_base/experiments/encoder_info_settings.cc
index e643c70..c5f544e 100644
--- a/rtc_base/experiments/encoder_info_settings.cc
+++ b/rtc_base/experiments/encoder_info_settings.cc
@@ -46,11 +46,10 @@
     // The min bitrate limits are not used in singlecast (used in SVC/simulcast
     // to de-/activate spatial layers) and are set to zero. Send resolution in
     // singlecast is assumed to be regulated by QP-based quality scaler.
-    return {{320 * 180, 0, 0, 256000},
-            {480 * 270, 176000, 0, 384000},
-            {640 * 360, 256000, 0, 512000},
-            {960 * 540, 384000, 0, 1024000},
-            {1280 * 720, 576000, 0, 1536000}};
+    return {
+        {320 * 180, 0, 0, 256000},        {480 * 270, 176000, 0, 384000},
+        {640 * 360, 256000, 0, 512000},   {960 * 540, 384000, 0, 1024000},
+        {1280 * 720, 576000, 0, 1536000}, {1920 * 1080, 1000000, 0, 3700000}};
   }
 
   if (codec_type == kVideoCodecVP9 || codec_type == kVideoCodecH265) {
@@ -64,7 +63,8 @@
             {480 * 270, 120000, 30000, 300000},
             {640 * 360, 190000, 30000, 420000},
             {960 * 540, 350000, 30000, 1000000},
-            {1280 * 720, 480000, 30000, 1500000}};
+            {1280 * 720, 480000, 30000, 1500000},
+            {1920 * 1080, 1000000, 30000, 3700000}};
   }
 
   // VP8 and other codecs.
@@ -72,7 +72,8 @@
           {480 * 270, 200000, 30000, 500000},
           {640 * 360, 300000, 30000, 800000},
           {960 * 540, 500000, 30000, 1500000},
-          {1280 * 720, 900000, 30000, 2500000}};
+          {1280 * 720, 900000, 30000, 2500000},
+          {1920 * 1080, 2000000, 30000, 5000000}};
 }
 
 std::optional<VideoEncoder::ResolutionBitrateLimits>
diff --git a/video/config/encoder_stream_factory.cc b/video/config/encoder_stream_factory.cc
index cb7f9f2..ff17c9c 100644
--- a/video/config/encoder_stream_factory.cc
+++ b/video/config/encoder_stream_factory.cc
@@ -409,7 +409,8 @@
       RTC_DCHECK_GE(sum_max_bitrates_kbps, 0);
       if (!api_max_bitrate_bps.has_value()) {
         max_bitrate_bps = sum_max_bitrates_kbps * 1000;
-      } else {
+      } else if (encoder_config.simulcast_layers[0].max_bitrate_bps <= 0) {
+        // Encoding max bitrate is kept if configured.
         max_bitrate_bps =
             std::min(max_bitrate_bps, sum_max_bitrates_kbps * 1000);
       }
diff --git a/video/config/encoder_stream_factory_unittest.cc b/video/config/encoder_stream_factory_unittest.cc
index 25ba15a..605d0d4 100644
--- a/video/config/encoder_stream_factory_unittest.cc
+++ b/video/config/encoder_stream_factory_unittest.cc
@@ -488,4 +488,20 @@
 }
 #endif
 
+TEST(EncoderStreamFactory, VP9SetsMaxBitrateToConfiguredEncodingValue) {
+  VideoEncoderConfig encoder_config;
+  VideoCodecVP9 vp9_settings = VideoEncoder::GetDefaultVp9Settings();
+  encoder_config.encoder_specific_settings =
+      rtc::make_ref_counted<VideoEncoderConfig::Vp9EncoderSpecificSettings>(
+          vp9_settings);
+  encoder_config.codec_type = VideoCodecType::kVideoCodecVP9;
+  encoder_config.number_of_streams = 1;
+  encoder_config.simulcast_layers.resize(3);
+  encoder_config.simulcast_layers[0].max_bitrate_bps = 5000000;
+  auto streams = CreateEncoderStreams(ExplicitKeyValueConfig(""), {1280, 720},
+                                      encoder_config);
+  ASSERT_THAT(streams, SizeIs(1));
+  EXPECT_EQ(streams[0].max_bitrate_bps, 5000000);
+}
+
 }  // namespace webrtc
diff --git a/video/end_to_end_tests/resolution_bitrate_limits_tests.cc b/video/end_to_end_tests/resolution_bitrate_limits_tests.cc
index 06eb71e..2a411f7 100644
--- a/video/end_to_end_tests/resolution_bitrate_limits_tests.cc
+++ b/video/end_to_end_tests/resolution_bitrate_limits_tests.cc
@@ -344,15 +344,14 @@
   RunBaseTest(&test);
 }
 
-TEST_P(ResolutionBitrateLimitsTest, EncodingMinBitrateAppliedMiddleActive) {
+TEST_P(ResolutionBitrateLimitsTest, EncodingMinMaxBitrateAppliedMiddleActive) {
   webrtc::test::ScopedFieldTrials field_trials(
       "WebRTC-GetEncoderInfoOverride/"
       "frame_size_pixels:230400|921600,"
       "min_start_bitrate_bps:0|0,"
       "min_bitrate_bps:31000|32000,"
-      "max_bitrate_bps:2222000|3333000/");
+      "max_bitrate_bps:1111000|3333000/");
 
-  // Max bitrate: min of encoding and bitrate limits used.
   InitEncodeTest test(env(), payload_name_,
                       {{.active = false,
                         .bitrate = {DataRate::KilobitsPerSec(28),
@@ -368,6 +367,49 @@
   RunBaseTest(&test);
 }
 
+TEST_P(ResolutionBitrateLimitsTest, MinBitrateNotAboveEncodingMax) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-GetEncoderInfoOverride/"
+      "frame_size_pixels:230400|921600,"
+      "min_start_bitrate_bps:0|0,"
+      "min_bitrate_bps:31000|32000,"
+      "max_bitrate_bps:1111000|3333000/");
+
+  InitEncodeTest test(
+      env(), payload_name_,
+      {{.active = false},
+       {.active = true,
+        .bitrate = {std::nullopt, DataRate::KilobitsPerSec(25)}},
+       {.active = false}},
+      // Expectations:
+      {{.pixels = 640 * 360,
+        .eq_bitrate = {DataRate::KilobitsPerSec(25),
+                       DataRate::KilobitsPerSec(25)}}});
+  RunBaseTest(&test);
+}
+
+TEST_P(ResolutionBitrateLimitsTest, MaxBitrateNotBelowEncodingMin) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-GetEncoderInfoOverride/"
+      "frame_size_pixels:230400|921600,"
+      "min_start_bitrate_bps:0|0,"
+      "min_bitrate_bps:21000|22000,"
+      "max_bitrate_bps:31000|32000/");
+
+  InitEncodeTest test(
+      env(), payload_name_,
+      {{.active = false,
+        .bitrate = {DataRate::KilobitsPerSec(50), std::nullopt}},
+       {.active = true,
+        .bitrate = {DataRate::KilobitsPerSec(50), std::nullopt}},
+       {.active = false}},
+      // Expectations:
+      {{.pixels = 640 * 360,
+        .eq_bitrate = {DataRate::KilobitsPerSec(50),
+                       DataRate::KilobitsPerSec(50)}}});
+  RunBaseTest(&test);
+}
+
 TEST_P(ResolutionBitrateLimitsTest, DefaultLimitsAppliedMiddleActive) {
   const std::optional<VideoEncoder::ResolutionBitrateLimits>
       kDefaultSinglecastLimits360p =
@@ -423,15 +465,14 @@
   RunBaseTest(&test);
 }
 
-TEST_P(ResolutionBitrateLimitsTest, EncodingMinBitrateAppliedHighestActive) {
+TEST_P(ResolutionBitrateLimitsTest, EncodingMinMaxBitrateAppliedHighestActive) {
   webrtc::test::ScopedFieldTrials field_trials(
       "WebRTC-GetEncoderInfoOverride/"
       "frame_size_pixels:230400|921600,"
       "min_start_bitrate_bps:0|0,"
       "min_bitrate_bps:31000|32000,"
-      "max_bitrate_bps:2222000|3333000/");
+      "max_bitrate_bps:555000|1111000/");
 
-  // Max bitrate: min of encoding and bitrate limits used.
   InitEncodeTest test(env(), payload_name_,
                       {{.active = false,
                         .bitrate = {DataRate::KilobitsPerSec(28),
@@ -552,15 +593,14 @@
 }
 
 TEST_F(ResolutionBitrateLimitsWithScalabilityModeTest,
-       EncodingMinBitrateAppliedForAv1SingleSpatialLayer) {
+       EncodingMinMaxBitrateAppliedForAv1SingleSpatialLayer) {
   webrtc::test::ScopedFieldTrials field_trials(
       "WebRTC-GetEncoderInfoOverride/"
       "frame_size_pixels:921600,"
       "min_start_bitrate_bps:0,"
       "min_bitrate_bps:32000,"
-      "max_bitrate_bps:133000/");
+      "max_bitrate_bps:99000/");
 
-  // Max bitrate: min of encoding and bitrate limits used.
   InitEncodeTest test(env(), "AV1",
                       {{.active = true,
                         .bitrate = {DataRate::KilobitsPerSec(28),
diff --git a/video/video_stream_encoder.cc b/video/video_stream_encoder.cc
index a7df421..18b13ea 100644
--- a/video/video_stream_encoder.cc
+++ b/video/video_stream_encoder.cc
@@ -468,15 +468,15 @@
   if (encoder_config.simulcast_layers[*index].max_bitrate_bps <= 0) {
     max_bitrate_bps = bitrate_limits->max_bitrate_bps;
   } else {
-    max_bitrate_bps =
-        std::min(bitrate_limits->max_bitrate_bps,
-                 encoder_config.simulcast_layers[*index].max_bitrate_bps);
+    max_bitrate_bps = encoder_config.simulcast_layers[*index].max_bitrate_bps;
   }
-  if (min_bitrate_bps >= max_bitrate_bps) {
-    RTC_LOG(LS_WARNING) << "Bitrate limits not used, min_bitrate_bps "
-                        << min_bitrate_bps << " >= max_bitrate_bps "
-                        << max_bitrate_bps;
-    return;
+
+  if (encoder_config.simulcast_layers[*index].min_bitrate_bps > 0) {
+    // Ensure max is not below configured min.
+    max_bitrate_bps = std::max(min_bitrate_bps, max_bitrate_bps);
+  } else {
+    // Ensure min is not above max.
+    min_bitrate_bps = std::min(min_bitrate_bps, max_bitrate_bps);
   }
 
   for (int i = 0; i < GetNumSpatialLayers(*codec); ++i) {
@@ -484,8 +484,9 @@
       codec->spatialLayers[i].minBitrate = min_bitrate_bps / 1000;
       codec->spatialLayers[i].maxBitrate = max_bitrate_bps / 1000;
       codec->spatialLayers[i].targetBitrate =
-          std::min(codec->spatialLayers[i].targetBitrate,
-                   codec->spatialLayers[i].maxBitrate);
+          std::clamp(codec->spatialLayers[i].targetBitrate,
+                     codec->spatialLayers[i].minBitrate,
+                     codec->spatialLayers[i].maxBitrate);
       break;
     }
   }
@@ -531,25 +532,21 @@
   if (encoder_config_layers[index].max_bitrate_bps <= 0) {
     max_bitrate_bps = encoder_bitrate_limits->max_bitrate_bps;
   } else {
-    max_bitrate_bps = std::min(encoder_bitrate_limits->max_bitrate_bps,
-                               (*streams)[index].max_bitrate_bps);
+    max_bitrate_bps = (*streams)[index].max_bitrate_bps;
   }
-  if (min_bitrate_bps >= max_bitrate_bps) {
-    RTC_LOG(LS_WARNING) << "Encoder bitrate limits"
-                        << " (min=" << encoder_bitrate_limits->min_bitrate_bps
-                        << ", max=" << encoder_bitrate_limits->max_bitrate_bps
-                        << ") do not intersect with stream limits"
-                        << " (min=" << (*streams)[index].min_bitrate_bps
-                        << ", max=" << (*streams)[index].max_bitrate_bps
-                        << "). Encoder bitrate limits not used.";
-    return;
+
+  if (encoder_config_layers[index].min_bitrate_bps > 0) {
+    // Ensure max is not below configured min.
+    max_bitrate_bps = std::max(min_bitrate_bps, max_bitrate_bps);
+  } else {
+    // Ensure min is not above max.
+    min_bitrate_bps = std::min(min_bitrate_bps, max_bitrate_bps);
   }
 
   (*streams)[index].min_bitrate_bps = min_bitrate_bps;
   (*streams)[index].max_bitrate_bps = max_bitrate_bps;
-  (*streams)[index].target_bitrate_bps =
-      std::min((*streams)[index].target_bitrate_bps,
-               encoder_bitrate_limits->max_bitrate_bps);
+  (*streams)[index].target_bitrate_bps = std::clamp(
+      (*streams)[index].target_bitrate_bps, min_bitrate_bps, max_bitrate_bps);
 }
 
 std::optional<int> ParseVp9LowTierCoreCountThreshold(
diff --git a/video/video_stream_encoder_unittest.cc b/video/video_stream_encoder_unittest.cc
index 08e3a45..417a424 100644
--- a/video/video_stream_encoder_unittest.cc
+++ b/video/video_stream_encoder_unittest.cc
@@ -2685,16 +2685,18 @@
   config.video_stream_factory = nullptr;
   video_stream_encoder_->ConfigureEncoder(config.Copy(), kMaxPayloadLength);
 
-  // The encoder bitrate limits for 270p should be used.
+  // The max configured bitrate should be used.
+  // The encoder bitrate limits for 270p should be used for min bitrate
   video_source_.IncomingCapturedFrame(CreateFrame(1, 480, 270));
   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
   EXPECT_EQ(fake_encoder_.config().numberOfSimulcastStreams, kNumStreams);
   EXPECT_EQ(static_cast<uint32_t>(kEncoderLimits270p.min_bitrate_bps),
             fake_encoder_.config().simulcastStream[1].minBitrate * 1000);
-  EXPECT_EQ(static_cast<uint32_t>(kEncoderLimits270p.max_bitrate_bps),
+  EXPECT_EQ(static_cast<uint32_t>(kMaxBitrateBps),
             fake_encoder_.config().simulcastStream[1].maxBitrate * 1000);
 
-  // The max configured bitrate is less than the encoder limit for 360p.
+  // The max configured bitrate should be used.
+  // The encoder bitrate limits for 360p should be used for min bitrate
   video_source_.IncomingCapturedFrame(CreateFrame(2, 640, 360));
   video_stream_encoder_->WaitUntilTaskQueueIsIdle();
   EXPECT_EQ(static_cast<uint32_t>(kEncoderLimits360p.min_bitrate_bps),