Makes BBR congestion window more similar to QUIC.

This CL makes the congestion window parameters, initial window, minimum
window, and maximum window more similar to the values for the
implementation in QUIC.

It also contains minor behavioral changes to better match the Quic
implementation.

Bug: webrtc:8415
Change-Id: I26f4b35b6cbb00178ea47a4aee871b1b700c153b
Reviewed-on: https://webrtc-review.googlesource.com/83587
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23630}
diff --git a/modules/congestion_controller/bbr/bbr_network_controller.cc b/modules/congestion_controller/bbr/bbr_network_controller.cc
index 03491e7..4bbcfac 100644
--- a/modules/congestion_controller/bbr/bbr_network_controller.cc
+++ b/modules/congestion_controller/bbr/bbr_network_controller.cc
@@ -42,9 +42,6 @@
 const DataSize kDefaultTCPMSS = DataSize::bytes(1460);
 // Constants based on TCP defaults.
 const DataSize kMaxSegmentSize = kDefaultTCPMSS;
-// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
-// Does not inflate the pacing rate.
-const DataSize kMinimumCongestionWindow = DataSize::bytes(1000);
 
 // The gain used for the slow start, equal to 2/ln(2).
 const double kHighGain = 2.885f;
@@ -72,16 +69,14 @@
 // we don't need to enter PROBE_RTT.
 const double kSimilarMinRttThreshold = 1.125;
 
-constexpr int64_t kInitialRttMs = 200;
 constexpr int64_t kInitialBandwidthKbps = 300;
 
-constexpr int64_t kMaxRttMs = 1000;
-constexpr int64_t kMaxBandwidthKbps = 5000;
+const int64_t kInitialCongestionWindowPackets = 32;
+// The minimum CWND to ensure delayed acks don't reduce bandwidth measurements.
+// Does not inflate the pacing rate.
+const int64_t kDefaultMinCongestionWindowPackets = 4;
+const int64_t kDefaultMaxCongestionWindowPackets = 2000;
 
-constexpr int64_t kInitialCongestionWindowBytes =
-    (kInitialRttMs * kInitialBandwidthKbps) / 8;
-constexpr int64_t kDefaultMaxCongestionWindowBytes =
-    (kMaxRttMs * kMaxBandwidthKbps) / 8;
 }  // namespace
 
 BbrNetworkController::BbrControllerConfig
@@ -179,10 +174,13 @@
       min_rtt_(TimeDelta::Zero()),
       last_rtt_(TimeDelta::Zero()),
       min_rtt_timestamp_(Timestamp::ms(0)),
-      congestion_window_(DataSize::bytes(kInitialCongestionWindowBytes)),
-      initial_congestion_window_(
-          DataSize::bytes(kInitialCongestionWindowBytes)),
-      max_congestion_window_(DataSize::bytes(kDefaultMaxCongestionWindowBytes)),
+      congestion_window_(kInitialCongestionWindowPackets * kDefaultTCPMSS),
+      initial_congestion_window_(kInitialCongestionWindowPackets *
+                                 kDefaultTCPMSS),
+      min_congestion_window_(kDefaultMinCongestionWindowPackets *
+                             kDefaultTCPMSS),
+      max_congestion_window_(kDefaultMaxCongestionWindowPackets *
+                             kDefaultTCPMSS),
       pacing_rate_(DataRate::Zero()),
       pacing_gain_(1),
       congestion_window_gain_constant_(kProbeBWCongestionWindowGain),
@@ -192,6 +190,7 @@
       is_at_full_bandwidth_(false),
       rounds_without_bandwidth_gain_(0),
       bandwidth_at_last_round_(DataRate::Zero()),
+      exiting_quiescence_(false),
       exit_probe_rtt_at_(),
       probe_rtt_round_passed_(false),
       last_sample_is_app_limited_(false),
@@ -206,12 +205,6 @@
     default_bandwidth_ = config.starting_bandwidth;
   constraints_ = config.constraints;
   Reset();
-  if (config_.num_startup_rtts > 0) {
-    EnterStartupMode();
-  } else {
-    is_at_full_bandwidth_ = true;
-    EnterProbeBandwidthMode(constraints_->at_time);
-  }
 }
 
 BbrNetworkController::~BbrNetworkController() {}
@@ -219,8 +212,13 @@
 void BbrNetworkController::Reset() {
   round_trip_count_ = 0;
   rounds_without_bandwidth_gain_ = 0;
-  is_at_full_bandwidth_ = false;
-  EnterStartupMode();
+  if (config_.num_startup_rtts > 0) {
+    is_at_full_bandwidth_ = false;
+    EnterStartupMode();
+  } else {
+    is_at_full_bandwidth_ = true;
+    EnterProbeBandwidthMode(constraints_->at_time);
+  }
 }
 
 NetworkControlUpdate BbrNetworkController::CreateRateUpdate(Timestamp at_time) {
@@ -323,6 +321,10 @@
 NetworkControlUpdate BbrNetworkController::OnSentPacket(SentPacket msg) {
   last_sent_packet_ = msg.sequence_number;
 
+  if (msg.data_in_flight.IsZero() && sampler_->is_app_limited()) {
+    exiting_quiescence_ = true;
+  }
+
   if (!aggregation_epoch_start_time_) {
     aggregation_epoch_start_time_ = msg.send_time;
   }
@@ -493,14 +495,14 @@
     congestion_window = gain * initial_congestion_window_;
   }
 
-  return std::max(congestion_window, kMinimumCongestionWindow);
+  return std::max(congestion_window, min_congestion_window_);
 }
 
 DataSize BbrNetworkController::ProbeRttCongestionWindow() const {
   if (config_.probe_rtt_based_on_bdp) {
     return GetTargetCongestionWindow(config_.probe_rtt_congestion_window_gain);
   }
-  return kMinimumCongestionWindow;
+  return min_congestion_window_;
 }
 
 void BbrNetworkController::EnterStartupMode() {
@@ -689,7 +691,7 @@
     const TransportPacketsFeedback& msg,
     bool is_round_start,
     bool min_rtt_expired) {
-  if (min_rtt_expired && mode_ != PROBE_RTT) {
+  if (min_rtt_expired && !exiting_quiescence_ && mode_ != PROBE_RTT) {
     mode_ = PROBE_RTT;
     pacing_gain_ = 1;
     // Do not decide on the time to exit PROBE_RTT until the |bytes_in_flight|
@@ -723,6 +725,8 @@
       }
     }
   }
+
+  exiting_quiescence_ = false;
 }
 
 void BbrNetworkController::UpdateRecoveryState(int64_t last_acked_packet,
@@ -758,8 +762,8 @@
       RTC_FALLTHROUGH();
     case GROWTH:
       // Exit recovery if appropriate.
-      if (!has_losses && end_recovery_at_ &&
-          last_acked_packet > *end_recovery_at_) {
+      if (!has_losses &&
+          (!end_recovery_at_ || last_acked_packet > *end_recovery_at_)) {
         recovery_state_ = NOT_IN_RECOVERY;
       }
 
@@ -865,7 +869,7 @@
   }
 
   // Enforce the limits on the congestion window.
-  congestion_window_ = std::max(congestion_window_, kMinimumCongestionWindow);
+  congestion_window_ = std::max(congestion_window_, min_congestion_window_);
   congestion_window_ = std::min(congestion_window_, max_congestion_window_);
 }
 
@@ -884,7 +888,7 @@
   // Set up the initial recovery window.
   if (recovery_window_.IsZero()) {
     recovery_window_ = bytes_in_flight + bytes_acked;
-    recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
+    recovery_window_ = std::max(min_congestion_window_, recovery_window_);
     return;
   }
 
@@ -906,7 +910,7 @@
   // Sanity checks.  Ensure that we always allow to send at least
   // |bytes_acked| in response.
   recovery_window_ = std::max(recovery_window_, bytes_in_flight + bytes_acked);
-  recovery_window_ = std::max(kMinimumCongestionWindow, recovery_window_);
+  recovery_window_ = std::max(min_congestion_window_, recovery_window_);
 }
 
 void BbrNetworkController::OnApplicationLimited(DataSize bytes_in_flight) {
diff --git a/modules/congestion_controller/bbr/bbr_network_controller.h b/modules/congestion_controller/bbr/bbr_network_controller.h
index 20cda56..20d12c8 100644
--- a/modules/congestion_controller/bbr/bbr_network_controller.h
+++ b/modules/congestion_controller/bbr/bbr_network_controller.h
@@ -32,7 +32,6 @@
 namespace webrtc {
 namespace bbr {
 
-typedef int64_t BbrPacketCount;
 typedef int64_t BbrRoundTripCount;
 
 // BbrSender implements BBR congestion control algorithm.  BBR aims to estimate
@@ -269,6 +268,9 @@
   // The initial value of the |congestion_window_|.
   DataSize initial_congestion_window_;
 
+  // The smallest value the |congestion_window_| can achieve.
+  DataSize min_congestion_window_;
+
   // The largest value the |congestion_window_| can achieve.
   DataSize max_congestion_window_;
 
@@ -300,6 +302,9 @@
   // The bandwidth compared to which the increase is measured.
   DataRate bandwidth_at_last_round_;
 
+  // Set to true upon exiting quiescence.
+  bool exiting_quiescence_;
+
   // Time at which PROBE_RTT has to be exited.  Setting it to zero indicates
   // that the time is yet unknown as the number of packets in flight has not
   // reached the required value.
@@ -314,7 +319,7 @@
   // Current state of recovery.
   RecoveryState recovery_state_;
   // Receiving acknowledgement of a packet after |end_recovery_at_| will cause
-  // BBR to exit the recovery mode.  An unset value indicates at least one
+  // BBR to exit the recovery mode.  A set value indicates at least one
   // loss has been detected, so it must not be reset.
   rtc::Optional<int64_t> end_recovery_at_;
   // A window used to limit the number of bytes in flight during loss recovery.