Add base class NetworkPredictor and NetworkPredictorFactory and wire up.

Add base class NetworkPredictor and NetworkPredictorFactory in /api, make it possible to inject customized NetworkPredictor in PeerConnectionFactory level. The NetworkPredictor object will be pass down to GoogCCNetworkControl and DelayBasedBwe.

Bug: webrtc:10492
Change-Id: Iceeadbe1c9388b11ce4ac01ee56554cb0bf64d04
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130201
Commit-Queue: Ying Wang <yinwa@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27543}
diff --git a/modules/congestion_controller/OWNERS b/modules/congestion_controller/OWNERS
index de51596..a9a7075 100644
--- a/modules/congestion_controller/OWNERS
+++ b/modules/congestion_controller/OWNERS
@@ -3,6 +3,7 @@
 terelius@webrtc.org
 philipel@webrtc.org
 mflodman@webrtc.org
+yinwa@webrtc.org
 
 # These are for the common case of adding or renaming files. If you're doing
 # structural changes, please get a review from a reviewer in this file.
diff --git a/modules/congestion_controller/goog_cc/BUILD.gn b/modules/congestion_controller/goog_cc/BUILD.gn
index 0124514..d9749bc 100644
--- a/modules/congestion_controller/goog_cc/BUILD.gn
+++ b/modules/congestion_controller/goog_cc/BUILD.gn
@@ -30,6 +30,8 @@
     ":probe_controller",
     ":pushback_controller",
     "../..:module_api",
+    "../../..:webrtc_common",
+    "../../../api:network_state_predictor_api",
     "../../../api/transport:field_trial_based_config",
     "../../../api/transport:network_control",
     "../../../api/transport:webrtc_key_value_config",
@@ -116,6 +118,7 @@
   ]
 
   deps = [
+    "../../../api:network_state_predictor_api",
     "../../../api/transport:webrtc_key_value_config",
     "../../../api/units:data_rate",
     "../../../logging:rtc_event_bwe",
@@ -143,6 +146,7 @@
 
   deps = [
     ":estimators",
+    "../../../api:network_state_predictor_api",
     "../../../api/transport:network_control",
     "../../../api/transport:webrtc_key_value_config",
     "../../../logging:rtc_event_bwe",
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
index e152521..f551ca5 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
@@ -83,7 +83,8 @@
 DelayBasedBwe::Result::~Result() {}
 
 DelayBasedBwe::DelayBasedBwe(const WebRtcKeyValueConfig* key_value_config,
-                             RtcEventLog* event_log)
+                             RtcEventLog* event_log,
+                             NetworkStatePredictor* network_state_predictor)
     : event_log_(event_log),
       inter_arrival_(),
       delay_detector_(),
@@ -100,13 +101,14 @@
       prev_state_(BandwidthUsage::kBwNormal),
       alr_limited_backoff_enabled_(
           key_value_config->Lookup("WebRTC-Bwe-AlrLimitedBackoff")
-              .find("Enabled") == 0) {
+              .find("Enabled") == 0),
+      network_state_predictor_(network_state_predictor) {
   RTC_LOG(LS_INFO)
       << "Using Trendline filter for delay change estimation with window size "
       << trendline_window_size_;
-  delay_detector_.reset(new TrendlineEstimator(trendline_window_size_,
-                                               trendline_smoothing_coeff_,
-                                               trendline_threshold_gain_));
+  delay_detector_.reset(new TrendlineEstimator(
+      trendline_window_size_, trendline_smoothing_coeff_,
+      trendline_threshold_gain_, network_state_predictor_));
 }
 
 DelayBasedBwe::~DelayBasedBwe() {}
@@ -169,9 +171,9 @@
     inter_arrival_.reset(
         new InterArrival((kTimestampGroupLengthMs << kInterArrivalShift) / 1000,
                          kTimestampToMs, true));
-    delay_detector_.reset(new TrendlineEstimator(trendline_window_size_,
-                                                 trendline_smoothing_coeff_,
-                                                 trendline_threshold_gain_));
+    delay_detector_.reset(new TrendlineEstimator(
+        trendline_window_size_, trendline_smoothing_coeff_,
+        trendline_threshold_gain_, network_state_predictor_));
   }
   last_seen_packet_ = at_time;
 
@@ -189,13 +191,12 @@
   uint32_t ts_delta = 0;
   int64_t t_delta = 0;
   int size_delta = 0;
-  if (inter_arrival_->ComputeDeltas(timestamp, packet_feedback.arrival_time_ms,
-                                    at_time.ms(), packet_feedback.payload_size,
-                                    &ts_delta, &t_delta, &size_delta)) {
-    double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
-    delay_detector_->Update(t_delta, ts_delta_ms,
-                            packet_feedback.arrival_time_ms);
-  }
+  bool calculated_deltas = inter_arrival_->ComputeDeltas(
+      timestamp, packet_feedback.arrival_time_ms, at_time.ms(),
+      packet_feedback.payload_size, &ts_delta, &t_delta, &size_delta);
+  double ts_delta_ms = (1000.0 * ts_delta) / (1 << kInterArrivalShift);
+  delay_detector_->Update(t_delta, ts_delta_ms, packet_feedback.send_time_ms,
+                          packet_feedback.arrival_time_ms, calculated_deltas);
 }
 
 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.h b/modules/congestion_controller/goog_cc/delay_based_bwe.h
index c891afc..34d356e 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.h
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.h
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/network_state_predictor.h"
 #include "api/transport/webrtc_key_value_config.h"
 #include "modules/congestion_controller/goog_cc/delay_increase_detector_interface.h"
 #include "modules/congestion_controller/goog_cc/probe_bitrate_estimator.h"
@@ -44,7 +45,8 @@
   };
 
   explicit DelayBasedBwe(const WebRtcKeyValueConfig* key_value_config,
-                         RtcEventLog* event_log);
+                         RtcEventLog* event_log,
+                         NetworkStatePredictor* network_state_predictor);
   virtual ~DelayBasedBwe();
 
   Result IncomingPacketFeedbackVector(
@@ -88,6 +90,7 @@
   DataRate prev_bitrate_;
   BandwidthUsage prev_state_;
   bool alr_limited_backoff_enabled_;
+  NetworkStatePredictor* network_state_predictor_;
 
   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe);
 };
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
index c057656..3611fee 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc
@@ -155,7 +155,8 @@
           absl::make_unique<AcknowledgedBitrateEstimator>(
               &field_trial_config_)),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
-      bitrate_estimator_(new DelayBasedBwe(&field_trial_config_, nullptr)),
+      bitrate_estimator_(
+          new DelayBasedBwe(&field_trial_config_, nullptr, nullptr)),
       stream_generator_(new test::StreamGenerator(1e6,  // Capacity.
                                                   clock_.TimeInMicroseconds())),
       arrival_time_offset_ms_(0),
@@ -169,7 +170,8 @@
           absl::make_unique<AcknowledgedBitrateEstimator>(
               &field_trial_config_)),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
-      bitrate_estimator_(new DelayBasedBwe(&field_trial_config_, nullptr)),
+      bitrate_estimator_(
+          new DelayBasedBwe(&field_trial_config_, nullptr, nullptr)),
       stream_generator_(new test::StreamGenerator(1e6,  // Capacity.
                                                   clock_.TimeInMicroseconds())),
       arrival_time_offset_ms_(0),
diff --git a/modules/congestion_controller/goog_cc/delay_increase_detector_interface.h b/modules/congestion_controller/goog_cc/delay_increase_detector_interface.h
index 40d945d..d1d7496 100644
--- a/modules/congestion_controller/goog_cc/delay_increase_detector_interface.h
+++ b/modules/congestion_controller/goog_cc/delay_increase_detector_interface.h
@@ -26,7 +26,9 @@
   // between timestamp groups as defined by the InterArrival class.
   virtual void Update(double recv_delta_ms,
                       double send_delta_ms,
-                      int64_t arrival_time_ms) = 0;
+                      int64_t send_time_ms,
+                      int64_t arrival_time_ms,
+                      bool calculated_deltas) = 0;
 
   virtual BandwidthUsage State() const = 0;
 
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
index e3e1dcc..06d94fe 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -17,6 +17,7 @@
 #include <memory>
 #include <numeric>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "absl/memory/memory.h"
@@ -77,9 +78,11 @@
 }
 }  // namespace
 
-GoogCcNetworkController::GoogCcNetworkController(RtcEventLog* event_log,
-                                                 NetworkControllerConfig config,
-                                                 bool feedback_only)
+GoogCcNetworkController::GoogCcNetworkController(
+    RtcEventLog* event_log,
+    NetworkControllerConfig config,
+    bool feedback_only,
+    std::unique_ptr<NetworkStatePredictor> network_state_predictor)
     : key_value_config_(config.key_value_config ? config.key_value_config
                                                 : &trial_based_config_),
       event_log_(event_log),
@@ -104,7 +107,9 @@
           absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
       alr_detector_(absl::make_unique<AlrDetector>()),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log)),
-      delay_based_bwe_(new DelayBasedBwe(key_value_config_, event_log_)),
+      delay_based_bwe_(new DelayBasedBwe(key_value_config_,
+                                         event_log_,
+                                         network_state_predictor.get())),
       acknowledged_bitrate_estimator_(
           absl::make_unique<AcknowledgedBitrateEstimator>(key_value_config_)),
       initial_config_(config),
@@ -117,7 +122,8 @@
               DataRate::Zero())),
       max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
           DataRate::Zero())),
-      max_total_allocated_bitrate_(DataRate::Zero()) {
+      max_total_allocated_bitrate_(DataRate::Zero()),
+      network_state_predictor_(std::move(network_state_predictor)) {
   RTC_DCHECK(config.constraints.at_time.IsFinite());
   ParseFieldTrial(
       {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
@@ -164,7 +170,8 @@
   acknowledged_bitrate_estimator_.reset(
       new AcknowledgedBitrateEstimator(key_value_config_));
   probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
-  delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_));
+  delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_,
+                                           network_state_predictor_.get()));
   bandwidth_estimation_->OnRouteChange();
   probe_controller_->Reset(msg.at_time.ms());
   NetworkControlUpdate update;
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.h b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
index 09e0649..c4e8409 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
@@ -17,6 +17,7 @@
 #include <vector>
 
 #include "absl/types/optional.h"
+#include "api/network_state_predictor.h"
 #include "api/transport/field_trial_based_config.h"
 #include "api/transport/network_control.h"
 #include "api/transport/network_types.h"
@@ -40,9 +41,11 @@
 
 class GoogCcNetworkController : public NetworkControllerInterface {
  public:
-  GoogCcNetworkController(RtcEventLog* event_log,
-                          NetworkControllerConfig config,
-                          bool feedback_only);
+  GoogCcNetworkController(
+      RtcEventLog* event_log,
+      NetworkControllerConfig config,
+      bool feedback_only,
+      std::unique_ptr<NetworkStatePredictor> network_state_predictor);
   ~GoogCcNetworkController() override;
 
   // NetworkControllerInterface
@@ -121,6 +124,8 @@
 
   absl::optional<DataSize> current_data_window_;
 
+  std::unique_ptr<NetworkStatePredictor> network_state_predictor_;
+
   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(GoogCcNetworkController);
 };
 
diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
index 1831f5d..a7bc235 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control_unittest.cc
@@ -110,7 +110,7 @@
 class GoogCcNetworkControllerTest : public ::testing::Test {
  protected:
   GoogCcNetworkControllerTest()
-      : current_time_(Timestamp::ms(123456)), factory_(&event_log_) {}
+      : current_time_(Timestamp::ms(123456)), factory_(&event_log_, nullptr) {}
   ~GoogCcNetworkControllerTest() override {}
 
   void SetUp() override {
diff --git a/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc b/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
index aba3cec..51ff387 100644
--- a/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
+++ b/modules/congestion_controller/goog_cc/test/goog_cc_printer.cc
@@ -60,7 +60,7 @@
 
 GoogCcDebugFactory::GoogCcDebugFactory(RtcEventLog* event_log,
                                        GoogCcStatePrinter* printer)
-    : GoogCcNetworkControllerFactory(event_log), printer_(printer) {}
+    : GoogCcNetworkControllerFactory(event_log, nullptr), printer_(printer) {}
 
 std::unique_ptr<NetworkControllerInterface> GoogCcDebugFactory::Create(
     NetworkControllerConfig config) {
diff --git a/modules/congestion_controller/goog_cc/trendline_estimator.cc b/modules/congestion_controller/goog_cc/trendline_estimator.cc
index e6fff8e..7db15a4 100644
--- a/modules/congestion_controller/goog_cc/trendline_estimator.cc
+++ b/modules/congestion_controller/goog_cc/trendline_estimator.cc
@@ -15,6 +15,7 @@
 #include <algorithm>
 
 #include "absl/types/optional.h"
+#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
 #include "modules/remote_bitrate_estimator/test/bwe_test_logging.h"
 #include "rtc_base/checks.h"
 #include "rtc_base/numerics/safe_minmax.h"
@@ -53,9 +54,11 @@
 
 }  // namespace
 
-TrendlineEstimator::TrendlineEstimator(size_t window_size,
-                                       double smoothing_coef,
-                                       double threshold_gain)
+TrendlineEstimator::TrendlineEstimator(
+    size_t window_size,
+    double smoothing_coef,
+    double threshold_gain,
+    NetworkStatePredictor* network_state_predictor)
     : window_size_(window_size),
       smoothing_coef_(smoothing_coef),
       threshold_gain_(threshold_gain),
@@ -73,51 +76,61 @@
       prev_trend_(0.0),
       time_over_using_(-1),
       overuse_counter_(0),
-      hypothesis_(BandwidthUsage::kBwNormal) {}
+      hypothesis_(BandwidthUsage::kBwNormal),
+      hypothesis_predicted_(BandwidthUsage::kBwNormal),
+      network_state_predictor_(network_state_predictor) {}
 
 TrendlineEstimator::~TrendlineEstimator() {}
 
 void TrendlineEstimator::Update(double recv_delta_ms,
                                 double send_delta_ms,
-                                int64_t arrival_time_ms) {
-  const double delta_ms = recv_delta_ms - send_delta_ms;
-  ++num_of_deltas_;
-  num_of_deltas_ = std::min(num_of_deltas_, kDeltaCounterMax);
-  if (first_arrival_time_ms_ == -1)
-    first_arrival_time_ms_ = arrival_time_ms;
+                                int64_t send_time_ms,
+                                int64_t arrival_time_ms,
+                                bool calculated_deltas) {
+  if (calculated_deltas) {
+    const double delta_ms = recv_delta_ms - send_delta_ms;
+    ++num_of_deltas_;
+    num_of_deltas_ = std::min(num_of_deltas_, kDeltaCounterMax);
+    if (first_arrival_time_ms_ == -1)
+      first_arrival_time_ms_ = arrival_time_ms;
 
-  // Exponential backoff filter.
-  accumulated_delay_ += delta_ms;
-  BWE_TEST_LOGGING_PLOT(1, "accumulated_delay_ms", arrival_time_ms,
-                        accumulated_delay_);
-  smoothed_delay_ = smoothing_coef_ * smoothed_delay_ +
-                    (1 - smoothing_coef_) * accumulated_delay_;
-  BWE_TEST_LOGGING_PLOT(1, "smoothed_delay_ms", arrival_time_ms,
-                        smoothed_delay_);
+    // Exponential backoff filter.
+    accumulated_delay_ += delta_ms;
+    BWE_TEST_LOGGING_PLOT(1, "accumulated_delay_ms", arrival_time_ms,
+                          accumulated_delay_);
+    smoothed_delay_ = smoothing_coef_ * smoothed_delay_ +
+                      (1 - smoothing_coef_) * accumulated_delay_;
+    BWE_TEST_LOGGING_PLOT(1, "smoothed_delay_ms", arrival_time_ms,
+                          smoothed_delay_);
 
-  // Simple linear regression.
-  delay_hist_.push_back(std::make_pair(
-      static_cast<double>(arrival_time_ms - first_arrival_time_ms_),
-      smoothed_delay_));
-  if (delay_hist_.size() > window_size_)
-    delay_hist_.pop_front();
-  double trend = prev_trend_;
-  if (delay_hist_.size() == window_size_) {
-    // Update trend_ if it is possible to fit a line to the data. The delay
-    // trend can be seen as an estimate of (send_rate - capacity)/capacity.
-    // 0 < trend < 1   ->  the delay increases, queues are filling up
-    //   trend == 0    ->  the delay does not change
-    //   trend < 0     ->  the delay decreases, queues are being emptied
-    trend = LinearFitSlope(delay_hist_).value_or(trend);
+    // Simple linear regression.
+    delay_hist_.push_back(std::make_pair(
+        static_cast<double>(arrival_time_ms - first_arrival_time_ms_),
+        smoothed_delay_));
+    if (delay_hist_.size() > window_size_)
+      delay_hist_.pop_front();
+    double trend = prev_trend_;
+    if (delay_hist_.size() == window_size_) {
+      // Update trend_ if it is possible to fit a line to the data. The delay
+      // trend can be seen as an estimate of (send_rate - capacity)/capacity.
+      // 0 < trend < 1   ->  the delay increases, queues are filling up
+      //   trend == 0    ->  the delay does not change
+      //   trend < 0     ->  the delay decreases, queues are being emptied
+      trend = LinearFitSlope(delay_hist_).value_or(trend);
+    }
+
+    BWE_TEST_LOGGING_PLOT(1, "trendline_slope", arrival_time_ms, trend);
+
+    Detect(trend, send_delta_ms, arrival_time_ms);
   }
-
-  BWE_TEST_LOGGING_PLOT(1, "trendline_slope", arrival_time_ms, trend);
-
-  Detect(trend, send_delta_ms, arrival_time_ms);
+  if (network_state_predictor_) {
+    hypothesis_predicted_ = network_state_predictor_->Update(
+        send_time_ms, arrival_time_ms, hypothesis_);
+  }
 }
 
 BandwidthUsage TrendlineEstimator::State() const {
-  return hypothesis_;
+  return network_state_predictor_ ? hypothesis_predicted_ : hypothesis_;
 }
 
 void TrendlineEstimator::Detect(double trend, double ts_delta, int64_t now_ms) {
diff --git a/modules/congestion_controller/goog_cc/trendline_estimator.h b/modules/congestion_controller/goog_cc/trendline_estimator.h
index 260cd03..f85c0fc 100644
--- a/modules/congestion_controller/goog_cc/trendline_estimator.h
+++ b/modules/congestion_controller/goog_cc/trendline_estimator.h
@@ -15,6 +15,7 @@
 #include <deque>
 #include <utility>
 
+#include "api/network_state_predictor.h"
 #include "modules/congestion_controller/goog_cc/delay_increase_detector_interface.h"
 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
 #include "rtc_base/constructor_magic.h"
@@ -28,10 +29,12 @@
   // the trend line. |threshold_gain| is used to scale the trendline slope for
   // comparison to the old threshold. Once the old estimator has been removed
   // (or the thresholds been merged into the estimators), we can just set the
-  // threshold instead of setting a gain.
+  // threshold instead of setting a gain.|network_state_predictor| is used to
+  // bettter predict network state.
   TrendlineEstimator(size_t window_size,
                      double smoothing_coef,
-                     double threshold_gain);
+                     double threshold_gain,
+                     NetworkStatePredictor* network_state_predictor);
 
   ~TrendlineEstimator() override;
 
@@ -39,7 +42,9 @@
   // between timestamp groups as defined by the InterArrival class.
   void Update(double recv_delta_ms,
               double send_delta_ms,
-              int64_t arrival_time_ms) override;
+              int64_t send_time_ms,
+              int64_t arrival_time_ms,
+              bool calculated_deltas) override;
 
   BandwidthUsage State() const override;
 
@@ -78,6 +83,8 @@
   double time_over_using_;
   int overuse_counter_;
   BandwidthUsage hypothesis_;
+  BandwidthUsage hypothesis_predicted_;
+  NetworkStatePredictor* network_state_predictor_;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(TrendlineEstimator);
 };
diff --git a/modules/congestion_controller/goog_cc/trendline_estimator_unittest.cc b/modules/congestion_controller/goog_cc/trendline_estimator_unittest.cc
index 7140763..d2e6cf0 100644
--- a/modules/congestion_controller/goog_cc/trendline_estimator_unittest.cc
+++ b/modules/congestion_controller/goog_cc/trendline_estimator_unittest.cc
@@ -26,7 +26,7 @@
   using TrendlineEstimator::modified_trend;
 };
 void TestEstimator(double slope, double jitter_stddev, double tolerance) {
-  TrendlineEstimatorForTest estimator(kWindowSize, kSmoothing, kGain);
+  TrendlineEstimatorForTest estimator(kWindowSize, kSmoothing, kGain, nullptr);
   Random random(0x1234567);
   int64_t send_times[kPacketCount];
   int64_t recv_times[kPacketCount];
@@ -41,7 +41,7 @@
   for (size_t i = 1; i < kPacketCount; ++i) {
     double recv_delta = recv_times[i] - recv_times[i - 1];
     double send_delta = send_times[i] - send_times[i - 1];
-    estimator.Update(recv_delta, send_delta, recv_times[i]);
+    estimator.Update(recv_delta, send_delta, 0, recv_times[i], true);
     if (i < kWindowSize)
       EXPECT_NEAR(estimator.modified_trend(), 0, 0.001);
     else
diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc
index 1080f9b..cf5b7a2 100644
--- a/modules/congestion_controller/send_side_congestion_controller.cc
+++ b/modules/congestion_controller/send_side_congestion_controller.cc
@@ -104,7 +104,8 @@
       pacer_paused_(false),
       min_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log_)),
-      delay_based_bwe_(new DelayBasedBwe(key_value_config_, event_log_)),
+      delay_based_bwe_(
+          new DelayBasedBwe(key_value_config_, event_log_, nullptr)),
       was_in_alr_(false),
       send_side_bwe_with_overhead_(
           key_value_config_->Lookup("WebRTC-SendSideBwe-WithOverhead")
@@ -235,7 +236,8 @@
     transport_overhead_bytes_per_packet_ = network_route.packet_overhead;
     min_bitrate_bps_ = min_bitrate_bps;
     probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
-    delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_));
+    delay_based_bwe_.reset(
+        new DelayBasedBwe(key_value_config_, event_log_, nullptr));
     acknowledged_bitrate_estimator_.reset(
         new AcknowledgedBitrateEstimator(key_value_config_));
     if (bitrate_bps > 0) {
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index 91e8a77..3094e8c 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -41,6 +41,7 @@
 
   deps = [
     "../..:webrtc_common",
+    "../../api:network_state_predictor_api",
     "../../api:rtp_headers",
     "../../api/units:data_rate",
     "../../api/units:timestamp",
diff --git a/modules/remote_bitrate_estimator/include/bwe_defines.h b/modules/remote_bitrate_estimator/include/bwe_defines.h
index 5223a6b..40fbfe0 100644
--- a/modules/remote_bitrate_estimator/include/bwe_defines.h
+++ b/modules/remote_bitrate_estimator/include/bwe_defines.h
@@ -14,6 +14,7 @@
 #include <stdint.h>
 
 #include "absl/types/optional.h"
+#include "api/network_state_predictor.h"
 #include "api/units/data_rate.h"
 
 #define BWE_MAX(a, b) ((a) > (b) ? (a) : (b))
@@ -38,13 +39,6 @@
   kBweNamesMax = 4
 };
 
-enum class BandwidthUsage {
-  kBwNormal = 0,
-  kBwUnderusing = 1,
-  kBwOverusing = 2,
-  kLast
-};
-
 enum RateControlState { kRcHold, kRcIncrease, kRcDecrease };
 
 struct RateControlInput {
diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/modules/remote_bitrate_estimator/test/estimators/send_side.cc
index 7b33cd4..c4b81c7 100644
--- a/modules/remote_bitrate_estimator/test/estimators/send_side.cc
+++ b/modules/remote_bitrate_estimator/test/estimators/send_side.cc
@@ -38,7 +38,7 @@
           absl::make_unique<AcknowledgedBitrateEstimator>(
               &field_trial_config_)),
       probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
-      bwe_(new DelayBasedBwe(&field_trial_config_, nullptr)),
+      bwe_(new DelayBasedBwe(&field_trial_config_, nullptr, nullptr)),
       feedback_observer_(bitrate_controller_.get()),
       clock_(clock),
       send_time_history_(10000),