| Index: webrtc/modules/congestion_controller/delay_based_bwe.cc
|
| diff --git a/webrtc/modules/congestion_controller/delay_based_bwe.cc b/webrtc/modules/congestion_controller/delay_based_bwe.cc
|
| index 78bc7f0e6e4702210ba3709cdc17017930f4608c..565dd2cd9d62f912c6d27e8308ec85cff02ee039 100644
|
| --- a/webrtc/modules/congestion_controller/delay_based_bwe.cc
|
| +++ b/webrtc/modules/congestion_controller/delay_based_bwe.cc
|
| @@ -21,6 +21,7 @@
|
| #include "webrtc/modules/congestion_controller/include/congestion_controller.h"
|
| #include "webrtc/modules/pacing/paced_sender.h"
|
| #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
|
| +#include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
|
| #include "webrtc/system_wrappers/include/field_trial.h"
|
| #include "webrtc/system_wrappers/include/metrics.h"
|
| #include "webrtc/typedefs.h"
|
| @@ -39,12 +40,18 @@ constexpr uint32_t kFixedSsrc = 0;
|
| constexpr int kInitialRateWindowMs = 500;
|
| constexpr int kRateWindowMs = 150;
|
|
|
| +// Parameters for linear least squares fit of regression line to noisy data.
|
| constexpr size_t kDefaultTrendlineWindowSize = 15;
|
| constexpr double kDefaultTrendlineSmoothingCoeff = 0.9;
|
| constexpr double kDefaultTrendlineThresholdGain = 4.0;
|
|
|
| +// Parameters for Theil-Sen robust fitting of line to noisy data.
|
| +constexpr size_t kDefaultTheilSenWindowSize = 20;
|
| +constexpr double kDefaultTheilSenThresholdGain = 4.0;
|
| +
|
| const char kBitrateEstimateExperiment[] = "WebRTC-ImprovedBitrateEstimate";
|
| const char kBweTrendlineFilterExperiment[] = "WebRTC-BweTrendlineFilter";
|
| +const char kBweTheilSenFilterExperiment[] = "WebRTC-BweTheilSenFilter";
|
|
|
| bool BitrateEstimateExperimentIsEnabled() {
|
| return webrtc::field_trial::FindFullName(kBitrateEstimateExperiment) ==
|
| @@ -58,16 +65,27 @@ bool TrendlineFilterExperimentIsEnabled() {
|
| return experiment_string.find("Enabled") == 0;
|
| }
|
|
|
| -bool ReadTrendlineFilterExperimentParameters(size_t* window_points,
|
| +bool TheilSenFilterExperimentIsEnabled() {
|
| + std::string experiment_string =
|
| + webrtc::field_trial::FindFullName(kBweTheilSenFilterExperiment);
|
| + // The experiment is enabled iff the field trial string begins with "Enabled".
|
| + return experiment_string.find("Enabled") == 0;
|
| +}
|
| +
|
| +bool ReadTrendlineFilterExperimentParameters(size_t* window_size,
|
| double* smoothing_coef,
|
| double* threshold_gain) {
|
| RTC_DCHECK(TrendlineFilterExperimentIsEnabled());
|
| + RTC_DCHECK(!TheilSenFilterExperimentIsEnabled());
|
| + RTC_DCHECK(window_size != nullptr);
|
| + RTC_DCHECK(smoothing_coef != nullptr);
|
| + RTC_DCHECK(threshold_gain != nullptr);
|
| std::string experiment_string =
|
| webrtc::field_trial::FindFullName(kBweTrendlineFilterExperiment);
|
| int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%zu,%lf,%lf",
|
| - window_points, smoothing_coef, threshold_gain);
|
| + window_size, smoothing_coef, threshold_gain);
|
| if (parsed_values == 3) {
|
| - RTC_CHECK_GT(*window_points, 1) << "Need at least 2 points to fit a line.";
|
| + RTC_CHECK_GT(*window_size, 1) << "Need at least 2 points to fit a line.";
|
| RTC_CHECK(0 <= *smoothing_coef && *smoothing_coef <= 1)
|
| << "Coefficient needs to be between 0 and 1 for weighted average.";
|
| RTC_CHECK_GT(*threshold_gain, 0) << "Threshold gain needs to be positive.";
|
| @@ -75,12 +93,33 @@ bool ReadTrendlineFilterExperimentParameters(size_t* window_points,
|
| }
|
| LOG(LS_WARNING) << "Failed to parse parameters for BweTrendlineFilter "
|
| "experiment from field trial string. Using default.";
|
| - *window_points = kDefaultTrendlineWindowSize;
|
| + *window_size = kDefaultTrendlineWindowSize;
|
| *smoothing_coef = kDefaultTrendlineSmoothingCoeff;
|
| *threshold_gain = kDefaultTrendlineThresholdGain;
|
| return false;
|
| }
|
|
|
| +bool ReadTheilSenFilterExperimentParameters(size_t* window_size,
|
| + double* threshold_gain) {
|
| + RTC_DCHECK(!TrendlineFilterExperimentIsEnabled());
|
| + RTC_DCHECK(TheilSenFilterExperimentIsEnabled());
|
| + RTC_DCHECK(window_size != nullptr);
|
| + RTC_DCHECK(threshold_gain != nullptr);
|
| + std::string experiment_string =
|
| + webrtc::field_trial::FindFullName(kBweTheilSenFilterExperiment);
|
| + int parsed_values = sscanf(experiment_string.c_str(), "Enabled-%zu,%lf",
|
| + window_size, threshold_gain);
|
| + if (parsed_values == 2) {
|
| + RTC_CHECK_GT(*window_size, 1) << "Need at least 2 points to fit a line.";
|
| + RTC_CHECK_GT(*threshold_gain, 0) << "Threshold gain needs to be positive.";
|
| + return true;
|
| + }
|
| + LOG(LS_WARNING) << "Failed to parse parameters for BweTheilSenFilter "
|
| + "experiment from field trial string. Using default.";
|
| + *window_size = kDefaultTheilSenWindowSize;
|
| + *threshold_gain = kDefaultTheilSenThresholdGain;
|
| + return false;
|
| +}
|
| } // namespace
|
|
|
| namespace webrtc {
|
| @@ -168,7 +207,9 @@ rtc::Optional<uint32_t> DelayBasedBwe::BitrateEstimator::bitrate_bps() const {
|
| }
|
|
|
| DelayBasedBwe::DelayBasedBwe(Clock* clock)
|
| - : clock_(clock),
|
| + : in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()),
|
| + in_theil_sen_experiment_(TheilSenFilterExperimentIsEnabled()),
|
| + clock_(clock),
|
| inter_arrival_(),
|
| kalman_estimator_(),
|
| trendline_estimator_(),
|
| @@ -180,12 +221,18 @@ DelayBasedBwe::DelayBasedBwe(Clock* clock)
|
| trendline_window_size_(kDefaultTrendlineWindowSize),
|
| trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff),
|
| trendline_threshold_gain_(kDefaultTrendlineThresholdGain),
|
| - in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()) {
|
| + theil_sen_window_size_(kDefaultTheilSenWindowSize),
|
| + theil_sen_threshold_gain_(kDefaultTheilSenThresholdGain) {
|
| if (in_trendline_experiment_) {
|
| ReadTrendlineFilterExperimentParameters(&trendline_window_size_,
|
| &trendline_smoothing_coeff_,
|
| &trendline_threshold_gain_);
|
| }
|
| + if (in_theil_sen_experiment_) {
|
| + ReadTheilSenFilterExperimentParameters(&trendline_window_size_,
|
| + &trendline_threshold_gain_);
|
| + }
|
| +
|
| network_thread_.DetachFromThread();
|
| }
|
|
|
| @@ -223,6 +270,8 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo(
|
| trendline_estimator_.reset(new TrendlineEstimator(
|
| trendline_window_size_, trendline_smoothing_coeff_,
|
| trendline_threshold_gain_));
|
| + theil_sen_estimator_.reset(new TheilSenEstimator(
|
| + theil_sen_window_size_, theil_sen_threshold_gain_));
|
| }
|
| last_seen_packet_ms_ = now_ms;
|
|
|
| @@ -248,7 +297,11 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo(
|
| detector_.Detect(trendline_estimator_->trendline_slope(), ts_delta_ms,
|
| trendline_estimator_->num_of_deltas(),
|
| info.arrival_time_ms);
|
| -
|
| + } else if (in_theil_sen_experiment_) {
|
| + theil_sen_estimator_->Update(t_delta, ts_delta_ms, info.arrival_time_ms);
|
| + detector_.Detect(theil_sen_estimator_->trendline_slope(), ts_delta_ms,
|
| + theil_sen_estimator_->num_of_deltas(),
|
| + info.arrival_time_ms);
|
| } else {
|
| kalman_estimator_->Update(t_delta, ts_delta_ms, size_delta,
|
| detector_.State(), info.arrival_time_ms);
|
| @@ -287,8 +340,11 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketInfo(
|
| UpdateEstimate(info.arrival_time_ms, now_ms, acked_bitrate_bps,
|
| &result.target_bitrate_bps);
|
| }
|
| - if (result.updated)
|
| + if (result.updated) {
|
| last_update_ms_ = now_ms;
|
| + BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms,
|
| + result.target_bitrate_bps);
|
| + }
|
|
|
| return result;
|
| }
|
|
|