From 58a3210823a3faaad347b4e54606d493ec005fb1 Mon Sep 17 00:00:00 2001 From: Christoffer Rodbro Date: Thu, 21 Nov 2019 15:19:40 +0100 Subject: [PATCH] Add config to reduce weight on small samples in BitrateEstimator. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change #159711 adds the option to filter out small packets on the input to the delay-based BWE. This change adds similar functionality to BitrateEstimator by reducing the weight of small observations. Bug: webrtc:10932 Change-Id: I0a673a067f7ef86769cabd30443e60e9de70053c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/160009 Commit-Queue: Christoffer Rodbro Reviewed-by: Björn Terelius Cr-Commit-Position: refs/heads/master@{#29865} --- .../goog_cc/bitrate_estimator.cc | 37 ++++++++++++------- .../goog_cc/bitrate_estimator.h | 7 +++- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.cc b/modules/congestion_controller/goog_cc/bitrate_estimator.cc index 1d801bff54..a68f33ec87 100644 --- a/modules/congestion_controller/goog_cc/bitrate_estimator.cc +++ b/modules/congestion_controller/goog_cc/bitrate_estimator.cc @@ -43,7 +43,9 @@ BitrateEstimator::BitrateEstimator(const WebRtcKeyValueConfig* key_value_config) kMinRateWindowMs, kMaxRateWindowMs), uncertainty_scale_("scale", 10.0), - uncertainty_scale_in_alr_("scale_alr", 10.0), + uncertainty_scale_in_alr_("scale_alr", uncertainty_scale_), + small_sample_uncertainty_scale_("scale_small", uncertainty_scale_), + small_sample_threshold_("small_thresh", DataSize::Zero()), uncertainty_symmetry_cap_("symmetry_cap", DataRate::Zero()), estimate_floor_("floor", DataRate::Zero()), current_window_ms_(0), @@ -51,10 +53,11 @@ BitrateEstimator::BitrateEstimator(const WebRtcKeyValueConfig* key_value_config) bitrate_estimate_kbps_(-1.0f), bitrate_estimate_var_(50.0f) { // E.g WebRTC-BweThroughputWindowConfig/initial_window_ms:350,window_ms:250/ - ParseFieldTrial({&initial_window_ms_, &noninitial_window_ms_, - &uncertainty_scale_, &uncertainty_scale_in_alr_, - &uncertainty_symmetry_cap_, &estimate_floor_}, - key_value_config->Lookup(kBweThroughputWindowConfig)); + ParseFieldTrial( + {&initial_window_ms_, &noninitial_window_ms_, &uncertainty_scale_, + &uncertainty_scale_in_alr_, &small_sample_uncertainty_scale_, + &small_sample_threshold_, &uncertainty_symmetry_cap_, &estimate_floor_}, + key_value_config->Lookup(kBweThroughputWindowConfig)); } BitrateEstimator::~BitrateEstimator() = default; @@ -65,8 +68,9 @@ void BitrateEstimator::Update(Timestamp at_time, DataSize amount, bool in_alr) { // we can use to initialize the estimate. if (bitrate_estimate_kbps_ < 0.f) rate_window_ms = initial_window_ms_.Get(); - float bitrate_sample_kbps = - UpdateWindow(at_time.ms(), amount.bytes(), rate_window_ms); + bool is_small_sample = false; + float bitrate_sample_kbps = UpdateWindow(at_time.ms(), amount.bytes(), + rate_window_ms, &is_small_sample); if (bitrate_sample_kbps < 0.0f) return; if (bitrate_estimate_kbps_ < 0.0f) { @@ -74,15 +78,19 @@ void BitrateEstimator::Update(Timestamp at_time, DataSize amount, bool in_alr) { bitrate_estimate_kbps_ = bitrate_sample_kbps; return; } + // Optionally use higher uncertainty for very small samples to avoid dropping + // estimate and for samples obtained in ALR. + float scale = uncertainty_scale_; + if (is_small_sample && bitrate_sample_kbps < bitrate_estimate_kbps_) { + scale = small_sample_uncertainty_scale_; + } else if (in_alr && bitrate_sample_kbps < bitrate_estimate_kbps_) { + // Optionally use higher uncertainty for samples obtained during ALR. + scale = uncertainty_scale_in_alr_; + } // Define the sample uncertainty as a function of how far away it is from the // current estimate. With low values of uncertainty_symmetry_cap_ we add more // uncertainty to increases than to decreases. For higher values we approach // symmetry. - float scale = uncertainty_scale_; - if (in_alr && bitrate_sample_kbps < bitrate_estimate_kbps_) { - // Optionally use higher uncertainty for samples obtained during ALR. - scale = uncertainty_scale_in_alr_; - } float sample_uncertainty = scale * std::abs(bitrate_estimate_kbps_ - bitrate_sample_kbps) / (bitrate_estimate_kbps_ + @@ -108,7 +116,9 @@ void BitrateEstimator::Update(Timestamp at_time, DataSize amount, bool in_alr) { float BitrateEstimator::UpdateWindow(int64_t now_ms, int bytes, - int rate_window_ms) { + int rate_window_ms, + bool* is_small_sample) { + RTC_DCHECK(is_small_sample != nullptr); // Reset if time moves backwards. if (now_ms < prev_time_ms_) { prev_time_ms_ = -1; @@ -126,6 +136,7 @@ float BitrateEstimator::UpdateWindow(int64_t now_ms, prev_time_ms_ = now_ms; float bitrate_sample = -1.0f; if (current_window_ms_ >= rate_window_ms) { + *is_small_sample = sum_ < small_sample_threshold_->bytes(); bitrate_sample = 8.0f * sum_ / static_cast(rate_window_ms); current_window_ms_ -= rate_window_ms; sum_ = 0; diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.h b/modules/congestion_controller/goog_cc/bitrate_estimator.h index c657dbcf8d..34114f017c 100644 --- a/modules/congestion_controller/goog_cc/bitrate_estimator.h +++ b/modules/congestion_controller/goog_cc/bitrate_estimator.h @@ -38,12 +38,17 @@ class BitrateEstimator { virtual void ExpectFastRateChange(); private: - float UpdateWindow(int64_t now_ms, int bytes, int rate_window_ms); + float UpdateWindow(int64_t now_ms, + int bytes, + int rate_window_ms, + bool* is_small_sample); int sum_; FieldTrialConstrained initial_window_ms_; FieldTrialConstrained noninitial_window_ms_; FieldTrialParameter uncertainty_scale_; FieldTrialParameter uncertainty_scale_in_alr_; + FieldTrialParameter small_sample_uncertainty_scale_; + FieldTrialParameter small_sample_threshold_; FieldTrialParameter uncertainty_symmetry_cap_; FieldTrialParameter estimate_floor_; int64_t current_window_ms_;