RateControlSettings: add option to set max QP for libvpx vp8.

Bug: none
Change-Id: Ia662068fe179faebc1df0aaa7f37b6e989b6525f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/135569
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Åsa Persson <asapersson@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27888}
diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
index 0030361..0bb08c7 100644
--- a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
+++ b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc
@@ -560,6 +560,10 @@
   if (inst->qpMax >= vpx_configs_[0].rc_min_quantizer) {
     qp_max_ = inst->qpMax;
   }
+  if (rate_control_settings_.LibvpxVp8QpMax()) {
+    qp_max_ = std::max(rate_control_settings_.LibvpxVp8QpMax().value(),
+                       static_cast<int>(vpx_configs_[0].rc_min_quantizer));
+  }
   vpx_configs_[0].rc_max_quantizer = qp_max_;
   vpx_configs_[0].rc_undershoot_pct = 100;
   vpx_configs_[0].rc_overshoot_pct = 15;
diff --git a/rtc_base/experiments/rate_control_settings.cc b/rtc_base/experiments/rate_control_settings.cc
index ce300ef..eeb2f49 100644
--- a/rtc_base/experiments/rate_control_settings.cc
+++ b/rtc_base/experiments/rate_control_settings.cc
@@ -66,6 +66,7 @@
       congestion_window_pushback_("MinBitrate"),
       pacing_factor_("pacing_factor"),
       alr_probing_("alr_probing", false),
+      vp8_qp_max_("vp8_qp_max"),
       trust_vp8_(
           "trust_vp8",
           IsEnabled(key_value_config, kVp8TrustedRateControllerFieldTrialName)),
@@ -90,7 +91,7 @@
   ParseFieldTrial({&congestion_window_, &congestion_window_pushback_},
                   key_value_config->Lookup("WebRTC-CongestionWindow"));
   ParseFieldTrial(
-      {&pacing_factor_, &alr_probing_, &trust_vp8_, &trust_vp9_,
+      {&pacing_factor_, &alr_probing_, &vp8_qp_max_, &trust_vp8_, &trust_vp9_,
        &video_hysteresis_, &screenshare_hysteresis_, &probe_max_allocation_,
        &bitrate_adjuster_, &adjuster_use_headroom_, &vp8_s0_boost_,
        &vp8_dynamic_rate_, &vp9_dynamic_rate_},
@@ -138,6 +139,14 @@
   return alr_probing_.Get();
 }
 
+absl::optional<int> RateControlSettings::LibvpxVp8QpMax() const {
+  if (vp8_qp_max_ && (vp8_qp_max_.Value() < 0 || vp8_qp_max_.Value() > 63)) {
+    RTC_LOG(LS_WARNING) << "Unsupported vp8_qp_max_ value, ignored.";
+    return absl::nullopt;
+  }
+  return vp8_qp_max_.GetOptional();
+}
+
 bool RateControlSettings::LibvpxVp8TrustedRateController() const {
   return trust_vp8_.Get();
 }
diff --git a/rtc_base/experiments/rate_control_settings.h b/rtc_base/experiments/rate_control_settings.h
index a36d9be..70acc25 100644
--- a/rtc_base/experiments/rate_control_settings.h
+++ b/rtc_base/experiments/rate_control_settings.h
@@ -40,6 +40,7 @@
   absl::optional<double> GetPacingFactor() const;
   bool UseAlrProbing() const;
 
+  absl::optional<int> LibvpxVp8QpMax() const;
   bool LibvpxVp8TrustedRateController() const;
   bool Vp8BoostBaseLayerQuality() const;
   bool Vp8DynamicRateSettings() const;
@@ -67,6 +68,7 @@
   FieldTrialOptional<int> congestion_window_pushback_;
   FieldTrialOptional<double> pacing_factor_;
   FieldTrialParameter<bool> alr_probing_;
+  FieldTrialOptional<int> vp8_qp_max_;
   FieldTrialParameter<bool> trust_vp8_;
   FieldTrialParameter<bool> trust_vp9_;
   FieldTrialParameter<double> video_hysteresis_;
diff --git a/rtc_base/experiments/rate_control_settings_unittest.cc b/rtc_base/experiments/rate_control_settings_unittest.cc
index 0f23df0..89319e9 100644
--- a/rtc_base/experiments/rate_control_settings_unittest.cc
+++ b/rtc_base/experiments/rate_control_settings_unittest.cc
@@ -65,6 +65,20 @@
   EXPECT_TRUE(RateControlSettings::ParseFromFieldTrials().UseAlrProbing());
 }
 
+TEST(RateControlSettingsTest, LibvpxVp8QpMax) {
+  EXPECT_FALSE(RateControlSettings::ParseFromFieldTrials().LibvpxVp8QpMax());
+
+  test::ScopedFieldTrials field_trials(
+      "WebRTC-VideoRateControl/vp8_qp_max:50/");
+  EXPECT_EQ(RateControlSettings::ParseFromFieldTrials().LibvpxVp8QpMax(), 50);
+}
+
+TEST(RateControlSettingsTest, DoesNotGetTooLargeLibvpxVp8QpMaxValue) {
+  test::ScopedFieldTrials field_trials(
+      "WebRTC-VideoRateControl/vp8_qp_max:70/");
+  EXPECT_FALSE(RateControlSettings::ParseFromFieldTrials().LibvpxVp8QpMax());
+}
+
 TEST(RateControlSettingsTest, LibvpxTrustedRateController) {
   const RateControlSettings settings_before =
       RateControlSettings::ParseFromFieldTrials();