diff options
Diffstat (limited to 'third_party/libwebrtc/modules/congestion_controller')
9 files changed, 115 insertions, 16 deletions
diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index 94645dcc4a..d8a0ce9d64 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -720,7 +720,8 @@ PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const { // Pacing rate is based on target rate before congestion window pushback, // because we don't want to build queues in the pacer when pushback occurs. DataRate pacing_rate = DataRate::Zero(); - if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_) { + if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_ && + !bandwidth_estimation_->PaceAtLossBasedEstimate()) { pacing_rate = std::max({min_total_allocated_bitrate_, estimate_->link_capacity_lower, last_loss_based_target_rate_}) * diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc index 8e1a3c4698..2f47ee0f18 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc @@ -499,6 +499,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( FieldTrialParameter<TimeDelta> padding_duration("PaddingDuration", TimeDelta::Zero()); FieldTrialParameter<bool> bound_best_candidate("BoundBestCandidate", false); + FieldTrialParameter<bool> pace_at_loss_based_estimate( + "PaceAtLossBasedEstimate", false); if (key_value_config) { ParseFieldTrial({&enabled, &bandwidth_rampup_upper_bound_factor, @@ -538,7 +540,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( &hold_duration_factor, &use_byte_loss_rate, &padding_duration, - &bound_best_candidate}, + &bound_best_candidate, + &pace_at_loss_based_estimate}, key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2")); } @@ -604,6 +607,7 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( config->use_byte_loss_rate = use_byte_loss_rate.Get(); config->padding_duration = padding_duration.Get(); config->bound_best_candidate = bound_best_candidate.Get(); + config->pace_at_loss_based_estimate = pace_at_loss_based_estimate.Get(); return config; } @@ -1199,4 +1203,9 @@ bool LossBasedBweV2::CanKeepIncreasingState(DataRate estimate) const { last_padding_info_.padding_rate < estimate; } +bool LossBasedBweV2::PaceAtLossBasedEstimate() const { + return config_->pace_at_loss_based_estimate && + loss_based_result_.state != LossBasedState::kDelayBasedEstimate; +} + } // namespace webrtc diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h index 9afbb11f1f..34c96c66d9 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h @@ -74,6 +74,7 @@ class LossBasedBweV2 { rtc::ArrayView<const PacketResult> packet_results, DataRate delay_based_estimate, bool in_alr); + bool PaceAtLossBasedEstimate() const; // For unit testing only. void SetBandwidthEstimate(DataRate bandwidth_estimate); @@ -124,6 +125,7 @@ class LossBasedBweV2 { bool use_byte_loss_rate = false; TimeDelta padding_duration = TimeDelta::Zero(); bool bound_best_candidate = false; + bool pace_at_loss_based_estimate = false; }; struct Derivatives { diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc index 9b7ad03148..bb867f4fb0 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc @@ -1776,5 +1776,41 @@ TEST_F(LossBasedBweV2Test, UseByteLossRate) { DataRate::KilobitsPerSec(150)); } +TEST_F(LossBasedBweV2Test, PaceAtLossBasedEstimate) { + ExplicitKeyValueConfig key_value_config(ShortObservationConfig( + "PaceAtLossBasedEstimate:true,PaddingDuration:1000ms")); + LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); + loss_based_bandwidth_estimator.SetBandwidthEstimate( + DataRate::KilobitsPerSec(1000)); + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWithReceivedPackets( + /*first_packet_timestamp=*/Timestamp::Zero()), + /*delay_based_estimate=*/DataRate::KilobitsPerSec(1000), + /*in_alr=*/false); + EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kDelayBasedEstimate); + EXPECT_FALSE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate()); + + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWith100pLossRate( + /*first_packet_timestamp=*/Timestamp::Zero() + + kObservationDurationLowerBound), + /*delay_based_estimate=*/DataRate::KilobitsPerSec(1000), + /*in_alr=*/false); + EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kDecreasing); + EXPECT_TRUE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate()); + + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWithReceivedPackets( + /*first_packet_timestamp=*/Timestamp::Zero() + + kObservationDurationLowerBound * 2), + /*delay_based_estimate=*/DataRate::KilobitsPerSec(1000), + /*in_alr=*/false); + EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kIncreaseUsingPadding); + EXPECT_TRUE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate()); +} + } // namespace } // namespace webrtc diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc index 32b1b93c0b..31727051a8 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.cc @@ -105,8 +105,7 @@ ProbeControllerConfig::ProbeControllerConfig( probe_on_max_allocated_bitrate_change("probe_max_allocation", true), first_allocation_probe_scale("alloc_p1", 1), second_allocation_probe_scale("alloc_p2", 2), - allocation_allow_further_probing("alloc_probe_further", false), - allocation_probe_max("alloc_probe_max", DataRate::PlusInfinity()), + allocation_probe_limit_by_current_scale("alloc_current_bwe_limit"), min_probe_packets_sent("min_probe_packets_sent", 5), min_probe_duration("min_probe_duration", TimeDelta::Millis(15)), loss_limited_probe_scale("loss_limited_scale", 1.5), @@ -118,7 +117,7 @@ ProbeControllerConfig::ProbeControllerConfig( &further_exponential_probe_scale, &further_probe_threshold, &alr_probing_interval, &alr_probe_scale, &probe_on_max_allocated_bitrate_change, &first_allocation_probe_scale, - &second_allocation_probe_scale, &allocation_allow_further_probing, + &second_allocation_probe_scale, &allocation_probe_limit_by_current_scale, &min_probe_duration, &network_state_estimate_probing_interval, &probe_if_estimate_lower_than_network_state_estimate_ratio, &estimate_lower_than_network_state_estimate_probing_interval, @@ -138,7 +137,7 @@ ProbeControllerConfig::ProbeControllerConfig( key_value_config->Lookup("WebRTC-Bwe-AlrProbing")); ParseFieldTrial( {&first_allocation_probe_scale, &second_allocation_probe_scale, - &allocation_allow_further_probing, &allocation_probe_max}, + &allocation_probe_limit_by_current_scale}, key_value_config->Lookup("WebRTC-Bwe-AllocationProbing")); ParseFieldTrial({&min_probe_packets_sent, &min_probe_duration}, key_value_config->Lookup("WebRTC-Bwe-ProbingBehavior")); @@ -220,19 +219,31 @@ std::vector<ProbeClusterConfig> ProbeController::OnMaxTotalAllocatedBitrate( DataRate first_probe_rate = max_total_allocated_bitrate * config_.first_allocation_probe_scale.Value(); - DataRate probe_cap = config_.allocation_probe_max.Get(); - first_probe_rate = std::min(first_probe_rate, probe_cap); + DataRate current_bwe_limit = + !config_.allocation_probe_limit_by_current_scale + ? DataRate::PlusInfinity() + : estimated_bitrate_ * + config_.allocation_probe_limit_by_current_scale.Value(); + bool limited_by_current_bwe = current_bwe_limit < first_probe_rate; + if (limited_by_current_bwe) { + first_probe_rate = current_bwe_limit; + } + std::vector<DataRate> probes = {first_probe_rate}; - if (config_.second_allocation_probe_scale) { + if (!limited_by_current_bwe && config_.second_allocation_probe_scale) { DataRate second_probe_rate = max_total_allocated_bitrate * config_.second_allocation_probe_scale.Value(); - second_probe_rate = std::min(second_probe_rate, probe_cap); + limited_by_current_bwe = current_bwe_limit < second_probe_rate; + if (limited_by_current_bwe) { + second_probe_rate = current_bwe_limit; + } if (second_probe_rate > first_probe_rate) probes.push_back(second_probe_rate); } - return InitiateProbing(at_time, probes, - config_.allocation_allow_further_probing.Get()); + bool allow_further_probing = limited_by_current_bwe; + + return InitiateProbing(at_time, probes, allow_further_probing); } max_total_allocated_bitrate_ = max_total_allocated_bitrate; return std::vector<ProbeClusterConfig>(); diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h index feec81f2dc..25f02aee69 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller.h @@ -64,8 +64,7 @@ struct ProbeControllerConfig { FieldTrialParameter<bool> probe_on_max_allocated_bitrate_change; FieldTrialOptional<double> first_allocation_probe_scale; FieldTrialOptional<double> second_allocation_probe_scale; - FieldTrialFlag allocation_allow_further_probing; - FieldTrialParameter<DataRate> allocation_probe_max; + FieldTrialOptional<double> allocation_probe_limit_by_current_scale; // The minimum number probing packets used. FieldTrialParameter<int> min_probe_packets_sent; diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc index 94025b30ea..6e34a2962d 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/probe_controller_unittest.cc @@ -213,6 +213,42 @@ TEST(ProbeControllerTest, ProbesOnMaxAllocatedBitrateIncreaseOnlyWhenInAlr) { EXPECT_TRUE(probes.empty()); } +TEST(ProbeControllerTest, ProbesOnMaxAllocatedBitrateLimitedByCurrentBwe) { + ProbeControllerFixture fixture( + "WebRTC-Bwe-ProbingConfiguration/" + "alloc_current_bwe_limit:1.5/"); + ASSERT_TRUE(kMaxBitrate > 1.5 * kStartBitrate); + std::unique_ptr<ProbeController> probe_controller = + fixture.CreateController(); + ASSERT_THAT( + probe_controller->OnNetworkAvailability({.network_available = true}), + IsEmpty()); + auto probes = probe_controller->SetBitrates( + kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime()); + probes = probe_controller->SetEstimatedBitrate( + kStartBitrate, BandwidthLimitedCause::kDelayBasedLimited, + fixture.CurrentTime()); + + // Wait long enough to time out exponential probing. + fixture.AdvanceTime(kExponentialProbingTimeout); + probes = probe_controller->Process(fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); + + // Probe when in alr. + probe_controller->SetAlrStartTimeMs(fixture.CurrentTime().ms()); + probes = probe_controller->OnMaxTotalAllocatedBitrate(kMaxBitrate, + fixture.CurrentTime()); + EXPECT_EQ(probes.size(), 1u); + EXPECT_EQ(probes.at(0).target_data_rate, 1.5 * kStartBitrate); + + // Continue probing if probe succeeds. + probes = probe_controller->SetEstimatedBitrate( + 1.5 * kStartBitrate, BandwidthLimitedCause::kDelayBasedLimited, + fixture.CurrentTime()); + EXPECT_EQ(probes.size(), 1u); + EXPECT_GT(probes.at(0).target_data_rate, 1.5 * kStartBitrate); +} + TEST(ProbeControllerTest, CanDisableProbingOnMaxTotalAllocatedBitrateIncrease) { ProbeControllerFixture fixture( "WebRTC-Bwe-ProbingConfiguration/" diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc index 211d86c95d..7b305f12f1 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.cc @@ -700,8 +700,12 @@ bool SendSideBandwidthEstimation::LossBasedBandwidthEstimatorV2Enabled() const { bool SendSideBandwidthEstimation::LossBasedBandwidthEstimatorV2ReadyForUse() const { - return LossBasedBandwidthEstimatorV2Enabled() && - loss_based_bandwidth_estimator_v2_->IsReady(); + return loss_based_bandwidth_estimator_v2_->IsReady(); +} + +bool SendSideBandwidthEstimation::PaceAtLossBasedEstimate() const { + return LossBasedBandwidthEstimatorV2ReadyForUse() && + loss_based_bandwidth_estimator_v2_->PaceAtLossBasedEstimate(); } } // namespace webrtc diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h b/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h index dd4d25a236..1d919af7b6 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/send_side_bandwidth_estimation.h @@ -129,6 +129,7 @@ class SendSideBandwidthEstimation { BandwidthUsage delay_detector_state, absl::optional<DataRate> probe_bitrate, bool in_alr); + bool PaceAtLossBasedEstimate() const; private: friend class GoogCcStatePrinter; |