From 7d1f6bb86cfc3751d4f3ad281d4e56b0266a9c57 Mon Sep 17 00:00:00 2001 From: Per Kjellander Date: Mon, 19 Sep 2022 16:19:55 +0200 Subject: [PATCH] Add field trial to not probe if estimates are larger that max needed. This add field trial string "skip_if_est_larger_than_fraction_of_max" Dont send a probe if min(estimate, network state estimate) is larger than this fraction of the set max bitrate. Bug: webrtc:14392 Change-Id: I7333f6ef45ab0c019f21b9e4c604352219e1d025 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/275940 Reviewed-by: Diep Bui Commit-Queue: Per Kjellander Cr-Commit-Position: refs/heads/main@{#38123} --- .../goog_cc/probe_controller.cc | 21 ++++- .../goog_cc/probe_controller.h | 3 + .../goog_cc/probe_controller_unittest.cc | 76 +++++++++++++++++++ 3 files changed, 97 insertions(+), 3 deletions(-) diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc index cd6334e87b..0dfb8a3ad4 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/modules/congestion_controller/goog_cc/probe_controller.cc @@ -101,7 +101,10 @@ ProbeControllerConfig::ProbeControllerConfig( min_probe_packets_sent("min_probe_packets_sent", 5), min_probe_duration("min_probe_duration", TimeDelta::Millis(15)), limit_probe_target_rate_to_loss_bwe("limit_probe_target_rate_to_loss_bwe", - false) { + false), + skip_if_estimate_larger_than_fraction_of_max( + "skip_if_est_larger_than_fraction_of_max", + 0.0) { ParseFieldTrial( {&first_exponential_probe_scale, &second_exponential_probe_scale, &further_exponential_probe_scale, &further_probe_threshold, @@ -111,7 +114,8 @@ ProbeControllerConfig::ProbeControllerConfig( &network_state_estimate_fast_rampup_rate, &network_state_estimate_drop_down_rate, &network_state_probe_scale, &network_state_probe_duration, &min_probe_packets_sent, - &limit_probe_target_rate_to_loss_bwe}, + &limit_probe_target_rate_to_loss_bwe, + &skip_if_estimate_larger_than_fraction_of_max}, key_value_config->Lookup("WebRTC-Bwe-ProbingConfiguration")); // Specialized keys overriding subsets of WebRTC-Bwe-ProbingConfiguration @@ -450,10 +454,20 @@ std::vector ProbeController::InitiateProbing( Timestamp now, std::vector bitrates_to_probe, bool probe_further) { + if (config_.skip_if_estimate_larger_than_fraction_of_max > 0) { + DataRate network_estimate = network_estimate_ + ? network_estimate_->link_capacity_upper + : DataRate::PlusInfinity(); + if (std::min(network_estimate, estimated_bitrate_) > + config_.skip_if_estimate_larger_than_fraction_of_max * max_bitrate_) { + return {}; + } + } + DataRate max_probe_bitrate = max_bitrate_; if (bwe_limited_due_to_packet_loss_ && config_.limit_probe_target_rate_to_loss_bwe) { - max_probe_bitrate = estimated_bitrate_; + max_probe_bitrate = std::min(estimated_bitrate_, max_bitrate_); } if (config_.network_state_estimate_probing_interval->IsFinite() && network_estimate_ && @@ -472,6 +486,7 @@ std::vector ProbeController::InitiateProbing( max_probe_bitrate = std::min(max_probe_bitrate, max_total_allocated_bitrate_ * 2); } + send_probe_on_next_process_interval_ = false; std::vector pending_probes; diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h index c32f25e00a..e1ee08fc99 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.h +++ b/modules/congestion_controller/goog_cc/probe_controller.h @@ -74,6 +74,9 @@ struct ProbeControllerConfig { // Max limit the target rate of a probe to current estimate if BWE is loss // limited. FieldTrialParameter limit_probe_target_rate_to_loss_bwe; + // Dont send a probe if min(estimate, network state estimate) is larger than + // this fraction of the set max bitrate. + FieldTrialParameter skip_if_estimate_larger_than_fraction_of_max; }; // This class controls initiation of probing to estimate initial channel diff --git a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc index bf2235af94..06ec68196e 100644 --- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc +++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc @@ -833,5 +833,81 @@ TEST(ProbeControllerTest, ProbeFurtherWhenDelayBasedLimited) { EXPECT_EQ(probes[0].target_data_rate, state_estimate.link_capacity_upper); } +TEST(ProbeControllerTest, SkipAlrProbeIfEstimateLargerThanMaxProbe) { + ProbeControllerFixture fixture( + "WebRTC-Bwe-ProbingConfiguration/" + "skip_if_est_larger_than_fraction_of_max:0.9/"); + std::unique_ptr probe_controller = + fixture.CreateController(); + probe_controller->EnablePeriodicAlrProbing(true); + auto probes = probe_controller->SetBitrates( + kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime()); + ASSERT_FALSE(probes.empty()); + + probes = probe_controller->SetEstimatedBitrate( + kMaxBitrate, /*bwe_limited_due_to_packet_loss=*/false, + fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); + + probe_controller->SetAlrStartTimeMs(fixture.CurrentTime().ms()); + fixture.AdvanceTime(TimeDelta::Seconds(10)); + probes = probe_controller->Process(fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); + + // But if the max rate increase, A new probe is sent. + probe_controller->SetMaxBitrate(2 * kMaxBitrate); + probes = probe_controller->Process(fixture.CurrentTime()); + EXPECT_FALSE(probes.empty()); +} + +TEST(ProbeControllerTest, SkipNetworkStateProbeIfEstimateLargerThanMaxProbe) { + ProbeControllerFixture fixture( + "WebRTC-Bwe-ProbingConfiguration/" + "network_state_interval:2s,skip_if_est_larger_than_fraction_of_max:0.9/"); + std::unique_ptr probe_controller = + fixture.CreateController(); + auto probes = probe_controller->SetBitrates( + kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime()); + ASSERT_FALSE(probes.empty()); + + probe_controller->SetNetworkStateEstimate( + {.link_capacity_upper = 2 * kMaxBitrate}); + probes = probe_controller->SetEstimatedBitrate( + kMaxBitrate, /*bwe_limited_due_to_packet_loss=*/false, + fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); + + fixture.AdvanceTime(TimeDelta::Seconds(10)); + probes = probe_controller->Process(fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); +} + +TEST(ProbeControllerTest, SendsProbeIfNetworkStateEstimateLowerThanMaxProbe) { + ProbeControllerFixture fixture( + "WebRTC-Bwe-ProbingConfiguration/" + "network_state_interval:2s,skip_if_est_larger_than_fraction_of_max:0.9," + "network_state_drop_down_rate:0.5/"); + std::unique_ptr probe_controller = + fixture.CreateController(); + auto probes = probe_controller->SetBitrates( + kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime()); + ASSERT_FALSE(probes.empty()); + probe_controller->SetNetworkStateEstimate( + {.link_capacity_upper = 2 * kMaxBitrate}); + probes = probe_controller->SetEstimatedBitrate( + kMaxBitrate, /*bwe_limited_due_to_packet_loss=*/false, + fixture.CurrentTime()); + EXPECT_TRUE(probes.empty()); + + // Need to wait at least one second before process can trigger a new probe. + fixture.AdvanceTime(TimeDelta::Millis(1100)); + + // Sends a probe immediately if NetworkState estimate decrease. + probe_controller->SetNetworkStateEstimate( + {.link_capacity_upper = kStartBitrate}); + probes = probe_controller->Process(fixture.CurrentTime()); + EXPECT_FALSE(probes.empty()); +} + } // namespace test } // namespace webrtc