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:
Per Kjellander
2022-09-03 21:44:11 +02:00
committed by WebRTC LUCI CQ
parent 189a32b732
commit ee969299f9
3 changed files with 115 additions and 46 deletions

View File

@ -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()) {

View File

@ -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

View File

@ -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