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,