Reland of https://chromium-review.googlesource.com/c/external/webrtc/+/616724 under field trial.

Bug: webrtc:8105
Change-Id: I8c68e0f270b3bd5d8da28b8334d4689064f607f6
Reviewed-on: https://webrtc-review.googlesource.com/4920
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Alex Narest <alexnarest@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#20205}
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.cc b/modules/remote_bitrate_estimator/aimd_rate_control.cc
index 96b0534..37c2529 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -68,7 +68,9 @@
                 ? ReadTrendlineFilterWindowSize()
                 : kDefaultBackoffFactor),
       rtt_(kDefaultRttMs),
-      in_experiment_(!AdaptiveThresholdExperimentIsDisabled()) {
+      in_experiment_(!AdaptiveThresholdExperimentIsDisabled()),
+      smoothing_experiment_(
+          webrtc::field_trial::IsEnabled("WebRTC-Audio-BandwidthSmoothing")) {
   LOG(LS_INFO) << "Using aimd rate control with back off factor " << beta_;
 }
 
@@ -166,13 +168,13 @@
 }
 
 int AimdRateControl::GetExpectedBandwidthPeriodMs() const {
-  constexpr int kMinPeriodMs = 2000;
+  const int kMinPeriodMs = smoothing_experiment_ ? 500 : 2000;
   constexpr int kDefaultPeriodMs = 3000;
   constexpr int kMaxPeriodMs = 50000;
 
   int increase_rate = GetNearMaxIncreaseRateBps();
   if (!last_decrease_)
-    return kDefaultPeriodMs;
+    return smoothing_experiment_ ? kMinPeriodMs : kDefaultPeriodMs;
 
   return std::min(kMaxPeriodMs,
                   std::max<int>(1000 * static_cast<int64_t>(*last_decrease_) /
@@ -241,8 +243,18 @@
 
       if (bitrate_is_initialized_ &&
           incoming_bitrate_bps < current_bitrate_bps_) {
-        last_decrease_ =
-            rtc::Optional<int>(current_bitrate_bps_ - new_bitrate_bps);
+        constexpr float kDegradationFactor = 0.9f;
+        if (smoothing_experiment_ &&
+            new_bitrate_bps <
+                kDegradationFactor * beta_ * current_bitrate_bps_) {
+          // If bitrate decreases more than a normal back off after overuse, it
+          // indicates a real network degradation. We do not let such a decrease
+          // to determine the bandwidth estimation period.
+          last_decrease_ = rtc::Optional<int>();
+        } else {
+          last_decrease_ =
+              rtc::Optional<int>(current_bitrate_bps_ - new_bitrate_bps);
+        }
       }
       if (incoming_bitrate_kbps <
           avg_max_bitrate_kbps_ - 3 * std_max_bit_rate) {
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.h b/modules/remote_bitrate_estimator/aimd_rate_control.h
index 769429a..a9ecb67 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -85,6 +85,7 @@
   float beta_;
   int64_t rtt_;
   bool in_experiment_;
+  bool smoothing_experiment_;
   rtc::Optional<int> last_decrease_;
 };
 }  // namespace webrtc
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
index 690eb68..1e894d9 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
@@ -11,6 +11,7 @@
 
 #include "modules/remote_bitrate_estimator/aimd_rate_control.h"
 #include "system_wrappers/include/clock.h"
+#include "test/field_trial.h"
 #include "test/gtest.h"
 
 namespace webrtc {
@@ -18,9 +19,12 @@
 
 constexpr int64_t kClockInitialTime = 123456;
 
-constexpr int kMinBwePeriodMs = 2000;
+constexpr int kMinBwePeriodMsSmoothingExp = 500;
+constexpr int kMinBwePeriodMsNoSmoothingExp = 2000;
+constexpr int kDefaultPeriodMsNoSmoothingExp = 3000;
 constexpr int kMaxBwePeriodMs = 50000;
-constexpr int kDefaultPeriodMs = 3000;
+constexpr char kSmoothingExpFieldTrial[] =
+    "WebRTC-Audio-BandwidthSmoothing/Enabled/";
 
 // After an overuse, we back off to 85% to the received bitrate.
 constexpr double kFractionAfterOveruse = 0.85;
@@ -74,6 +78,7 @@
 }
 
 TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriod) {
+  // Smoothing experiment disabled
   auto states = CreateAimdRateControlStates();
   constexpr int kBitrate = 300000;
   states.aimd_rate_control->SetEstimate(
@@ -82,7 +87,23 @@
                     states.simulated_clock->TimeInMilliseconds());
   EXPECT_NEAR(14000, states.aimd_rate_control->GetNearMaxIncreaseRateBps(),
               1000);
-  EXPECT_EQ(3000, states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+  EXPECT_EQ(kDefaultPeriodMsNoSmoothingExp,
+            states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+}
+
+TEST(AimdRateControlTest, GetIncreaseRateAndBandwidthPeriodSmoothingExp) {
+  // Smoothing experiment enabled
+  test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
+  auto states = CreateAimdRateControlStates();
+  constexpr int kBitrate = 300000;
+  states.aimd_rate_control->SetEstimate(
+      kBitrate, states.simulated_clock->TimeInMilliseconds());
+  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kBitrate,
+                    states.simulated_clock->TimeInMilliseconds());
+  EXPECT_NEAR(14000, states.aimd_rate_control->GetNearMaxIncreaseRateBps(),
+              1000);
+  EXPECT_EQ(kMinBwePeriodMsSmoothingExp,
+            states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
 }
 
 TEST(AimdRateControlTest, BweLimitedByAckedBitrate) {
@@ -125,14 +146,29 @@
 }
 
 TEST(AimdRateControlTest, DefaultPeriodUntilFirstOveruse) {
+  // Smoothing experiment disabled
   auto states = CreateAimdRateControlStates();
   states.aimd_rate_control->SetStartBitrate(300000);
-  EXPECT_EQ(kDefaultPeriodMs,
+  EXPECT_EQ(kDefaultPeriodMsNoSmoothingExp,
             states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
   states.simulated_clock->AdvanceTimeMilliseconds(100);
-  UpdateRateControl(states, BandwidthUsage::kBwOverusing, 100000,
+  UpdateRateControl(states, BandwidthUsage::kBwOverusing, 280000,
                     states.simulated_clock->TimeInMilliseconds());
-  EXPECT_NE(kDefaultPeriodMs,
+  EXPECT_NE(kDefaultPeriodMsNoSmoothingExp,
+            states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+}
+
+TEST(AimdRateControlTest, MinPeriodUntilFirstOveruseSmoothingExp) {
+  // Smoothing experiment enabled
+  test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
+  auto states = CreateAimdRateControlStates();
+  states.aimd_rate_control->SetStartBitrate(300000);
+  EXPECT_EQ(kMinBwePeriodMsSmoothingExp,
+            states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+  states.simulated_clock->AdvanceTimeMilliseconds(100);
+  UpdateRateControl(states, BandwidthUsage::kBwOverusing, 280000,
+                    states.simulated_clock->TimeInMilliseconds());
+  EXPECT_NE(kMinBwePeriodMsSmoothingExp,
             states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
 }
 
@@ -152,6 +188,23 @@
   EXPECT_EQ(4000, states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
 }
 
+TEST(AimdRateControlTest, MinPeriodAfterLargeBitrateDecreaseSmoothingExp) {
+  // Smoothing experiment enabled
+  test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
+  auto states = CreateAimdRateControlStates();
+  constexpr int kInitialBitrate = 110000;
+  states.aimd_rate_control->SetEstimate(
+      kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+  states.simulated_clock->AdvanceTimeMilliseconds(100);
+  // Make such a large drop in bitrate that should be treated as network
+  // degradation.
+  constexpr int kAckedBitrate = kInitialBitrate * 3 / 4 / kFractionAfterOveruse;
+  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
+                    states.simulated_clock->TimeInMilliseconds());
+  EXPECT_EQ(kMinBwePeriodMsSmoothingExp,
+            states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+}
+
 TEST(AimdRateControlTest, BandwidthPeriodIsNotBelowMin) {
   auto states = CreateAimdRateControlStates();
   constexpr int kInitialBitrate = 10000;
@@ -161,11 +214,27 @@
   // Make a small (1.5 kbps) bitrate drop to 8.5 kbps.
   UpdateRateControl(states, BandwidthUsage::kBwOverusing, kInitialBitrate - 1,
                     states.simulated_clock->TimeInMilliseconds());
-  EXPECT_EQ(kMinBwePeriodMs,
+  EXPECT_EQ(kMinBwePeriodMsNoSmoothingExp,
             states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
 }
 
-TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMax) {
+TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxSmoothingExp) {
+  // Smoothing experiment enabled
+  test::ScopedFieldTrials override_field_trials(kSmoothingExpFieldTrial);
+  auto states = CreateAimdRateControlStates();
+  constexpr int kInitialBitrate = 50000000;
+  states.aimd_rate_control->SetEstimate(
+      kInitialBitrate, states.simulated_clock->TimeInMilliseconds());
+  states.simulated_clock->AdvanceTimeMilliseconds(100);
+  // Make a large (10 Mbps) bitrate drop to 10 kbps.
+  constexpr int kAckedBitrate = 40000000 / kFractionAfterOveruse;
+  UpdateRateControl(states, BandwidthUsage::kBwOverusing, kAckedBitrate,
+                    states.simulated_clock->TimeInMilliseconds());
+  EXPECT_EQ(kMaxBwePeriodMs,
+            states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
+}
+
+TEST(AimdRateControlTest, BandwidthPeriodIsNotAboveMaxNoSmoothingExp) {
   auto states = CreateAimdRateControlStates();
   constexpr int kInitialBitrate = 10010000;
   states.aimd_rate_control->SetEstimate(