Allow injection of network estimator into GoogCC.

Bug: webrtc:10498
Change-Id: Ie9225411db201dfcfa0a37a3c40992acbdc215bb
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/132402
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27624}
diff --git a/api/transport/goog_cc_factory.cc b/api/transport/goog_cc_factory.cc
index 00f6a2e..2187da3 100644
--- a/api/transport/goog_cc_factory.cc
+++ b/api/transport/goog_cc_factory.cc
@@ -10,7 +10,7 @@
 
 #include "api/transport/goog_cc_factory.h"
 
-#include <stdint.h>
+#include <utility>
 
 #include "absl/memory/memory.h"
 #include "modules/congestion_controller/goog_cc/goog_cc_network_control.h"
@@ -18,21 +18,37 @@
 namespace webrtc {
 GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
     RtcEventLog* event_log)
-    : event_log_(event_log), network_state_predictor_factory_(nullptr) {}
+    : event_log_(event_log) {}
 
 GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
-    RtcEventLog* event_log,
-    NetworkStatePredictorFactoryInterface* network_state_predictor_factory)
-    : event_log_(event_log),
-      network_state_predictor_factory_(network_state_predictor_factory) {}
+    NetworkStatePredictorFactoryInterface* network_state_predictor_factory) {
+  factory_config_.network_state_predictor_factory =
+      network_state_predictor_factory;
+}
+
+GoogCcNetworkControllerFactory::GoogCcNetworkControllerFactory(
+    GoogCcFactoryConfig config)
+    : factory_config_(std::move(config)) {}
 
 std::unique_ptr<NetworkControllerInterface>
 GoogCcNetworkControllerFactory::Create(NetworkControllerConfig config) {
-  return absl::make_unique<GoogCcNetworkController>(
-      event_log_, config, false,
-      network_state_predictor_factory_
-          ? network_state_predictor_factory_->CreateNetworkStatePredictor()
-          : nullptr);
+  if (event_log_)
+    config.event_log = event_log_;
+  GoogCcConfig goog_cc_config;
+  goog_cc_config.feedback_only = factory_config_.feedback_only;
+  if (factory_config_.network_state_estimator_factory) {
+    RTC_DCHECK(config.key_value_config);
+    goog_cc_config.network_state_estimator =
+        factory_config_.network_state_estimator_factory->Create(
+            config.key_value_config);
+  }
+  if (factory_config_.network_state_predictor_factory) {
+    goog_cc_config.network_state_predictor =
+        factory_config_.network_state_predictor_factory
+            ->CreateNetworkStatePredictor();
+  }
+  return absl::make_unique<GoogCcNetworkController>(config,
+                                                    std::move(goog_cc_config));
 }
 
 TimeDelta GoogCcNetworkControllerFactory::GetProcessInterval() const {
@@ -42,16 +58,8 @@
 
 GoogCcFeedbackNetworkControllerFactory::GoogCcFeedbackNetworkControllerFactory(
     RtcEventLog* event_log)
-    : event_log_(event_log) {}
-
-std::unique_ptr<NetworkControllerInterface>
-GoogCcFeedbackNetworkControllerFactory::Create(NetworkControllerConfig config) {
-  return absl::make_unique<GoogCcNetworkController>(event_log_, config, true,
-                                                    nullptr);
+    : GoogCcNetworkControllerFactory(event_log) {
+  factory_config_.feedback_only = true;
 }
 
-TimeDelta GoogCcFeedbackNetworkControllerFactory::GetProcessInterval() const {
-  const int64_t kUpdateIntervalMs = 25;
-  return TimeDelta::ms(kUpdateIntervalMs);
-}
 }  // namespace webrtc
diff --git a/api/transport/goog_cc_factory.h b/api/transport/goog_cc_factory.h
index dbf4fe1..fb85c78 100644
--- a/api/transport/goog_cc_factory.h
+++ b/api/transport/goog_cc_factory.h
@@ -18,35 +18,39 @@
 namespace webrtc {
 class RtcEventLog;
 
+struct GoogCcFactoryConfig {
+  std::unique_ptr<NetworkStateEstimatorFactory>
+      network_state_estimator_factory = nullptr;
+  NetworkStatePredictorFactoryInterface* network_state_predictor_factory =
+      nullptr;
+  bool feedback_only = false;
+};
+
 class GoogCcNetworkControllerFactory
     : public NetworkControllerFactoryInterface {
  public:
   explicit GoogCcNetworkControllerFactory(RtcEventLog* event_log);
   explicit GoogCcNetworkControllerFactory(
-      RtcEventLog* event_log,
       NetworkStatePredictorFactoryInterface* network_state_predictor_factory);
+
+  explicit GoogCcNetworkControllerFactory(GoogCcFactoryConfig config);
   std::unique_ptr<NetworkControllerInterface> Create(
       NetworkControllerConfig config) override;
   TimeDelta GetProcessInterval() const override;
 
- private:
-  RtcEventLog* const event_log_;
-  NetworkStatePredictorFactoryInterface* const network_state_predictor_factory_;
+ protected:
+  RtcEventLog* const event_log_ = nullptr;
+  GoogCcFactoryConfig factory_config_;
 };
 
 // Factory to create packet feedback only GoogCC, this can be used for
 // connections providing packet receive time feedback but no other reports.
 class GoogCcFeedbackNetworkControllerFactory
-    : public NetworkControllerFactoryInterface {
+    : public GoogCcNetworkControllerFactory {
  public:
   explicit GoogCcFeedbackNetworkControllerFactory(RtcEventLog* event_log);
-  std::unique_ptr<NetworkControllerInterface> Create(
-      NetworkControllerConfig config) override;
-  TimeDelta GetProcessInterval() const override;
-
- private:
-  RtcEventLog* const event_log_;
 };
+
 }  // namespace webrtc
 
 #endif  // API_TRANSPORT_GOOG_CC_FACTORY_H_
diff --git a/api/transport/network_control.h b/api/transport/network_control.h
index 53ac10e..99f1491 100644
--- a/api/transport/network_control.h
+++ b/api/transport/network_control.h
@@ -17,6 +17,8 @@
 #include "api/transport/webrtc_key_value_config.h"
 
 namespace webrtc {
+// TODO(srte): Remove this forward declaration when this is in api.
+class RtcEventLog;
 
 class TargetTransferRateObserver {
  public:
@@ -44,6 +46,8 @@
   // Optional override of configuration of WebRTC internals. Using nullptr here
   // indicates that the field trial API will be used.
   const WebRtcKeyValueConfig* key_value_config = nullptr;
+  // Optional override of event log.
+  RtcEventLog* event_log = nullptr;
 };
 
 // NetworkControllerInterface is implemented by network controllers. A network
@@ -94,6 +98,24 @@
   // OnProcessInterval calls.
   virtual TimeDelta GetProcessInterval() const = 0;
 };
+
+// Under development, subject to change without notice.
+class NetworkStateEstimator {
+ public:
+  // Gets the current best estimate according to the estimator.
+  virtual absl::optional<NetworkStateEstimate> GetCurrentEstimate() = 0;
+  // Called with per packet feedback regarding receive time.
+  virtual void OnTransportPacketsFeedback(const TransportPacketsFeedback&) = 0;
+  // Called when the receiving or sending endpoint changes address.
+  virtual void OnRouteChange(const NetworkRouteChange&) = 0;
+  virtual ~NetworkStateEstimator() = default;
+};
+class NetworkStateEstimatorFactory {
+ public:
+  virtual std::unique_ptr<NetworkStateEstimator> Create(
+      const WebRtcKeyValueConfig* key_value_config) = 0;
+  virtual ~NetworkStateEstimatorFactory() = default;
+};
 }  // namespace webrtc
 
 #endif  // API_TRANSPORT_NETWORK_CONTROL_H_
diff --git a/api/transport/network_types.h b/api/transport/network_types.h
index 730e41b..3e0615d 100644
--- a/api/transport/network_types.h
+++ b/api/transport/network_types.h
@@ -212,6 +212,22 @@
   Timestamp at_time = Timestamp::PlusInfinity();
   absl::optional<DataSize> pacer_queue;
 };
+
+// Under development, subject to change without notice.
+struct NetworkStateEstimate {
+  Timestamp last_feed_time = Timestamp::MinusInfinity();
+  Timestamp last_send_time = Timestamp::MinusInfinity();
+  TimeDelta time_delta = TimeDelta::MinusInfinity();
+  DataRate link_capacity = DataRate::MinusInfinity();
+  DataRate link_capacity_std_dev = DataRate::MinusInfinity();
+  DataRate link_capacity_min = DataRate::MinusInfinity();
+  double cross_traffic_ratio;
+  TimeDelta pre_link_buffer_delay = TimeDelta::MinusInfinity();
+  TimeDelta post_link_buffer_delay = TimeDelta::MinusInfinity();
+  TimeDelta propagation_delay = TimeDelta::MinusInfinity();
+  double cross_delay_rate;
+  double spike_delay_rate;
+};
 }  // namespace webrtc
 
 #endif  // API_TRANSPORT_NETWORK_TYPES_H_
diff --git a/call/rtp_transport_controller_send.cc b/call/rtp_transport_controller_send.cc
index 11e35a9..203d41e 100644
--- a/call/rtp_transport_controller_send.cc
+++ b/call/rtp_transport_controller_send.cc
@@ -70,8 +70,7 @@
       observer_(nullptr),
       controller_factory_override_(controller_factory),
       controller_factory_fallback_(
-          absl::make_unique<GoogCcNetworkControllerFactory>(event_log,
-                                                            predictor_factory)),
+          absl::make_unique<GoogCcNetworkControllerFactory>(predictor_factory)),
       process_interval_(controller_factory_fallback_->GetProcessInterval()),
       last_report_block_time_(Timestamp::ms(clock_->TimeInMilliseconds())),
       reset_feedback_on_route_change_(
@@ -87,6 +86,8 @@
           "rtp_send_controller",
           TaskQueueFactory::Priority::NORMAL)) {
   initial_config_.constraints = ConvertConstraints(bitrate_config, clock_);
+  initial_config_.event_log = event_log;
+  initial_config_.key_value_config = &trial_based_config_;
   RTC_DCHECK(bitrate_config.start_bitrate_bps > 0);
 
   pacer_.SetPacingRates(bitrate_config.start_bitrate_bps, 0);
diff --git a/call/rtp_transport_controller_send.h b/call/rtp_transport_controller_send.h
index 43dc1a0..df4892c 100644
--- a/call/rtp_transport_controller_send.h
+++ b/call/rtp_transport_controller_send.h
@@ -132,6 +132,7 @@
   void UpdateControlState() RTC_RUN_ON(task_queue_);
 
   Clock* const clock_;
+  const FieldTrialBasedConfig trial_based_config_;
   PacketRouter packet_router_;
   std::vector<std::unique_ptr<RtpVideoSenderInterface>> video_rtp_senders_;
   PacedSender pacer_;
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
index f551ca5..450449f 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.cc
@@ -14,9 +14,9 @@
 #include <cstdint>
 #include <cstdio>
 #include <string>
+#include <utility>
 
 #include "absl/memory/memory.h"
-#include "api/transport/network_types.h"  // For PacedPacketInfo
 #include "logging/rtc_event_log/events/rtc_event.h"
 #include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
 #include "logging/rtc_event_log/rtc_event_log.h"
@@ -117,6 +117,7 @@
     const std::vector<PacketFeedback>& packet_feedback_vector,
     absl::optional<DataRate> acked_bitrate,
     absl::optional<DataRate> probe_bitrate,
+    absl::optional<NetworkStateEstimate> network_estimate,
     bool in_alr,
     Timestamp at_time) {
   RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(),
@@ -158,7 +159,9 @@
     // against building very large network queues.
     return Result();
   }
+  rate_control_.SetNetworkStateEstimate(network_estimate);
   return MaybeUpdateEstimate(acked_bitrate, probe_bitrate,
+                             std::move(network_estimate),
                              recovered_from_overuse, in_alr, at_time);
 }
 
@@ -202,6 +205,7 @@
 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
     absl::optional<DataRate> acked_bitrate,
     absl::optional<DataRate> probe_bitrate,
+    absl::optional<NetworkStateEstimate> state_estimate,
     bool recovered_from_overuse,
     bool in_alr,
     Timestamp at_time) {
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.h b/modules/congestion_controller/goog_cc/delay_based_bwe.h
index 34d356e..efd5edb 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe.h
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe.h
@@ -18,6 +18,7 @@
 
 #include "absl/types/optional.h"
 #include "api/network_state_predictor.h"
+#include "api/transport/network_types.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"
@@ -53,6 +54,7 @@
       const std::vector<PacketFeedback>& packet_feedback_vector,
       absl::optional<DataRate> acked_bitrate,
       absl::optional<DataRate> probe_bitrate,
+      absl::optional<NetworkStateEstimate> network_estimate,
       bool in_alr,
       Timestamp at_time);
   void OnRttUpdate(TimeDelta avg_rtt);
@@ -66,11 +68,13 @@
   friend class GoogCcStatePrinter;
   void IncomingPacketFeedback(const PacketFeedback& packet_feedback,
                               Timestamp at_time);
-  Result MaybeUpdateEstimate(absl::optional<DataRate> acked_bitrate,
-                             absl::optional<DataRate> probe_bitrate,
-                             bool recovered_from_overuse,
-                             bool in_alr,
-                             Timestamp at_time);
+  Result MaybeUpdateEstimate(
+      absl::optional<DataRate> acked_bitrate,
+      absl::optional<DataRate> probe_bitrate,
+      absl::optional<NetworkStateEstimate> state_estimate,
+      bool recovered_from_overuse,
+      bool in_alr,
+      Timestamp at_time);
   // Updates the current remote rate estimate and returns true if a valid
   // estimate exists.
   bool UpdateEstimate(Timestamp now,
diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc
index 98bb17a..9a602c2 100644
--- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc
+++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc
@@ -29,9 +29,10 @@
 
 TEST_F(DelayBasedBweTest, NoCrashEmptyFeedback) {
   std::vector<PacketFeedback> packet_feedback_vector;
-  bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector,
-                                                   absl::nullopt, absl::nullopt,
-                                                   false, kDummyTimestamp);
+  bitrate_estimator_->IncomingPacketFeedbackVector(
+      packet_feedback_vector, /*acked_bitrate*/ absl::nullopt,
+      /*probe_bitrate*/ absl::nullopt, /*network_estimate*/ absl::nullopt,
+      /*in_alr*/ false, kDummyTimestamp);
 }
 
 TEST_F(DelayBasedBweTest, NoCrashOnlyLostFeedback) {
@@ -42,9 +43,10 @@
   packet_feedback_vector.push_back(PacketFeedback(PacketFeedback::kNotReceived,
                                                   PacketFeedback::kNoSendTime,
                                                   1, 1500, PacedPacketInfo()));
-  bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector,
-                                                   absl::nullopt, absl::nullopt,
-                                                   false, kDummyTimestamp);
+  bitrate_estimator_->IncomingPacketFeedbackVector(
+      packet_feedback_vector, /*acked_bitrate*/ absl::nullopt,
+      /*probe_bitrate*/ absl::nullopt, /*network_estimate*/ absl::nullopt,
+      /*in_alr*/ false, kDummyTimestamp);
 }
 
 TEST_F(DelayBasedBweTest, ProbeDetection) {
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 3611fee..8baaf3d 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
@@ -211,7 +211,8 @@
   DelayBasedBwe::Result result =
       bitrate_estimator_->IncomingPacketFeedbackVector(
           packets, acknowledged_bitrate_estimator_->bitrate(),
-          probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), false,
+          probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
+          /*network_estimate*/ absl::nullopt, /*in_alr*/ false,
           Timestamp::ms(clock_.TimeInMilliseconds()));
   const uint32_t kDummySsrc = 0;
   if (result.updated) {
@@ -252,7 +253,8 @@
   DelayBasedBwe::Result result =
       bitrate_estimator_->IncomingPacketFeedbackVector(
           packets, acknowledged_bitrate_estimator_->bitrate(),
-          probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), false,
+          probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
+          /*network_estimate*/ absl::nullopt, /*in_alr*/ false,
           Timestamp::ms(clock_.TimeInMilliseconds()));
   const uint32_t kDummySsrc = 0;
   if (result.updated) {
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 489f6a0..ca5728f 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -78,15 +78,12 @@
 }
 }  // namespace
 
-GoogCcNetworkController::GoogCcNetworkController(
-    RtcEventLog* event_log,
-    NetworkControllerConfig config,
-    bool feedback_only,
-    std::unique_ptr<NetworkStatePredictor> network_state_predictor)
+GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config,
+                                                 GoogCcConfig goog_cc_config)
     : key_value_config_(config.key_value_config ? config.key_value_config
                                                 : &trial_based_config_),
-      event_log_(event_log),
-      packet_feedback_only_(feedback_only),
+      event_log_(config.event_log),
+      packet_feedback_only_(goog_cc_config.feedback_only),
       safe_reset_on_route_change_("Enabled"),
       safe_reset_acknowledged_rate_("ack"),
       use_stable_bandwidth_estimate_(
@@ -97,7 +94,8 @@
           IsNotDisabled(key_value_config_, "WebRTC-Bwe-MinAllocAsLowerBound")),
       rate_control_settings_(
           RateControlSettings::ParseFromKeyValueConfig(key_value_config_)),
-      probe_controller_(new ProbeController(key_value_config_, event_log)),
+      probe_controller_(
+          new ProbeController(key_value_config_, config.event_log)),
       congestion_window_pushback_controller_(
           rate_control_settings_.UseCongestionWindowPushback()
               ? absl::make_unique<CongestionWindowPushbackController>(
@@ -106,10 +104,13 @@
       bandwidth_estimation_(
           absl::make_unique<SendSideBandwidthEstimation>(event_log_)),
       alr_detector_(absl::make_unique<AlrDetector>(key_value_config_)),
-      probe_bitrate_estimator_(new ProbeBitrateEstimator(event_log)),
+      probe_bitrate_estimator_(new ProbeBitrateEstimator(config.event_log)),
+      network_estimator_(std::move(goog_cc_config.network_state_estimator)),
+      network_state_predictor_(
+          std::move(goog_cc_config.network_state_predictor)),
       delay_based_bwe_(new DelayBasedBwe(key_value_config_,
                                          event_log_,
-                                         network_state_predictor.get())),
+                                         network_state_predictor_.get())),
       acknowledged_bitrate_estimator_(
           absl::make_unique<AcknowledgedBitrateEstimator>(key_value_config_)),
       initial_config_(config),
@@ -122,8 +123,7 @@
               DataRate::Zero())),
       max_padding_rate_(config.stream_based_config.max_padding_rate.value_or(
           DataRate::Zero())),
-      max_total_allocated_bitrate_(DataRate::Zero()),
-      network_state_predictor_(std::move(network_state_predictor)) {
+      max_total_allocated_bitrate_(DataRate::Zero()) {
   RTC_DCHECK(config.constraints.at_time.IsFinite());
   ParseFieldTrial(
       {&safe_reset_on_route_change_, &safe_reset_acknowledged_rate_},
@@ -170,6 +170,8 @@
   acknowledged_bitrate_estimator_.reset(
       new AcknowledgedBitrateEstimator(key_value_config_));
   probe_bitrate_estimator_.reset(new ProbeBitrateEstimator(event_log_));
+  if (network_estimator_)
+    network_estimator_->OnRouteChange(msg);
   delay_based_bwe_.reset(new DelayBasedBwe(key_value_config_, event_log_,
                                            network_state_predictor_.get()));
   bandwidth_estimation_->OnRouteChange();
@@ -472,14 +474,20 @@
                                              report.feedback_time);
   bandwidth_estimation_->IncomingPacketFeedbackVector(report);
 
+  if (network_estimator_)
+    network_estimator_->OnTransportPacketsFeedback(report);
+
   NetworkControlUpdate update;
   bool recovered_from_overuse = false;
   bool backoff_in_alr = false;
 
   DelayBasedBwe::Result result;
+  absl::optional<NetworkStateEstimate> network_estimate =
+      network_estimator_ ? network_estimator_->GetCurrentEstimate()
+                         : absl::nullopt;
   result = delay_based_bwe_->IncomingPacketFeedbackVector(
       received_feedback_vector, acknowledged_bitrate, probe_bitrate,
-      alr_start_time.has_value(), report.feedback_time);
+      network_estimate, alr_start_time.has_value(), report.feedback_time);
 
   if (result.updated) {
     if (result.probe) {
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 c4e8409..de1ea4f 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
@@ -37,15 +37,16 @@
 #include "rtc_base/experiments/rate_control_settings.h"
 
 namespace webrtc {
-
+struct GoogCcConfig {
+  std::unique_ptr<NetworkStateEstimator> network_state_estimator = nullptr;
+  std::unique_ptr<NetworkStatePredictor> network_state_predictor = nullptr;
+  bool feedback_only = false;
+};
 
 class GoogCcNetworkController : public NetworkControllerInterface {
  public:
-  GoogCcNetworkController(
-      RtcEventLog* event_log,
-      NetworkControllerConfig config,
-      bool feedback_only,
-      std::unique_ptr<NetworkStatePredictor> network_state_predictor);
+  GoogCcNetworkController(NetworkControllerConfig config,
+                          GoogCcConfig goog_cc_config);
   ~GoogCcNetworkController() override;
 
   // NetworkControllerInterface
@@ -91,6 +92,8 @@
   std::unique_ptr<SendSideBandwidthEstimation> bandwidth_estimation_;
   std::unique_ptr<AlrDetector> alr_detector_;
   std::unique_ptr<ProbeBitrateEstimator> probe_bitrate_estimator_;
+  std::unique_ptr<NetworkStateEstimator> network_estimator_;
+  std::unique_ptr<NetworkStatePredictor> network_state_predictor_;
   std::unique_ptr<DelayBasedBwe> delay_based_bwe_;
   std::unique_ptr<AcknowledgedBitrateEstimator> acknowledged_bitrate_estimator_;
 
@@ -124,7 +127,6 @@
 
   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 1e53d48..8f7b4f1 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
@@ -107,7 +107,7 @@
 class GoogCcNetworkControllerTest : public ::testing::Test {
  protected:
   GoogCcNetworkControllerTest()
-      : current_time_(Timestamp::ms(123456)), factory_(&event_log_, nullptr) {}
+      : current_time_(Timestamp::ms(123456)), factory_(&event_log_) {}
   ~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 51ff387..aba3cec 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, nullptr), printer_(printer) {}
+    : GoogCcNetworkControllerFactory(event_log), printer_(printer) {}
 
 std::unique_ptr<NetworkControllerInterface> GoogCcDebugFactory::Create(
     NetworkControllerConfig config) {
diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc
index cf5b7a2..1fbc63d 100644
--- a/modules/congestion_controller/send_side_congestion_controller.cc
+++ b/modules/congestion_controller/send_side_congestion_controller.cc
@@ -410,7 +410,8 @@
     result = delay_based_bwe_->IncomingPacketFeedbackVector(
         feedback_vector, acknowledged_bitrate_estimator_->bitrate(),
         probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
-        currently_in_alr, Timestamp::ms(clock_->TimeInMilliseconds()));
+        absl::nullopt, currently_in_alr,
+        Timestamp::ms(clock_->TimeInMilliseconds()));
   }
   if (result.updated) {
     bitrate_controller_->OnDelayBasedBweResult(result);
diff --git a/modules/remote_bitrate_estimator/BUILD.gn b/modules/remote_bitrate_estimator/BUILD.gn
index 3094e8c..7ce7cba 100644
--- a/modules/remote_bitrate_estimator/BUILD.gn
+++ b/modules/remote_bitrate_estimator/BUILD.gn
@@ -43,6 +43,7 @@
     "../..:webrtc_common",
     "../../api:network_state_predictor_api",
     "../../api:rtp_headers",
+    "../../api/transport:network_control",
     "../../api/units:data_rate",
     "../../api/units:timestamp",
     "../../modules:module_api",
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.cc b/modules/remote_bitrate_estimator/aimd_rate_control.cc
index 16b6ac7..688b3b8 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -17,6 +17,7 @@
 #include <cstdio>
 #include <string>
 
+#include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "modules/remote_bitrate_estimator/include/bwe_defines.h"
 #include "modules/remote_bitrate_estimator/overuse_detector.h"
@@ -71,7 +72,10 @@
       smoothing_experiment_(
           webrtc::field_trial::IsEnabled("WebRTC-Audio-BandwidthSmoothing")),
       initial_backoff_interval_("initial_backoff_interval"),
-      low_throughput_threshold_("low_throughput", DataRate::Zero()) {
+      low_throughput_threshold_("low_throughput", DataRate::Zero()),
+      capacity_deviation_ratio_threshold_("cap_thr", 0.2),
+      cross_traffic_factor_("cross", 1.0),
+      capacity_limit_deviation_factor_("cap_lim", 1) {
   // E.g
   // WebRTC-BweAimdRateControlConfig/initial_backoff_interval:100ms,
   // low_throughput:50kbps/
@@ -82,6 +86,10 @@
                      << " " << ToString(*initial_backoff_interval_) << ".";
   }
   RTC_LOG(LS_INFO) << "Using aimd rate control with back off factor " << beta_;
+  ParseFieldTrial(
+      {&capacity_deviation_ratio_threshold_, &cross_traffic_factor_,
+       &capacity_limit_deviation_factor_},
+      field_trial::FindFullName("WebRTC-Bwe-AimdRateControl-NetworkState"));
 }
 
 AimdRateControl::~AimdRateControl() {}
@@ -186,6 +194,11 @@
   }
 }
 
+void AimdRateControl::SetNetworkStateEstimate(
+    const absl::optional<NetworkStateEstimate>& estimate) {
+  network_estimate_ = estimate;
+}
+
 double AimdRateControl::GetNearMaxIncreaseRateBpsPerSecond() const {
   RTC_DCHECK(!current_bitrate_.IsZero());
   const TimeDelta kFrameInterval = TimeDelta::seconds(1) / 30;
@@ -263,6 +276,21 @@
       break;
 
     case kRcDecrease:
+      if (network_estimate_ && capacity_deviation_ratio_threshold_) {
+        // If we have a low variance network estimate, we use it over the
+        // acknowledged rate to avoid dropping the bitrate too far. This avoids
+        // overcompensating when the send rate is lower than the capacity.
+        double deviation_ratio = network_estimate_->link_capacity_std_dev /
+                                 network_estimate_->link_capacity;
+        if (deviation_ratio < *capacity_deviation_ratio_threshold_) {
+          double available_ratio =
+              std::max(0.0, 1.0 - network_estimate_->cross_traffic_ratio *
+                                      cross_traffic_factor_);
+          DataRate available_rate =
+              network_estimate_->link_capacity * available_ratio;
+          estimated_throughput = std::max(available_rate, estimated_throughput);
+        }
+      }
       if (estimated_throughput > low_throughput_threshold_) {
         // Set bit rate to something slightly lower than the measured throughput
         // to get rid of any self-induced delay.
@@ -323,6 +351,12 @@
   if (new_bitrate > current_bitrate_ && new_bitrate > max_bitrate) {
     new_bitrate = std::max(current_bitrate_, max_bitrate);
   }
+  if (network_estimate_ && capacity_limit_deviation_factor_) {
+    DataRate upper_bound = network_estimate_->link_capacity +
+                           network_estimate_->link_capacity_std_dev *
+                               capacity_limit_deviation_factor_.Value();
+    new_bitrate = std::min(new_bitrate, upper_bound);
+  }
   new_bitrate = std::max(new_bitrate, min_configured_bitrate_);
   return new_bitrate;
 }
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.h b/modules/remote_bitrate_estimator/aimd_rate_control.h
index 4d7bc7e..dfefc48 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -14,6 +14,7 @@
 #include <stdint.h>
 
 #include "absl/types/optional.h"
+#include "api/transport/network_types.h"
 #include "api/units/data_rate.h"
 #include "api/units/timestamp.h"
 #include "modules/congestion_controller/goog_cc/link_capacity_estimator.h"
@@ -52,6 +53,8 @@
   void SetRtt(TimeDelta rtt);
   DataRate Update(const RateControlInput* input, Timestamp at_time);
   void SetEstimate(DataRate bitrate, Timestamp at_time);
+  void SetNetworkStateEstimate(
+      const absl::optional<NetworkStateEstimate>& estimate);
 
   // Returns the increase rate when used bandwidth is near the link capacity.
   double GetNearMaxIncreaseRateBpsPerSecond() const;
@@ -87,6 +90,7 @@
   DataRate current_bitrate_;
   DataRate latest_estimated_throughput_;
   LinkCapacityEstimator link_capacity_;
+  absl::optional<NetworkStateEstimate> network_estimate_;
   RateControlState rate_control_state_;
   Timestamp time_last_bitrate_change_;
   Timestamp time_last_bitrate_decrease_;
@@ -99,6 +103,9 @@
   absl::optional<DataRate> last_decrease_;
   FieldTrialOptional<TimeDelta> initial_backoff_interval_;
   FieldTrialParameter<DataRate> low_throughput_threshold_;
+  FieldTrialOptional<double> capacity_deviation_ratio_threshold_;
+  FieldTrialParameter<double> cross_traffic_factor_;
+  FieldTrialOptional<double> capacity_limit_deviation_factor_;
 };
 }  // namespace webrtc
 
diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/modules/remote_bitrate_estimator/test/estimators/send_side.cc
index c4b81c7..bd701cf 100644
--- a/modules/remote_bitrate_estimator/test/estimators/send_side.cc
+++ b/modules/remote_bitrate_estimator/test/estimators/send_side.cc
@@ -92,8 +92,8 @@
   }
   DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector(
       packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate(),
-      probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), false,
-      Timestamp::ms(clock_->TimeInMilliseconds()));
+      probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
+      absl::nullopt, false, Timestamp::ms(clock_->TimeInMilliseconds()));
   if (result.updated)
     bitrate_controller_->OnDelayBasedBweResult(result);