Add field trial to probe if NetworkState drop below a threshold
Change ProbeController field trial to also probe when loss limited but probe at the current estimate.
Bug: webrtc:14392
Change-Id: I8b30e316b935a0f2c375e2204a8e33e6671eb956
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/273901
Reviewed-by: Diep Bui <diepbp@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#38004}
diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc
index e60c722..b9e6151 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller.cc
@@ -89,6 +89,7 @@
TimeDelta::PlusInfinity()),
network_state_estimate_fast_rampup_rate("network_state_fast_rampup_rate",
0),
+ network_state_estimate_drop_down_rate("network_state_drop_down_rate", 0),
network_state_probe_scale("network_state_scale", 1.0),
network_state_probe_duration("network_state_probe_duration",
TimeDelta::Millis(15)),
@@ -99,16 +100,17 @@
allocation_probe_max("alloc_probe_max", DataRate::PlusInfinity()),
min_probe_packets_sent("min_probe_packets_sent", 5),
min_probe_duration("min_probe_duration", TimeDelta::Millis(15)),
- probe_if_bwe_limited_due_to_loss("probe_if_bwe_limited_due_to_loss",
- true) {
+ limit_probe_target_rate_to_loss_bwe("limit_probe_target_rate_to_loss_bwe",
+ false) {
ParseFieldTrial(
{&first_exponential_probe_scale, &second_exponential_probe_scale,
&further_exponential_probe_scale, &further_probe_threshold,
&alr_probing_interval, &alr_probe_scale, &first_allocation_probe_scale,
&second_allocation_probe_scale, &allocation_allow_further_probing,
&min_probe_duration, &network_state_estimate_probing_interval,
- &network_state_estimate_fast_rampup_rate, &network_state_probe_scale,
- &network_state_probe_duration, &probe_if_bwe_limited_due_to_loss},
+ &network_state_estimate_fast_rampup_rate,
+ &network_state_estimate_drop_down_rate, &network_state_probe_scale,
+ &network_state_probe_duration, &limit_probe_target_rate_to_loss_bwe},
key_value_config->Lookup("WebRTC-Bwe-ProbingConfiguration"));
// Specialized keys overriding subsets of WebRTC-Bwe-ProbingConfiguration
@@ -364,6 +366,15 @@
network_estimate_->link_capacity_upper)) {
send_probe_on_next_process_interval_ = true;
}
+ if (config_.network_state_estimate_drop_down_rate > 0 && network_estimate_ &&
+ (estimated_bitrate_ > estimate.link_capacity_upper ||
+ bwe_limited_due_to_packet_loss_) &&
+ estimate.link_capacity_upper <=
+ config_.network_state_estimate_drop_down_rate *
+ network_estimate_->link_capacity_upper) {
+ send_probe_on_next_process_interval_ = true;
+ }
+
network_estimate_ = estimate;
}
@@ -434,11 +445,11 @@
Timestamp now,
std::vector<DataRate> bitrates_to_probe,
bool probe_further) {
- if (bwe_limited_due_to_packet_loss_ &&
- !config_.probe_if_bwe_limited_due_to_loss) {
- 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_;
+ }
if (config_.network_state_estimate_probing_interval->IsFinite() &&
network_estimate_ &&
network_estimate_->link_capacity_upper > DataRate::Zero()) {
diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h
index 399b38e..c32f25e 100644
--- a/modules/congestion_controller/goog_cc/probe_controller.h
+++ b/modules/congestion_controller/goog_cc/probe_controller.h
@@ -53,6 +53,9 @@
// If the network state estimate increase more than this rate, a probe is sent
// the next process interval.
FieldTrialParameter<double> network_state_estimate_fast_rampup_rate;
+ // If the network state estimate decreases more than this rate, a probe is
+ // sent the next process interval.
+ FieldTrialParameter<double> network_state_estimate_drop_down_rate;
FieldTrialParameter<double> network_state_probe_scale;
// Overrides min_probe_duration if network_state_estimate_probing_interval
// is set and a network state estimate is known.
@@ -68,8 +71,9 @@
FieldTrialParameter<int> min_probe_packets_sent;
// The minimum probing duration.
FieldTrialParameter<TimeDelta> min_probe_duration;
-
- FieldTrialParameter<bool> probe_if_bwe_limited_due_to_loss;
+ // Max limit the target rate of a probe to current estimate if BWE is loss
+ // limited.
+ FieldTrialParameter<bool> limit_probe_target_rate_to_loss_bwe;
};
// 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 8860a0f..2907606 100644
--- a/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
+++ b/modules/congestion_controller/goog_cc/probe_controller_unittest.cc
@@ -504,10 +504,10 @@
EXPECT_EQ(probes[0].target_data_rate.bps(), 400'000);
}
-TEST(ProbeControllerTest, PauseAlrProbeWhenLossBasedBweLimited) {
+TEST(ProbeControllerTest, LimitAlrProbeWhenLossBasedBweLimited) {
ProbeControllerFixture fixture(
"WebRTC-Bwe-ProbingConfiguration/"
- "probe_if_bwe_limited_due_to_loss:false/");
+ "limit_probe_target_rate_to_loss_bwe:true/");
std::unique_ptr<ProbeController> probe_controller =
fixture.CreateController();
probe_controller->EnablePeriodicAlrProbing(true);
@@ -527,40 +527,16 @@
fixture.CurrentTime());
fixture.AdvanceTime(TimeDelta::Seconds(6));
probes = probe_controller->Process(fixture.CurrentTime());
- EXPECT_TRUE(probes.empty());
- // ALR probing resumed when estimate is no longer restricted by loss based
- // BWE.
+ ASSERT_EQ(probes.size(), 1u);
+ EXPECT_EQ(probes[0].target_data_rate, DataRate::BitsPerSec(500));
+
probes = probe_controller->SetEstimatedBitrate(
DataRate::BitsPerSec(500), /*bwe_limited_due_to_packet_loss=*/false,
fixture.CurrentTime());
fixture.AdvanceTime(TimeDelta::Seconds(6));
probes = probe_controller->Process(fixture.CurrentTime());
- EXPECT_TRUE(!probes.empty());
-}
-
-TEST(ProbeControllerTest, AlrProbeStartWhenNotLossBasedBweLimited) {
- ProbeControllerFixture fixture(
- "WebRTC-Bwe-ProbingConfiguration/"
- "probe_if_bwe_limited_due_to_loss:false/");
- std::unique_ptr<ProbeController> probe_controller =
- fixture.CreateController();
- probe_controller->EnablePeriodicAlrProbing(true);
- auto probes = probe_controller->SetBitrates(
- kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime());
- probes = probe_controller->SetEstimatedBitrate(
- DataRate::BitsPerSec(500), /*bwe_limited_due_to_packet_loss=*/true,
- fixture.CurrentTime());
- // Expect the controller to send a new probe after 5s has passed.
- probe_controller->SetAlrStartTimeMs(fixture.CurrentTime().ms());
- fixture.AdvanceTime(TimeDelta::Seconds(5));
- probes = probe_controller->Process(fixture.CurrentTime());
- EXPECT_TRUE(probes.empty());
- probes = probe_controller->SetEstimatedBitrate(
- DataRate::BitsPerSec(500), /*bwe_limited_due_to_packet_loss*/ false,
- fixture.CurrentTime());
- fixture.AdvanceTime(TimeDelta::Seconds(1));
- probes = probe_controller->Process(fixture.CurrentTime());
- EXPECT_TRUE(!probes.empty());
+ ASSERT_TRUE(!probes.empty());
+ EXPECT_GT(probes[0].target_data_rate, DataRate::BitsPerSec(500));
}
TEST(ProbeControllerTest, PeriodicProbeAtUpperNetworkStateEstimate) {
@@ -590,10 +566,10 @@
}
TEST(ProbeControllerTest,
- PausePeriodicProbeAtUpperNetworkStateEstimateIfLossBasedLimited) {
+ LimitProbeAtUpperNetworkStateEstimateIfLossBasedLimited) {
ProbeControllerFixture fixture(
"WebRTC-Bwe-ProbingConfiguration/"
- "network_state_interval:5s,probe_if_bwe_limited_due_to_loss:false/");
+ "network_state_interval:5s,limit_probe_target_rate_to_loss_bwe:true/");
std::unique_ptr<ProbeController> probe_controller =
fixture.CreateController();
@@ -616,14 +592,16 @@
// Expect the controller to send a new probe after 5s has passed.
fixture.AdvanceTime(TimeDelta::Seconds(5));
probes = probe_controller->Process(fixture.CurrentTime());
- EXPECT_TRUE(probes.empty());
+ ASSERT_TRUE(!probes.empty());
+ EXPECT_EQ(probes[0].target_data_rate, DataRate::BitsPerSec(500));
probes = probe_controller->SetEstimatedBitrate(
DataRate::BitsPerSec(500), /*bwe_limited_due_to_packet_loss=*/false,
fixture.CurrentTime());
fixture.AdvanceTime(TimeDelta::Seconds(5));
probes = probe_controller->Process(fixture.CurrentTime());
- EXPECT_FALSE(probes.empty());
+ ASSERT_TRUE(!probes.empty());
+ EXPECT_GT(probes[0].target_data_rate, DataRate::BitsPerSec(500));
}
TEST(ProbeControllerTest, AlrProbesLimitedByNetworkStateEstimate) {
@@ -677,7 +655,7 @@
EXPECT_EQ(probes[0].target_duration, TimeDelta::Millis(100));
}
-TEST(ProbeControllerTest, ProbeAfterLargeNetworkStateChange) {
+TEST(ProbeControllerTest, ProbeAfterLargeNetworkStateIncrease) {
ProbeControllerFixture fixture(
"WebRTC-Bwe-ProbingConfiguration/"
"network_state_interval:5s,network_state_fast_rampup_rate:2.0/");
@@ -716,5 +694,81 @@
EXPECT_EQ(probes.size(), 1u);
}
+TEST(ProbeControllerTest, ProbeAfterLargeNetworkStateDrop) {
+ ProbeControllerFixture fixture(
+ "WebRTC-Bwe-ProbingConfiguration/"
+ "network_state_interval:5s,network_state_drop_down_rate:0.5/");
+ std::unique_ptr<ProbeController> probe_controller =
+ fixture.CreateController();
+
+ auto probes = probe_controller->SetBitrates(
+ kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime());
+ probes = probe_controller->SetEstimatedBitrate(
+ kStartBitrate, /*bwe_limited_due_to_packet_loss=*/false,
+ fixture.CurrentTime());
+ // Need to wait at least one second before process can trigger a new probe.
+ fixture.AdvanceTime(TimeDelta::Millis(1100));
+ probes = probe_controller->Process(fixture.CurrentTime());
+ EXPECT_TRUE(probes.empty());
+
+ NetworkStateEstimate state_estimate;
+ state_estimate.link_capacity_upper = kStartBitrate;
+ probe_controller->SetNetworkStateEstimate(state_estimate);
+ // No probe since NetworkStateEstimate is not lower than the set
+ // estimated bitrate.
+ probes = probe_controller->Process(fixture.CurrentTime());
+ EXPECT_TRUE(probes.empty());
+
+ // If NetworkState decrease just a bit, dont expect the probe to be sent
+ // immediately.
+ state_estimate.link_capacity_upper = kStartBitrate * 0.9;
+ probe_controller->SetNetworkStateEstimate(state_estimate);
+ probes = probe_controller->Process(fixture.CurrentTime());
+ EXPECT_TRUE(probes.empty());
+
+ // If NetworkState decrease dramatically, expect a probe to be sent.
+ state_estimate.link_capacity_upper = kStartBitrate * 0.9 * 0.5;
+ probe_controller->SetNetworkStateEstimate(state_estimate);
+ probes = probe_controller->Process(fixture.CurrentTime());
+ EXPECT_EQ(probes.size(), 1u);
+}
+
+TEST(ProbeControllerTest, ProbeAfterLargeNetworkStateDropLossLimited) {
+ ProbeControllerFixture fixture(
+ "WebRTC-Bwe-ProbingConfiguration/"
+ "network_state_interval:5s,network_state_drop_down_rate:0.5,limit_probe_"
+ "target_rate_to_loss_bwe:true/");
+ std::unique_ptr<ProbeController> probe_controller =
+ fixture.CreateController();
+
+ auto probes = probe_controller->SetBitrates(
+ kMinBitrate, kStartBitrate, kMaxBitrate, fixture.CurrentTime());
+ probes = probe_controller->SetEstimatedBitrate(
+ kStartBitrate, /*bwe_limited_due_to_packet_loss=*/false,
+ fixture.CurrentTime());
+ // Need to wait at least one second before process can trigger a new probe.
+ fixture.AdvanceTime(TimeDelta::Millis(1100));
+ probes = probe_controller->Process(fixture.CurrentTime());
+ EXPECT_TRUE(probes.empty());
+
+ NetworkStateEstimate state_estimate;
+ state_estimate.link_capacity_upper = kStartBitrate;
+ probe_controller->SetNetworkStateEstimate(state_estimate);
+ probes = probe_controller->Process(fixture.CurrentTime());
+ EXPECT_TRUE(probes.empty());
+
+ // Loss limited.
+ probes = probe_controller->SetEstimatedBitrate(
+ kStartBitrate / 3, /*bwe_limited_due_to_packet_loss=*/true,
+ fixture.CurrentTime());
+ // If NetworkState decrease dramatically, expect a probe to be sent.
+ // But limited to loss based estimate.
+ state_estimate.link_capacity_upper = kStartBitrate / 2;
+ probe_controller->SetNetworkStateEstimate(state_estimate);
+ probes = probe_controller->Process(fixture.CurrentTime());
+ ASSERT_EQ(probes.size(), 1u);
+ EXPECT_EQ(probes[0].target_data_rate, kStartBitrate / 3);
+}
+
} // namespace test
} // namespace webrtc