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}
This commit is contained in:

committed by
WebRTC LUCI CQ

parent
189a32b732
commit
ee969299f9
@ -89,6 +89,7 @@ ProbeControllerConfig::ProbeControllerConfig(
|
||||
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 @@ ProbeControllerConfig::ProbeControllerConfig(
|
||||
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 @@ void ProbeController::SetNetworkStateEstimate(
|
||||
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 @@ std::vector<ProbeClusterConfig> ProbeController::InitiateProbing(
|
||||
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()) {
|
||||
|
@ -53,6 +53,9 @@ struct ProbeControllerConfig {
|
||||
// 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 @@ struct ProbeControllerConfig {
|
||||
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
|
||||
|
@ -504,10 +504,10 @@ TEST(ProbeControllerTest, ConfigurableProbingFieldTrial) {
|
||||
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 @@ TEST(ProbeControllerTest, PauseAlrProbeWhenLossBasedBweLimited) {
|
||||
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, PeriodicProbeAtUpperNetworkStateEstimate) {
|
||||
}
|
||||
|
||||
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 @@ TEST(ProbeControllerTest,
|
||||
// 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 @@ TEST(ProbeControllerTest, CanSetLongerProbeDurationAfterNetworkStateEstimate) {
|
||||
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 @@ TEST(ProbeControllerTest, ProbeAfterLargeNetworkStateChange) {
|
||||
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
|
||||
|
Reference in New Issue
Block a user