diff --git a/modules/video_coding/frame_buffer2.cc b/modules/video_coding/frame_buffer2.cc index 10bc711332..d5df3baefa 100644 --- a/modules/video_coding/frame_buffer2.cc +++ b/modules/video_coding/frame_buffer2.cc @@ -62,7 +62,8 @@ FrameBuffer::FrameBuffer(Clock* clock, stats_callback_(stats_callback), last_log_non_decoded_ms_(-kLogNonDecodedIntervalMs), add_rtt_to_playout_delay_( - webrtc::field_trial::IsEnabled("WebRTC-AddRttToPlayoutDelay")) {} + webrtc::field_trial::IsEnabled("WebRTC-AddRttToPlayoutDelay")), + rtt_mult_settings_(RttMultExperiment::GetRttMultValue()) {} FrameBuffer::~FrameBuffer() {} @@ -299,11 +300,10 @@ EncodedFrame* FrameBuffer::GetNextFrame() { } float rtt_mult = protection_mode_ == kProtectionNackFEC ? 0.0 : 1.0; - absl::optional rtt_mult_add_cap_ms = absl::nullopt; - if (RttMultExperiment::RttMultEnabled()) { - rtt_mult = RttMultExperiment::GetRttMultValue(); - // TODO(mhoro): add RttMultExperiment::GetJitterEstCapValue(); - rtt_mult_add_cap_ms = 200.0; + absl::optional rtt_mult_add_cap_ms = absl::nullopt; + if (rtt_mult_settings_.has_value()) { + rtt_mult = rtt_mult_settings_->rtt_mult_setting; + rtt_mult_add_cap_ms = rtt_mult_settings_->rtt_mult_add_cap_ms; } timing_->SetJitterDelay( jitter_estimator_.GetJitterEstimate(rtt_mult, rtt_mult_add_cap_ms)); diff --git a/modules/video_coding/frame_buffer2.h b/modules/video_coding/frame_buffer2.h index 835079c980..15dca64d3f 100644 --- a/modules/video_coding/frame_buffer2.h +++ b/modules/video_coding/frame_buffer2.h @@ -195,6 +195,9 @@ class FrameBuffer { const bool add_rtt_to_playout_delay_; + // rtt_mult experiment settings. + const absl::optional rtt_mult_settings_; + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(FrameBuffer); }; diff --git a/rtc_base/experiments/BUILD.gn b/rtc_base/experiments/BUILD.gn index 6daac42921..3a78afe9a5 100644 --- a/rtc_base/experiments/BUILD.gn +++ b/rtc_base/experiments/BUILD.gn @@ -131,6 +131,7 @@ rtc_static_library("rtt_mult_experiment") { deps = [ "../:rtc_base_approved", "../../system_wrappers:field_trial", + "//third_party/abseil-cpp/absl/types:optional", ] } diff --git a/rtc_base/experiments/rtt_mult_experiment.cc b/rtc_base/experiments/rtt_mult_experiment.cc index beb577c1be..ed262622a9 100644 --- a/rtc_base/experiments/rtt_mult_experiment.cc +++ b/rtc_base/experiments/rtt_mult_experiment.cc @@ -22,29 +22,43 @@ namespace { const char kRttMultExperiment[] = "WebRTC-RttMult"; const float max_rtt_mult_setting = 1.0; const float min_rtt_mult_setting = 0.0; +const float max_rtt_mult_add_cap_ms = 2000.0; +const float min_rtt_mult_add_cap_ms = 0.0; } // namespace bool RttMultExperiment::RttMultEnabled() { return field_trial::IsEnabled(kRttMultExperiment); } -float RttMultExperiment::GetRttMultValue() { +absl::optional +RttMultExperiment::GetRttMultValue() { + if (!RttMultExperiment::RttMultEnabled()) + return absl::nullopt; const std::string group = webrtc::field_trial::FindFullName(kRttMultExperiment); if (group.empty()) { RTC_LOG(LS_WARNING) << "Could not find rtt_mult_experiment."; - return 0.0; + return absl::nullopt; } - float rtt_mult_setting; - if (sscanf(group.c_str(), "Enabled-%f", &rtt_mult_setting) != 1) { + Settings s; + if (sscanf(group.c_str(), "Enabled-%f,%f", &s.rtt_mult_setting, + &s.rtt_mult_add_cap_ms) != 2) { RTC_LOG(LS_WARNING) << "Invalid number of parameters provided."; - return 0.0; + return absl::nullopt; } - // Bounds check rtt_mult_setting value. - rtt_mult_setting = std::min(rtt_mult_setting, max_rtt_mult_setting); - rtt_mult_setting = std::max(rtt_mult_setting, min_rtt_mult_setting); - return rtt_mult_setting; + // Bounds check rtt_mult_setting and rtt_mult_add_cap_ms values. + s.rtt_mult_setting = std::min(s.rtt_mult_setting, max_rtt_mult_setting); + s.rtt_mult_setting = std::max(s.rtt_mult_setting, min_rtt_mult_setting); + s.rtt_mult_add_cap_ms = + std::min(s.rtt_mult_add_cap_ms, max_rtt_mult_add_cap_ms); + s.rtt_mult_add_cap_ms = + std::max(s.rtt_mult_add_cap_ms, min_rtt_mult_add_cap_ms); + RTC_LOG(LS_INFO) << "rtt_mult experiment: rtt_mult value = " + << s.rtt_mult_setting + << " rtt_mult addition cap = " << s.rtt_mult_add_cap_ms + << " ms."; + return s; } } // namespace webrtc diff --git a/rtc_base/experiments/rtt_mult_experiment.h b/rtc_base/experiments/rtt_mult_experiment.h index d431af6681..a868e63e8d 100644 --- a/rtc_base/experiments/rtt_mult_experiment.h +++ b/rtc_base/experiments/rtt_mult_experiment.h @@ -10,15 +10,24 @@ #ifndef RTC_BASE_EXPERIMENTS_RTT_MULT_EXPERIMENT_H_ #define RTC_BASE_EXPERIMENTS_RTT_MULT_EXPERIMENT_H_ +#include "absl/types/optional.h" + namespace webrtc { class RttMultExperiment { public: + struct Settings { + float rtt_mult_setting; // Jitter buffer size is increased by this factor + // times the estimated RTT. + float rtt_mult_add_cap_ms; // Jitter buffer size increase is capped by this + // value. + }; + // Returns true if the experiment is enabled. static bool RttMultEnabled(); - // Returns rtt_mult value from field trial. - static float GetRttMultValue(); + // Returns rtt_mult value and rtt_mult addition cap value from field trial. + static absl::optional GetRttMultValue(); }; } // namespace webrtc diff --git a/rtc_base/experiments/rtt_mult_experiment_unittest.cc b/rtc_base/experiments/rtt_mult_experiment_unittest.cc index 9442cea80c..bb00f5ec34 100644 --- a/rtc_base/experiments/rtt_mult_experiment_unittest.cc +++ b/rtc_base/experiments/rtt_mult_experiment_unittest.cc @@ -20,33 +20,43 @@ TEST(RttMultExperimentTest, RttMultDisabledByDefault) { } TEST(RttMultExperimentTest, RttMultEnabledByFieldTrial) { - webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-0.25/"); + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-RttMult/Enabled-0.60,100.0/"); EXPECT_TRUE(RttMultExperiment::RttMultEnabled()); } TEST(RttMultExperimentTest, RttMultTestValue) { - webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-0.25/"); - EXPECT_EQ(0.25, RttMultExperiment::GetRttMultValue()); + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-RttMult/Enabled-0.60,100.0/"); + EXPECT_EQ(0.6f, RttMultExperiment::GetRttMultValue()->rtt_mult_setting); + EXPECT_EQ(100.0f, RttMultExperiment::GetRttMultValue()->rtt_mult_add_cap_ms); } TEST(RttMultExperimentTest, RttMultTestMalformedEnabled) { - webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enable-0.25/"); + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-RttMult/Enable-0.60,100.0/"); EXPECT_FALSE(RttMultExperiment::RttMultEnabled()); + EXPECT_FALSE(RttMultExperiment::GetRttMultValue()); } TEST(RttMultExperimentTest, RttMultTestValueOutOfBoundsPositive) { - webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-1.5/"); - EXPECT_EQ(1.0, RttMultExperiment::GetRttMultValue()); + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-RttMult/Enabled-1.5,2100.0/"); + EXPECT_EQ(1.0f, RttMultExperiment::GetRttMultValue()->rtt_mult_setting); + EXPECT_EQ(2000.0f, RttMultExperiment::GetRttMultValue()->rtt_mult_add_cap_ms); } TEST(RttMultExperimentTest, RttMultTestValueOutOfBoundsNegative) { - webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled--0.5/"); - EXPECT_EQ(0.0, RttMultExperiment::GetRttMultValue()); + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-RttMult/Enabled--0.5,-100.0/"); + EXPECT_EQ(0.0f, RttMultExperiment::GetRttMultValue()->rtt_mult_setting); + EXPECT_EQ(0.0f, RttMultExperiment::GetRttMultValue()->rtt_mult_add_cap_ms); } TEST(RttMultExperimentTest, RttMultTestMalformedValue) { - webrtc::test::ScopedFieldTrials field_trials("WebRTC-RttMult/Enabled-0.2a5/"); - EXPECT_NE(0.25, RttMultExperiment::GetRttMultValue()); + webrtc::test::ScopedFieldTrials field_trials( + "WebRTC-RttMult/Enabled-0.25,10a0.0/"); + EXPECT_NE(100.0f, RttMultExperiment::GetRttMultValue()->rtt_mult_add_cap_ms); } } // namespace webrtc