diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc index a5260bb8ce..78f3cba78d 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc @@ -380,6 +380,8 @@ absl::optional LossBasedBweV2::CreateConfig( "AckedRateCandidate", true); FieldTrialParameter append_delay_based_estimate_candidate( "DelayBasedCandidate", true); + FieldTrialParameter append_upper_bound_candidate_in_alr( + "UpperBoundCandidateInAlr", false); FieldTrialParameter observation_duration_lower_bound( "ObservationDurationLowerBound", TimeDelta::Millis(250)); FieldTrialParameter observation_window_size("ObservationWindowSize", 20); @@ -433,6 +435,7 @@ absl::optional LossBasedBweV2::CreateConfig( &newton_step_size, &append_acknowledged_rate_candidate, &append_delay_based_estimate_candidate, + &append_upper_bound_candidate_in_alr, &observation_duration_lower_bound, &observation_window_size, &sending_rate_smoothing_factor, @@ -485,6 +488,8 @@ absl::optional LossBasedBweV2::CreateConfig( append_acknowledged_rate_candidate.Get(); config->append_delay_based_estimate_candidate = append_delay_based_estimate_candidate.Get(); + config->append_upper_bound_candidate_in_alr = + append_upper_bound_candidate_in_alr.Get(); config->observation_duration_lower_bound = observation_duration_lower_bound.Get(); config->observation_window_size = observation_window_size.Get(); @@ -776,6 +781,11 @@ std::vector LossBasedBweV2::GetCandidates( } } + if (in_alr && config_->append_upper_bound_candidate_in_alr && + current_best_estimate_.loss_limited_bandwidth > GetInstantUpperBound()) { + bandwidths.push_back(GetInstantUpperBound()); + } + const DataRate candidate_bandwidth_upper_bound = GetCandidateBandwidthUpperBound(); diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h index 4a95c10f28..9221028ddd 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h @@ -99,6 +99,7 @@ class LossBasedBweV2 { double newton_step_size = 0.0; bool append_acknowledged_rate_candidate = true; bool append_delay_based_estimate_candidate = false; + bool append_upper_bound_candidate_in_alr = false; TimeDelta observation_duration_lower_bound = TimeDelta::Zero(); int observation_window_size = 0; double sending_rate_smoothing_factor = 0.0; diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc index a25dc95200..8416f29f9c 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc @@ -1388,6 +1388,38 @@ TEST_F(LossBasedBweV2Test, HasIncreaseStateBecauseOfLowerBound) { LossBasedState::kIncreasing); } +TEST_F(LossBasedBweV2Test, + EstimateIncreaseSlowlyFromInstantUpperBoundInAlrIfFieldTrial) { + ExplicitKeyValueConfig key_value_config( + ShortObservationConfig("UpperBoundCandidateInAlr:true")); + LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); + loss_based_bandwidth_estimator.SetBandwidthEstimate( + DataRate::KilobitsPerSec(1000)); + loss_based_bandwidth_estimator.SetAcknowledgedBitrate( + DataRate::KilobitsPerSec(150)); + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWith50pLossRate( + /*first_packet_timestamp=*/Timestamp::Zero()), + /*delay_based_estimate=*/DataRate::PlusInfinity(), + /*in_alr=*/true); + LossBasedBweV2::Result result_after_loss = + loss_based_bandwidth_estimator.GetLossBasedResult(); + ASSERT_EQ(result_after_loss.state, LossBasedState::kDecreasing); + + for (int feedback_count = 1; feedback_count <= 3; ++feedback_count) { + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + CreatePacketResultsWithReceivedPackets( + /*first_packet_timestamp=*/Timestamp::Zero() + + feedback_count * kObservationDurationLowerBound), + /*delay_based_estimate=*/DataRate::PlusInfinity(), + /*in_alr=*/true); + } + // Expect less than 100% increase. + EXPECT_LT( + loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate, + 2 * result_after_loss.bandwidth_estimate); +} + TEST_F(LossBasedBweV2Test, HasDelayBasedStateIfLossBasedBweIsMax) { ExplicitKeyValueConfig key_value_config(ShortObservationConfig("")); LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);