Don't reset RTT Backoff timeout on route change.

Bug: webrtc:9718
Change-Id: I536733b33c40838cdfc473988581147bec6a358a
Reviewed-on: https://webrtc-review.googlesource.com/c/109927
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25638}
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation.cc b/modules/bitrate_controller/send_side_bandwidth_estimation.cc
index ce7c510..7dfee62 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation.cc
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation.cc
@@ -104,21 +104,43 @@
 }
 }  // namespace
 
-RttBasedBackoffConfig::RttBasedBackoffConfig()
-    : rtt_limit("limit", TimeDelta::PlusInfinity()),
-      drop_fraction("fraction", 0.5),
-      drop_interval("interval", TimeDelta::ms(300)) {
-  std::string trial_string =
-      field_trial::FindFullName("WebRTC-Bwe-MaxRttLimit");
-  ParseFieldTrial({&rtt_limit, &drop_fraction, &drop_interval}, trial_string);
+RttBasedBackoff::RttBasedBackoff()
+    : rtt_limit_("limit", TimeDelta::PlusInfinity()),
+      drop_fraction_("fraction", 0.5),
+      drop_interval_("interval", TimeDelta::ms(300)),
+      persist_on_route_change_("persist"),
+      // By initializing this to plus infinity, we make sure that we never
+      // trigger rtt backoff unless packet feedback is enabled.
+      last_propagation_rtt_update_(Timestamp::PlusInfinity()),
+      last_propagation_rtt_(TimeDelta::Zero()) {
+  ParseFieldTrial({&rtt_limit_, &drop_fraction_, &drop_interval_,
+                   &persist_on_route_change_},
+                  field_trial::FindFullName("WebRTC-Bwe-MaxRttLimit"));
 }
-RttBasedBackoffConfig::RttBasedBackoffConfig(const RttBasedBackoffConfig&) =
-    default;
-RttBasedBackoffConfig::~RttBasedBackoffConfig() = default;
+
+void RttBasedBackoff::OnRouteChange() {
+  if (!persist_on_route_change_) {
+    last_propagation_rtt_update_ = Timestamp::PlusInfinity();
+    last_propagation_rtt_ = TimeDelta::Zero();
+  }
+}
+
+void RttBasedBackoff::UpdatePropagationRtt(Timestamp at_time,
+                                           TimeDelta propagation_rtt) {
+  last_propagation_rtt_update_ = at_time;
+  last_propagation_rtt_ = propagation_rtt;
+}
+
+TimeDelta RttBasedBackoff::RttLowerBound(Timestamp at_time) const {
+  // TODO(srte): Use time since last unacknowledged packet for this.
+  TimeDelta time_since_rtt = at_time - last_propagation_rtt_update_;
+  return time_since_rtt + last_propagation_rtt_;
+}
+
+RttBasedBackoff::~RttBasedBackoff() = default;
 
 SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log)
-    : rtt_backoff_config_(RttBasedBackoffConfig()),
-      lost_packets_since_last_loss_update_(0),
+    : lost_packets_since_last_loss_update_(0),
       expected_packets_since_last_loss_update_(0),
       current_bitrate_(DataRate::Zero()),
       min_bitrate_configured_(
@@ -132,10 +154,6 @@
       last_fraction_loss_(0),
       last_logged_fraction_loss_(0),
       last_round_trip_time_(TimeDelta::Zero()),
-      // By initializing this to plus infinity, we make sure that we never
-      // trigger rtt backoff unless packet feedback is enabled.
-      last_propagation_rtt_update_(Timestamp::PlusInfinity()),
-      last_propagation_rtt_(TimeDelta::Zero()),
       bwe_incoming_(DataRate::Zero()),
       delay_based_bitrate_(DataRate::Zero()),
       time_last_decrease_(Timestamp::MinusInfinity()),
@@ -168,6 +186,34 @@
 
 SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {}
 
+void SendSideBandwidthEstimation::OnRouteChange() {
+  lost_packets_since_last_loss_update_ = 0;
+  expected_packets_since_last_loss_update_ = 0;
+  current_bitrate_ = DataRate::Zero();
+  min_bitrate_configured_ =
+      DataRate::bps(congestion_controller::GetMinBitrateBps());
+  max_bitrate_configured_ = kDefaultMaxBitrate;
+  last_low_bitrate_log_ = Timestamp::MinusInfinity();
+  has_decreased_since_last_fraction_loss_ = false;
+  last_loss_feedback_ = Timestamp::MinusInfinity();
+  last_loss_packet_report_ = Timestamp::MinusInfinity();
+  last_timeout_ = Timestamp::MinusInfinity();
+  last_fraction_loss_ = 0;
+  last_logged_fraction_loss_ = 0;
+  last_round_trip_time_ = TimeDelta::Zero();
+  bwe_incoming_ = DataRate::Zero();
+  delay_based_bitrate_ = DataRate::Zero();
+  time_last_decrease_ = Timestamp::MinusInfinity();
+  first_report_time_ = Timestamp::MinusInfinity();
+  initially_lost_packets_ = 0;
+  bitrate_at_2_seconds_ = DataRate::Zero();
+  uma_update_state_ = kNoUpdate;
+  uma_rtt_state_ = kNoUpdate;
+  last_rtc_event_log_ = Timestamp::MinusInfinity();
+
+  rtt_backoff_.OnRouteChange();
+}
+
 void SendSideBandwidthEstimation::SetBitrates(
     absl::optional<DataRate> send_bitrate,
     DataRate min_bitrate,
@@ -312,11 +358,10 @@
 
 void SendSideBandwidthEstimation::UpdateEstimate(Timestamp at_time) {
   DataRate new_bitrate = current_bitrate_;
-  TimeDelta time_since_rtt = at_time - last_propagation_rtt_update_;
-  if (time_since_rtt + last_propagation_rtt_ > rtt_backoff_config_.rtt_limit) {
-    if (at_time - time_last_decrease_ >= rtt_backoff_config_.drop_interval) {
+  if (rtt_backoff_.RttLowerBound(at_time) > rtt_backoff_.rtt_limit_) {
+    if (at_time - time_last_decrease_ >= rtt_backoff_.drop_interval_) {
       time_last_decrease_ = at_time;
-      new_bitrate = current_bitrate_ * rtt_backoff_config_.drop_fraction;
+      new_bitrate = current_bitrate_ * rtt_backoff_.drop_fraction_;
     }
     CapBitrateToThresholds(at_time, new_bitrate);
     return;
@@ -412,8 +457,7 @@
 void SendSideBandwidthEstimation::UpdatePropagationRtt(
     Timestamp at_time,
     TimeDelta propagation_rtt) {
-  last_propagation_rtt_update_ = at_time;
-  last_propagation_rtt_ = propagation_rtt;
+  rtt_backoff_.UpdatePropagationRtt(at_time, propagation_rtt);
 }
 
 bool SendSideBandwidthEstimation::IsInStartPhase(Timestamp at_time) const {
diff --git a/modules/bitrate_controller/send_side_bandwidth_estimation.h b/modules/bitrate_controller/send_side_bandwidth_estimation.h
index 9ee43bb..83efe92 100644
--- a/modules/bitrate_controller/send_side_bandwidth_estimation.h
+++ b/modules/bitrate_controller/send_side_bandwidth_estimation.h
@@ -29,14 +29,22 @@
 
 class RtcEventLog;
 
-struct RttBasedBackoffConfig {
-  RttBasedBackoffConfig();
-  RttBasedBackoffConfig(const RttBasedBackoffConfig&);
-  RttBasedBackoffConfig& operator=(const RttBasedBackoffConfig&) = default;
-  ~RttBasedBackoffConfig();
-  FieldTrialParameter<TimeDelta> rtt_limit;
-  FieldTrialParameter<double> drop_fraction;
-  FieldTrialParameter<TimeDelta> drop_interval;
+class RttBasedBackoff {
+ public:
+  RttBasedBackoff();
+  ~RttBasedBackoff();
+  void OnRouteChange();
+  void UpdatePropagationRtt(Timestamp at_time, TimeDelta propagation_rtt);
+  TimeDelta RttLowerBound(Timestamp at_time) const;
+
+  FieldTrialParameter<TimeDelta> rtt_limit_;
+  FieldTrialParameter<double> drop_fraction_;
+  FieldTrialParameter<TimeDelta> drop_interval_;
+  FieldTrialFlag persist_on_route_change_;
+
+ public:
+  Timestamp last_propagation_rtt_update_;
+  TimeDelta last_propagation_rtt_;
 };
 
 class SendSideBandwidthEstimation {
@@ -45,12 +53,13 @@
   explicit SendSideBandwidthEstimation(RtcEventLog* event_log);
   ~SendSideBandwidthEstimation();
 
+  void OnRouteChange();
   void CurrentEstimate(int* bitrate, uint8_t* loss, int64_t* rtt) const;
 
   // Call periodically to update estimate.
   void UpdateEstimate(Timestamp at_time);
   void OnSentPacket(SentPacket sent_packet);
-  void UpdatePropagationRtt(Timestamp at_time, TimeDelta feedback_rtt);
+  void UpdatePropagationRtt(Timestamp at_time, TimeDelta propagation_rtt);
 
   // Call when we receive a RTCP message with TMMBR or REMB.
   void UpdateReceiverEstimate(Timestamp at_time, DataRate bandwidth);
@@ -96,7 +105,7 @@
   // set |current_bitrate_| to the capped value and updates the event log.
   void CapBitrateToThresholds(Timestamp at_time, DataRate bitrate);
 
-  RttBasedBackoffConfig rtt_backoff_config_;
+  RttBasedBackoff rtt_backoff_;
 
   std::deque<std::pair<Timestamp, DataRate> > min_bitrate_history_;
 
@@ -117,9 +126,6 @@
   uint8_t last_logged_fraction_loss_;
   TimeDelta last_round_trip_time_;
 
-  Timestamp last_propagation_rtt_update_;
-  TimeDelta last_propagation_rtt_;
-
   DataRate bwe_incoming_;
   DataRate delay_based_bitrate_;
   Timestamp time_last_decrease_;
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 0088018..3b06ed6 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -213,8 +213,7 @@
   delay_based_bwe_.reset(new DelayBasedBwe(event_log_));
   delay_based_bwe_->SetStartBitrate(start_bitrate_bps);
   delay_based_bwe_->SetMinBitrate(min_bitrate_bps);
-  bandwidth_estimation_ =
-      absl::make_unique<SendSideBandwidthEstimation>(event_log_);
+  bandwidth_estimation_->OnRouteChange();
   bandwidth_estimation_->SetBitrates(
       msg.constraints.starting_rate, DataRate::bps(min_bitrate_bps),
       msg.constraints.max_data_rate.value_or(DataRate::Infinity()),
@@ -428,6 +427,7 @@
     const size_t kMaxFeedbackRttWindow = 32;
     if (feedback_max_rtts_.size() > kMaxFeedbackRttWindow)
       feedback_max_rtts_.pop_front();
+    // TODO(srte): Use time since last unacknowledged packet.
     bandwidth_estimation_->UpdatePropagationRtt(report.feedback_time,
                                                 min_propagation_rtt);
   }