Reduce pacing buffer padding rate during pushback.

Bug: webrtc:10112
Change-Id: I2cd2d07bd5bcbff5b3808ee63eea251a52e45b79
Reviewed-on: https://webrtc-review.googlesource.com/c/113808
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Commit-Queue: Christoffer Rodbro <crodbro@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25968}
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 c99a6c9..6de143d 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc
@@ -150,6 +150,7 @@
           absl::make_unique<AcknowledgedBitrateEstimator>()),
       initial_config_(config),
       last_target_rate_(*config.constraints.starting_rate),
+      pushback_target_rate_(last_target_rate_),
       pacing_factor_(config.stream_based_config.pacing_factor.value_or(
           kDefaultPaceMultiplier)),
       min_pacing_rate_(config.stream_based_config.min_pacing_rate.value_or(
@@ -619,6 +620,7 @@
                                         pushback_rate);
       target_rate = DataRate::bps(pushback_rate);
     }
+    pushback_target_rate_ = target_rate;
 
     TargetTransferRate target_rate_msg;
     target_rate_msg.at_time = at_time;
@@ -642,7 +644,7 @@
 PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const {
   DataRate pacing_rate =
       std::max(min_pacing_rate_, last_target_rate_) * pacing_factor_;
-  DataRate padding_rate = std::min(max_padding_rate_, last_target_rate_);
+  DataRate padding_rate = std::min(max_padding_rate_, pushback_target_rate_);
   PacerConfig msg;
   msg.at_time = at_time;
   msg.time_window = TimeDelta::seconds(1);
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 057ed12..c635ab4 100644
--- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h
+++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h
@@ -95,6 +95,7 @@
   std::deque<int64_t> feedback_max_rtts_;
 
   DataRate last_target_rate_;
+  DataRate pushback_target_rate_;
 
   int32_t last_estimated_bitrate_bps_ = 0;
   uint8_t last_estimated_fraction_loss_ = 0;
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 79ded00..62be521 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
@@ -357,6 +357,43 @@
               20);
 }
 
+TEST_F(GoogCcNetworkControllerTest,
+       PaddingRateLimitedByCongestionWindowInTrial) {
+  ScopedFieldTrials trial(
+      "WebRTC-CongestionWindowPushback/Enabled/WebRTC-CwndExperiment/"
+      "Enabled-200/");
+
+  Scenario s("googcc_unit/padding_limited", false);
+  NetworkNodeConfig net_conf;
+  auto send_net = s.CreateSimulationNode([=](NetworkNodeConfig* c) {
+    c->simulation.bandwidth = DataRate::kbps(1000);
+    c->simulation.delay = TimeDelta::ms(100);
+    c->update_frequency = TimeDelta::ms(5);
+  });
+  auto ret_net = s.CreateSimulationNode([](NetworkNodeConfig* c) {
+    c->simulation.delay = TimeDelta::ms(100);
+    c->update_frequency = TimeDelta::ms(5);
+  });
+  SimulatedTimeClientConfig config;
+  config.transport.cc =
+      TransportControllerConfig::CongestionController::kGoogCc;
+  // Start high so bandwidth drop has max effect.
+  config.transport.rates.start_rate = DataRate::kbps(1000);
+  config.transport.rates.max_rate = DataRate::kbps(2000);
+  config.transport.rates.max_padding_rate = config.transport.rates.max_rate;
+  SimulatedTimeClient* client = s.CreateSimulatedTimeClient(
+      "send", config, {PacketStreamConfig()}, {send_net}, {ret_net});
+  // Run for a few seconds to allow the controller to stabilize.
+  s.RunFor(TimeDelta::seconds(10));
+
+  // Check that padding rate matches target rate.
+  EXPECT_NEAR(client->padding_rate().kbps(), client->target_rate_kbps(), 1);
+
+  // Check this is also the case when congestion window pushback kicks in.
+  send_net->PauseTransmissionUntil(s.Now() + TimeDelta::seconds(1));
+  EXPECT_NEAR(client->padding_rate().kbps(), client->target_rate_kbps(), 1);
+}
+
 TEST_F(GoogCcNetworkControllerTest, LimitsToMinRateIfRttIsHighInTrial) {
   // The field trial limits maximum RTT to 2 seconds, higher RTT means that the
   // controller backs off until it reaches the minimum configured bitrate. This
diff --git a/test/scenario/scenario_config.h b/test/scenario/scenario_config.h
index 7716b4e..cb538a7 100644
--- a/test/scenario/scenario_config.h
+++ b/test/scenario/scenario_config.h
@@ -44,6 +44,7 @@
     DataRate min_rate = DataRate::kbps(30);
     DataRate max_rate = DataRate::kbps(3000);
     DataRate start_rate = DataRate::kbps(300);
+    DataRate max_padding_rate = DataRate::Zero();
   } rates;
   enum CongestionController { kBbr, kGoogCc, kGoogCcFeedback } cc = kGoogCc;
   TimeDelta state_log_interval = TimeDelta::ms(100);
diff --git a/test/scenario/simulated_time.cc b/test/scenario/simulated_time.cc
index becd793..90ea518 100644
--- a/test/scenario/simulated_time.cc
+++ b/test/scenario/simulated_time.cc
@@ -264,6 +264,8 @@
   current_contraints_.max_data_rate = config.transport.rates.max_rate;
   NetworkControllerConfig initial_config;
   initial_config.constraints = current_contraints_;
+  initial_config.stream_based_config.max_padding_rate =
+      config.transport.rates.max_padding_rate;
   congestion_controller_ = network_controller_factory_.Create(initial_config);
   for (auto& stream_config : stream_configs)
     packet_streams_.emplace_back(new PacketStream(stream_config));
@@ -364,5 +366,9 @@
   return target_rate_.kbps<double>();
 }
 
+DataRate SimulatedTimeClient::padding_rate() const {
+  return sender_.pacer_config_.pad_rate();
+}
+
 }  // namespace test
 }  // namespace webrtc
diff --git a/test/scenario/simulated_time.h b/test/scenario/simulated_time.h
index 4d91c8f..da5e972 100644
--- a/test/scenario/simulated_time.h
+++ b/test/scenario/simulated_time.h
@@ -139,6 +139,7 @@
   TimeDelta GetNetworkControllerProcessInterval() const;
   double target_rate_kbps() const;
   DataRate link_capacity() const;
+  DataRate padding_rate() const;
 
   bool TryDeliverPacket(rtc::CopyOnWriteBuffer packet,
                         uint64_t receiver,