diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_encoder.cc index 0030361a75..0bb08c7e8a 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 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst, 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(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 ce300ef8fa..eeb2f4957b 100644 --- a/rtc_base/experiments/rate_control_settings.cc +++ b/rtc_base/experiments/rate_control_settings.cc @@ -66,6 +66,7 @@ RateControlSettings::RateControlSettings( 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 @@ RateControlSettings::RateControlSettings( 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 @@ bool RateControlSettings::UseAlrProbing() const { return alr_probing_.Get(); } +absl::optional 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 a36d9be3ff..70acc25c6a 100644 --- a/rtc_base/experiments/rate_control_settings.h +++ b/rtc_base/experiments/rate_control_settings.h @@ -40,6 +40,7 @@ class RateControlSettings final { absl::optional GetPacingFactor() const; bool UseAlrProbing() const; + absl::optional LibvpxVp8QpMax() const; bool LibvpxVp8TrustedRateController() const; bool Vp8BoostBaseLayerQuality() const; bool Vp8DynamicRateSettings() const; @@ -67,6 +68,7 @@ class RateControlSettings final { FieldTrialOptional congestion_window_pushback_; FieldTrialOptional pacing_factor_; FieldTrialParameter alr_probing_; + FieldTrialOptional vp8_qp_max_; FieldTrialParameter trust_vp8_; FieldTrialParameter trust_vp9_; FieldTrialParameter video_hysteresis_; diff --git a/rtc_base/experiments/rate_control_settings_unittest.cc b/rtc_base/experiments/rate_control_settings_unittest.cc index 0f23df0726..89319e9088 100644 --- a/rtc_base/experiments/rate_control_settings_unittest.cc +++ b/rtc_base/experiments/rate_control_settings_unittest.cc @@ -65,6 +65,20 @@ TEST(RateControlSettingsTest, AlrProbing) { 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();