From d48a18fbbbd74284766b9a1b41ee450b584867bc Mon Sep 17 00:00:00 2001 From: Per K Date: Thu, 2 May 2024 13:51:12 +0000 Subject: [PATCH] Limit pacingfactor by upper link capacity estimate. If pacing rate, (current loss based bwe * pacing factor) is larger than the current upper link capacity estimate, reduce pacing factor to max of current bwe and upper link capacity. Bug: webrtc:42220543 Change-Id: I5246da1f38530f8d411e7314adaa8651fc848f48 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/349601 Reviewed-by: Diep Bui Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#42210} --- experiments/field_trials.py | 3 ++ .../goog_cc/goog_cc_network_control.cc | 11 +++++++ .../goog_cc/goog_cc_network_control.h | 1 + .../goog_cc_network_control_unittest.cc | 31 +++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/experiments/field_trials.py b/experiments/field_trials.py index c23d523611..be070fa9a2 100755 --- a/experiments/field_trials.py +++ b/experiments/field_trials.py @@ -59,6 +59,9 @@ ACTIVE_FIELD_TRIALS: FrozenSet[FieldTrial] = frozenset([ FieldTrial('WebRTC-Av1-GetEncoderInfoOverride', 42225234, date(2024, 4, 1)), + FieldTrial('WebRTC-Bwe-LimitPacingFactorByUpperLinkCapacityEstimate', + 42220543, + date(2025, 1, 1)), FieldTrial('WebRTC-DataChannelMessageInterleaving', 41481008, date(2024, 10, 1)), 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 815520ace2..09ac8caef2 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -120,6 +120,9 @@ GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config, pace_at_max_of_bwe_and_lower_link_capacity_( IsEnabled(key_value_config_, "WebRTC-Bwe-PaceAtMaxOfBweAndLowerLinkCapacity")), + limit_pacingfactor_by_upper_link_capacity_estimate_( + IsEnabled(key_value_config_, + "WebRTC-Bwe-LimitPacingFactorByUpperLinkCapacityEstimate")), probe_controller_( new ProbeController(key_value_config_, config.event_log)), congestion_window_pushback_controller_( @@ -735,6 +738,14 @@ PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const { std::max(min_total_allocated_bitrate_, last_loss_based_target_rate_) * pacing_factor_; } + if (limit_pacingfactor_by_upper_link_capacity_estimate_ && estimate_ && + estimate_->link_capacity_upper.IsFinite() && + pacing_rate > estimate_->link_capacity_upper) { + pacing_rate = + std::max({estimate_->link_capacity_upper, min_total_allocated_bitrate_, + last_loss_based_target_rate_}); + } + DataRate padding_rate = (last_loss_base_state_ == LossBasedState::kIncreaseUsingPadding) ? std::max(max_padding_rate_, last_loss_based_target_rate_) 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 957cedbac6..2b4fb6e35c 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.h +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.h @@ -96,6 +96,7 @@ class GoogCcNetworkController : public NetworkControllerInterface { const bool limit_probes_lower_than_throughput_estimate_; const RateControlSettings rate_control_settings_; const bool pace_at_max_of_bwe_and_lower_link_capacity_; + const bool limit_pacingfactor_by_upper_link_capacity_estimate_; const std::unique_ptr probe_controller_; const std::unique_ptr 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 c97d34da22..c651f1376a 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 @@ -486,6 +486,37 @@ TEST(GoogCcNetworkControllerTest, PaceAtMaxOfLowerLinkCapacityAndBwe) { update.target_rate->target_rate.kbps() * kDefaultPacingRate); } +TEST(GoogCcNetworkControllerTest, LimitPacingFactorToUpperLinkCapacity) { + ScopedFieldTrials trial( + "WebRTC-Bwe-LimitPacingFactorByUpperLinkCapacityEstimate/Enabled/"); + NetworkControllerTestFixture fixture; + std::unique_ptr controller = + fixture.CreateController(); + Timestamp current_time = Timestamp::Millis(123); + NetworkControlUpdate update = controller->OnNetworkAvailability( + {.at_time = current_time, .network_available = true}); + update = controller->OnProcessInterval({.at_time = current_time}); + current_time += TimeDelta::Millis(100); + NetworkStateEstimate network_estimate = { + .link_capacity_upper = kInitialBitrate * kDefaultPacingRate / 2}; + update = controller->OnNetworkStateEstimate(network_estimate); + // OnNetworkStateEstimate does not trigger processing a new estimate. So add a + // dummy loss report to trigger a BWE update in the next process interval. + TransportLossReport loss_report; + loss_report.start_time = current_time; + loss_report.end_time = current_time; + loss_report.receive_time = current_time; + loss_report.packets_received_delta = 50; + loss_report.packets_lost_delta = 1; + update = controller->OnTransportLossReport(loss_report); + update = controller->OnProcessInterval({.at_time = current_time}); + ASSERT_TRUE(update.pacer_config); + ASSERT_TRUE(update.target_rate); + EXPECT_GE(update.target_rate->target_rate, kInitialBitrate); + EXPECT_EQ(update.pacer_config->data_rate(), + network_estimate.link_capacity_upper); +} + // Test congestion window pushback on network delay happens. TEST(GoogCcScenario, CongestionWindowPushbackOnNetworkDelay) { auto factory = CreateFeedbackOnlyFactory();