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 d4cb827098..7e051f505b 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 @@ -664,55 +664,6 @@ DataRate AverageBitrateAfterCrossInducedLoss(absl::string_view name) { s.TimeSinceStart(); } -TEST(GoogCcScenario, LossBasedRecoversFasterAfterCrossInducedLoss) { - // This test acts as a reference for the test below, showing that without the - // trial, we have worse behavior. - DataRate average_bitrate_without_loss_based = - AverageBitrateAfterCrossInducedLoss("googcc_unit/no_cross_loss_based"); - - // We recover bitrate better when subject to loss spikes from cross traffic - // when loss based controller is used. - ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/"); - DataRate average_bitrate_with_loss_based = - AverageBitrateAfterCrossInducedLoss("googcc_unit/cross_loss_based"); - - EXPECT_GT(average_bitrate_with_loss_based, - average_bitrate_without_loss_based); -} - -TEST(GoogCcScenario, LossBasedEstimatorCapsRateAtModerateLoss) { - ScopedFieldTrials trial("WebRTC-Bwe-LossBasedControl/Enabled/"); - Scenario s("googcc_unit/moderate_loss_channel", false); - CallClientConfig config; - config.transport.rates.min_rate = DataRate::KilobitsPerSec(10); - config.transport.rates.max_rate = DataRate::KilobitsPerSec(5000); - config.transport.rates.start_rate = DataRate::KilobitsPerSec(1000); - - NetworkSimulationConfig network; - network.bandwidth = DataRate::KilobitsPerSec(2000); - network.delay = TimeDelta::Millis(100); - // 3% loss rate is in the moderate loss rate region at 2000 kbps, limiting the - // bitrate increase. - network.loss_rate = 0.03; - auto send_net = s.CreateMutableSimulationNode(network); - auto* client = s.CreateClient("send", std::move(config)); - auto* route = s.CreateRoutes(client, {send_net->node()}, - s.CreateClient("return", CallClientConfig()), - {s.CreateSimulationNode(network)}); - s.CreateVideoStream(route->forward(), VideoStreamConfig()); - // Allow the controller to stabilize at the lower bitrate. - s.RunFor(TimeDelta::Seconds(1)); - // This increase in capacity would cause the target bitrate to increase to - // over 4000 kbps without LossBasedControl. - send_net->UpdateConfig([](NetworkSimulationConfig* c) { - c->bandwidth = DataRate::KilobitsPerSec(5000); - }); - s.RunFor(TimeDelta::Seconds(20)); - // Using LossBasedControl, the bitrate will not increase over 2500 kbps since - // we have detected moderate loss. - EXPECT_LT(client->target_rate().kbps(), 2500); -} - TEST(GoogCcScenario, MaintainsLowRateInSafeResetTrial) { const DataRate kLinkCapacity = DataRate::KilobitsPerSec(200); const DataRate kStartRate = DataRate::KilobitsPerSec(300); @@ -944,11 +895,39 @@ TEST(GoogCcScenario, FastRampupOnRembCapLifted) { EXPECT_GT(final_estimate.kbps(), 1500); } -TEST(GoogCcScenario, SlowRampupOnRembCapLiftedWithFieldTrial) { - ScopedFieldTrials trial("WebRTC-Bwe-ReceiverLimitCapsOnly/Disabled/"); - DataRate final_estimate = - RunRembDipScenario("googcc_unit/legacy_slow_rampup_on_remb_cap_lifted"); - EXPECT_LT(final_estimate.kbps(), 1000); +TEST(GoogCcScenario, FallbackToLossBasedBweWithoutPacketFeedback) { + const DataRate kLinkCapacity = DataRate::KilobitsPerSec(1000); + const DataRate kStartRate = DataRate::KilobitsPerSec(1000); + + Scenario s("googcc_unit/high_loss_channel", false); + auto* net = s.CreateMutableSimulationNode([&](NetworkSimulationConfig* c) { + c->bandwidth = kLinkCapacity; + c->delay = TimeDelta::Millis(100); + }); + auto* client = s.CreateClient("send", [&](CallClientConfig* c) { + c->transport.rates.start_rate = kStartRate; + }); + auto* route = s.CreateRoutes( + client, {net->node()}, s.CreateClient("return", CallClientConfig()), + {s.CreateSimulationNode(NetworkSimulationConfig())}); + + // Create a config without packet feedback. + VideoStreamConfig video_config; + video_config.stream.packet_feedback = false; + s.CreateVideoStream(route->forward(), video_config); + + s.RunFor(TimeDelta::Seconds(20)); + // Bandwith does not backoff because network is normal. + EXPECT_GE(client->target_rate().kbps(), 500); + + // Update the network to create high loss ratio + net->UpdateConfig([](NetworkSimulationConfig* c) { + c->loss_rate = 0.15; + }); + s.RunFor(TimeDelta::Seconds(20)); + + // Bandwidth decreases thanks to loss based bwe v0. + EXPECT_LE(client->target_rate().kbps(), 300); } } // namespace test 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 f9cea09d1f..b4d3ae8c1f 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc @@ -345,64 +345,64 @@ bool LossBasedBweV2::IsEstimateIncreasingWhenLossLimited( // configuration for the `LossBasedBweV2` which is explicitly enabled. absl::optional LossBasedBweV2::CreateConfig( const FieldTrialsView* key_value_config) { - FieldTrialParameter enabled("Enabled", false); + FieldTrialParameter enabled("Enabled", true); FieldTrialParameter bandwidth_rampup_upper_bound_factor( - "BwRampupUpperBoundFactor", 1.1); + "BwRampupUpperBoundFactor", 1000000.0); FieldTrialParameter rampup_acceleration_max_factor( "BwRampupAccelMaxFactor", 0.0); FieldTrialParameter rampup_acceleration_maxout_time( "BwRampupAccelMaxoutTime", TimeDelta::Seconds(60)); FieldTrialList candidate_factors("CandidateFactors", - {1.05, 1.0, 0.95}); + {1.02, 1.0, 0.95}); FieldTrialParameter higher_bandwidth_bias_factor("HigherBwBiasFactor", - 0.00001); + 0.0002); FieldTrialParameter higher_log_bandwidth_bias_factor( - "HigherLogBwBiasFactor", 0.001); + "HigherLogBwBiasFactor", 0.02); FieldTrialParameter inherent_loss_lower_bound( "InherentLossLowerBound", 1.0e-3); FieldTrialParameter loss_threshold_of_high_bandwidth_preference( - "LossThresholdOfHighBandwidthPreference", 0.99); + "LossThresholdOfHighBandwidthPreference", 0.15); FieldTrialParameter bandwidth_preference_smoothing_factor( "BandwidthPreferenceSmoothingFactor", 0.002); FieldTrialParameter inherent_loss_upper_bound_bandwidth_balance( - "InherentLossUpperBoundBwBalance", DataRate::KilobitsPerSec(15.0)); + "InherentLossUpperBoundBwBalance", DataRate::KilobitsPerSec(75.0)); FieldTrialParameter inherent_loss_upper_bound_offset( "InherentLossUpperBoundOffset", 0.05); FieldTrialParameter initial_inherent_loss_estimate( "InitialInherentLossEstimate", 0.01); FieldTrialParameter newton_iterations("NewtonIterations", 1); - FieldTrialParameter newton_step_size("NewtonStepSize", 0.5); + FieldTrialParameter newton_step_size("NewtonStepSize", 0.75); FieldTrialParameter append_acknowledged_rate_candidate( "AckedRateCandidate", true); FieldTrialParameter append_delay_based_estimate_candidate( - "DelayBasedCandidate", false); + "DelayBasedCandidate", true); FieldTrialParameter observation_duration_lower_bound( - "ObservationDurationLowerBound", TimeDelta::Seconds(1)); + "ObservationDurationLowerBound", TimeDelta::Millis(250)); FieldTrialParameter observation_window_size("ObservationWindowSize", 20); FieldTrialParameter sending_rate_smoothing_factor( "SendingRateSmoothingFactor", 0.0); FieldTrialParameter instant_upper_bound_temporal_weight_factor( - "InstantUpperBoundTemporalWeightFactor", 0.99); + "InstantUpperBoundTemporalWeightFactor", 0.9); FieldTrialParameter instant_upper_bound_bandwidth_balance( - "InstantUpperBoundBwBalance", DataRate::KilobitsPerSec(15.0)); + "InstantUpperBoundBwBalance", DataRate::KilobitsPerSec(75.0)); FieldTrialParameter instant_upper_bound_loss_offset( "InstantUpperBoundLossOffset", 0.05); FieldTrialParameter temporal_weight_factor("TemporalWeightFactor", - 0.99); + 0.9); FieldTrialParameter bandwidth_backoff_lower_bound_factor( "BwBackoffLowerBoundFactor", 1.0); FieldTrialParameter trendline_integration_enabled( "TrendlineIntegrationEnabled", false); FieldTrialParameter trendline_observations_window_size( "TrendlineObservationsWindowSize", 20); - FieldTrialParameter max_increase_factor("MaxIncreaseFactor", 1000.0); + FieldTrialParameter max_increase_factor("MaxIncreaseFactor", 1.3); FieldTrialParameter delayed_increase_window( "DelayedIncreaseWindow", TimeDelta::Millis(300)); FieldTrialParameter use_acked_bitrate_only_when_overusing( "UseAckedBitrateOnlyWhenOverusing", false); FieldTrialParameter not_increase_if_inherent_loss_less_than_average_loss( - "NotIncreaseIfInherentLossLessThanAverageLoss", false); + "NotIncreaseIfInherentLossLessThanAverageLoss", true); FieldTrialParameter high_loss_rate_threshold("HighLossRateThreshold", 1.0); FieldTrialParameter bandwidth_cap_at_high_loss_rate( 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 3cbc6f798e..c303c29d68 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 @@ -746,7 +746,7 @@ TEST_P(LossBasedBweV2Test, "ObservationWindowSize:2,ObservationDurationLowerBound:200ms," "InstantUpperBoundBwBalance:10000kbps," "DelayBasedCandidate:true,MaxIncreaseFactor:1.5,BwRampupUpperBoundFactor:" - "2.0/"); + "2.0,NotIncreaseIfInherentLossLessThanAverageLoss:false/"); LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000); DataRate acked_rate = DataRate::KilobitsPerSec(300); @@ -792,7 +792,7 @@ TEST_P(LossBasedBweV2Test, "InstantUpperBoundBwBalance:10000kbps," "DelayBasedCandidate:true,MaxIncreaseFactor:100," "BwRampupUpperBoundFactor:" - "2.0/"); + "2.0,NotIncreaseIfInherentLossLessThanAverageLoss:false/"); LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); DataRate delay_based_estimate = DataRate::KilobitsPerSec(600); DataRate acked_rate = DataRate::KilobitsPerSec(300); @@ -879,14 +879,19 @@ TEST_P(LossBasedBweV2Test, enough_feedback_2, delay_based_estimate, BandwidthUsage::kBwNormal, /*probe_estimate=*/absl::nullopt, /*upper_link_capacity=*/DataRate::PlusInfinity()); - EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state, - LossBasedState::kIncreasing); + EXPECT_NE(loss_based_bandwidth_estimator.GetLossBasedResult().state, + LossBasedState::kDelayBasedEstimate); } // After loss based bwe backs off, the next estimate is capped by // a factor of acked bitrate. TEST_P(LossBasedBweV2Test, IncreaseByFactorOfAckedBitrateAfterLossBasedBweBacksOff) { + ExplicitKeyValueConfig key_value_config( + "WebRTC-Bwe-LossBasedBweV2/" + "Enabled:true,LossThresholdOfHighBandwidthPreference:0.99," + "BwRampupUpperBoundFactor:1.2," + "InherentLossUpperBoundOffset:0.9,ObservationDurationLowerBound:200ms/"); std::vector enough_feedback_1 = CreatePacketResultsWith100pLossRate( /*first_packet_timestamp=*/Timestamp::Zero()); @@ -894,9 +899,6 @@ TEST_P(LossBasedBweV2Test, CreatePacketResultsWith10pLossRate( /*first_packet_timestamp=*/Timestamp::Zero() + kObservationDurationLowerBound); - ExplicitKeyValueConfig key_value_config( - Config(/*enabled=*/true, /*valid=*/true, - /*trendline_integration_enabled=*/GetParam())); LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000); @@ -1075,7 +1077,7 @@ TEST_P(LossBasedBweV2Test, "DelayBasedCandidate:true,InstantUpperBoundBwBalance:100kbps," "ObservationDurationLowerBound:200ms,HigherBwBiasFactor:1000," "HigherLogBwBiasFactor:1000,LossThresholdOfHighBandwidthPreference:0." - "20/"); + "20,NotIncreaseIfInherentLossLessThanAverageLoss:false/"); LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);