Cap probing bitrate to max total allocated bitrate

Bug: webrtc:10070
Change-Id: I3ba2656dff08e9ff054e263d78dcacba1ff77dd1
Reviewed-on: https://webrtc-review.googlesource.com/c/112384
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25845}
diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc
index af967dc..4421b9e 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller.cc
@@ -78,12 +78,18 @@
 constexpr char kBweRapidRecoveryExperiment[] =
     "WebRTC-BweRapidRecoveryExperiment";
 
+// Never probe higher than configured by OnMaxTotalAllocatedBitrate().
+constexpr char kCappedProbingFieldTrialName[] = "WebRTC-BweCappedProbing";
+
 }  // namespace
 
-ProbeController::ProbeController() : enable_periodic_alr_probing_(false) {
+ProbeController::ProbeController()
+    : enable_periodic_alr_probing_(false),
+      in_rapid_recovery_experiment_(
+          webrtc::field_trial::IsEnabled(kBweRapidRecoveryExperiment)),
+      limit_probes_with_allocateable_rate_(
+          !webrtc::field_trial::IsDisabled(kCappedProbingFieldTrialName)) {
   Reset(0);
-  in_rapid_recovery_experiment_ = webrtc::field_trial::FindFullName(
-                                      kBweRapidRecoveryExperiment) == "Enabled";
 }
 
 ProbeController::~ProbeController() {}
@@ -141,8 +147,6 @@
 std::vector<ProbeClusterConfig> ProbeController::OnMaxTotalAllocatedBitrate(
     int64_t max_total_allocated_bitrate,
     int64_t at_time_ms) {
-  // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for
-  //                 ALR probing?
   if (state_ == State::kProbingComplete &&
       max_total_allocated_bitrate != max_total_allocated_bitrate_ &&
       estimated_bitrate_bps_ != 0 &&
@@ -330,6 +334,11 @@
     RTC_DCHECK_GT(bitrate, 0);
     int64_t max_probe_bitrate_bps =
         max_bitrate_bps_ > 0 ? max_bitrate_bps_ : kDefaultMaxProbingBitrateBps;
+    if (limit_probes_with_allocateable_rate_ &&
+        max_total_allocated_bitrate_ > 0) {
+      max_probe_bitrate_bps =
+          std::min(max_probe_bitrate_bps, max_total_allocated_bitrate_);
+    }
     if (bitrate > max_probe_bitrate_bps) {
       bitrate = max_probe_bitrate_bps;
       probe_further = false;
diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h
index 4ddd77f..0b1e685 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.h
+++ b/modules/congestion_controller/goog_cc/probe_controller.h
@@ -102,7 +102,8 @@
   int64_t bitrate_before_last_large_drop_bps_;
   int64_t max_total_allocated_bitrate_;
 
-  bool in_rapid_recovery_experiment_;
+  const bool in_rapid_recovery_experiment_;
+  const bool limit_probes_with_allocateable_rate_;
   // For WebRTC.BWE.MidCallProbing.* metric.
   bool mid_call_probing_waiting_for_result_;
   int64_t mid_call_probing_bitrate_bps_;
diff --git a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
index 184d112..b803cd4 100644
--- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
@@ -263,5 +263,40 @@
   EXPECT_EQ(probes.size(), 0u);
 }
 
+TEST_F(ProbeControllerTest, TestAllocatedBitrateCap) {
+  const int64_t kMbpsMultiplier = 1000000;
+  auto probes = probe_controller_->SetBitrates(
+      kMinBitrateBps, 10 * kMbpsMultiplier, 100 * kMbpsMultiplier, NowMs());
+
+  // Configure ALR for periodic probing.
+  probe_controller_->EnablePeriodicAlrProbing(true);
+  int64_t alr_start_time = clock_.TimeInMilliseconds();
+  probe_controller_->SetAlrStartTimeMs(alr_start_time);
+
+  // Verify that probe bitrate is capped at the specified max bitrate.
+  probes =
+      probe_controller_->SetEstimatedBitrate(60 * kMbpsMultiplier, NowMs());
+  EXPECT_EQ(probes[0].target_data_rate.bps(), 100 * kMbpsMultiplier);
+
+  // Set a max allocated bitrate below the current max.
+  probes = probe_controller_->OnMaxTotalAllocatedBitrate(1 * kMbpsMultiplier,
+                                                         NowMs());
+  EXPECT_TRUE(probes.empty());  // No probe since lower than current max.
+
+  // Other probes, such as ALR, such also be capped at the same limit.
+  clock_.AdvanceTimeMilliseconds(5000);
+  probes = probe_controller_->Process(NowMs());
+  EXPECT_EQ(probes[0].target_data_rate.bps(), 1 * kMbpsMultiplier);
+
+  // Advance time and configure remove allocated bitrate limit.
+  EXPECT_TRUE(
+      probe_controller_->OnMaxTotalAllocatedBitrate(0, NowMs()).empty());
+
+  // New ALR probes use previous limits.
+  clock_.AdvanceTimeMilliseconds(5000);
+  probes = probe_controller_->Process(NowMs());
+  EXPECT_EQ(probes[0].target_data_rate.bps(), 100 * kMbpsMultiplier);
+}
+
 }  // namespace test
 }  // namespace webrtc