Add config to reduce weight on small samples in BitrateEstimator.

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 <crodbro@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29865}
diff --git a/modules/congestion_controller/goog_cc/bitrate_estimator.cc b/modules/congestion_controller/goog_cc/bitrate_estimator.cc
index 1d801bf..a68f33e 100644
--- a/modules/congestion_controller/goog_cc/bitrate_estimator.cc
+++ b/modules/congestion_controller/goog_cc/bitrate_estimator.cc
@@ -43,7 +43,9 @@
                             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 @@
       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 @@
   // 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 @@
     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 @@
 
 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 @@
   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<float>(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 c657dbc..34114f0 100644
--- a/modules/congestion_controller/goog_cc/bitrate_estimator.h
+++ b/modules/congestion_controller/goog_cc/bitrate_estimator.h
@@ -38,12 +38,17 @@
   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<int> initial_window_ms_;
   FieldTrialConstrained<int> noninitial_window_ms_;
   FieldTrialParameter<double> uncertainty_scale_;
   FieldTrialParameter<double> uncertainty_scale_in_alr_;
+  FieldTrialParameter<double> small_sample_uncertainty_scale_;
+  FieldTrialParameter<DataSize> small_sample_threshold_;
   FieldTrialParameter<DataRate> uncertainty_symmetry_cap_;
   FieldTrialParameter<DataRate> estimate_floor_;
   int64_t current_window_ms_;