Field trial to not clamp delay based estimate to a lowered link estimate

This adds a new paramater to WebRTC-Bwe-EstimateBoundedIncrease that ensure that even if the link capacity has decreased, the delay based estimate does not immediately decrease unless an overuse has been detected.
This is a follow up to https://webrtc-review.googlesource.com/c/src/+/252442/

Bug: none
Change-Id: I98d77ba1e3f7856b06f2691575f2d248a500e659
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/253901
Reviewed-by: Diep Bui <diepbp@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36154}
This commit is contained in:
Per Kjellander 2022-03-09 09:29:42 +01:00 committed by WebRTC LUCI CQ
parent f73b524a5a
commit 4d54260ae2
4 changed files with 92 additions and 2 deletions

View File

@ -122,6 +122,7 @@ if (rtc_include_tests) {
"../../api/transport:field_trial_based_config",
"../../api/transport:mock_network_control",
"../../api/transport:network_control",
"../../api/units:data_rate",
"../../rtc_base",
"../../rtc_base:checks",
"../../rtc_base:rtc_base_approved",

View File

@ -99,7 +99,8 @@ AimdRateControl::AimdRateControl(const WebRtcKeyValueConfig* key_value_config,
link_capacity_fix_("link_capacity_fix") {
ParseFieldTrial(
{&disable_estimate_bounded_increase_, &estimate_bounded_increase_ratio_,
&ignore_throughput_limit_if_network_estimate_},
&ignore_throughput_limit_if_network_estimate_,
&ignore_network_estimate_decrease_},
key_value_config->Lookup("WebRTC-Bwe-EstimateBoundedIncrease"));
// E.g
// WebRTC-BweAimdRateControlConfig/initial_backoff_interval:100ms/
@ -380,7 +381,10 @@ DataRate AimdRateControl::ClampBitrate(DataRate new_bitrate) const {
network_estimate_->link_capacity_upper.IsFinite()) {
DataRate upper_bound = network_estimate_->link_capacity_upper *
estimate_bounded_increase_ratio_.Get();
new_bitrate = std::min(new_bitrate, upper_bound);
if (ignore_network_estimate_decrease_) {
upper_bound = std::max(upper_bound, current_bitrate_);
}
new_bitrate = std::min(upper_bound, new_bitrate);
}
new_bitrate = std::max(new_bitrate, min_configured_bitrate_);
return new_bitrate;

View File

@ -113,6 +113,8 @@ class AimdRateControl {
FieldTrialParameter<double> estimate_bounded_increase_ratio_{"ratio", 1.0};
FieldTrialParameter<bool> ignore_throughput_limit_if_network_estimate_{
"ignore_acked", false};
FieldTrialParameter<bool> ignore_network_estimate_decrease_{"ignore_decr",
false};
absl::optional<DataRate> last_decrease_;
FieldTrialOptional<TimeDelta> initial_backoff_interval_;
FieldTrialFlag link_capacity_fix_;

View File

@ -12,6 +12,7 @@
#include <memory>
#include "api/transport/field_trial_based_config.h"
#include "api/units/data_rate.h"
#include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gtest.h"
@ -254,6 +255,37 @@ TEST(AimdRateControlTest, SetEstimateIncreaseBweInAlr) {
2 * kInitialBitrateBps);
}
TEST(AimdRateControlTest, SetEstimateClampedByNetworkEstimate) {
auto states = CreateAimdRateControlStates(/*send_side=*/true);
NetworkStateEstimate network_estimate;
network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(400);
states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
SetEstimate(states, 500'000);
EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
network_estimate.link_capacity_upper);
}
TEST(AimdRateControlTest, SetEstimateIgnoresNetworkEstimatesLowerThanCurrent) {
test::ScopedFieldTrials override_field_trials(
"WebRTC-Bwe-EstimateBoundedIncrease/"
"ratio:0.85,ignore_acked:true,ignore_decr:true/");
auto states = CreateAimdRateControlStates(/*send_side=*/true);
states.aimd_rate_control->SetStartBitrate(DataRate::KilobitsPerSec(30));
NetworkStateEstimate network_estimate;
network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(400);
states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
SetEstimate(states, 500'000);
ASSERT_EQ(states.aimd_rate_control->LatestEstimate(),
network_estimate.link_capacity_upper * 0.85);
NetworkStateEstimate lower_network_estimate;
lower_network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(300);
states.aimd_rate_control->SetNetworkStateEstimate(lower_network_estimate);
SetEstimate(states, 500'000);
EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
network_estimate.link_capacity_upper * 0.85);
}
TEST(AimdRateControlTest, EstimateIncreaseWhileNotInAlr) {
// Allow the estimate to increase as long as alr is not detected to ensure
// tha BWE can not get stuck at a certain bitrate.
@ -317,6 +349,57 @@ TEST(AimdRateControlTest, EstimateLimitedByNetworkEstimateInAlrIfSet) {
network_estimate.link_capacity_upper * 0.85);
}
TEST(AimdRateControlTest, EstimateNotLoweredByNetworkEstimate) {
// The delay based estimator is allowed to increase up to a percentage of
// upper link capacity but does not decrease unless the delay detector
// discover an overuse.
test::ScopedFieldTrials override_field_trials(
"WebRTC-Bwe-EstimateBoundedIncrease/"
"ratio:0.85,ignore_acked:true,ignore_decr:true/"
"WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
auto states = CreateAimdRateControlStates(/*send_side=*/true);
constexpr int kInitialBitrateBps = 123000;
constexpr int kEstimatedThroughputBps = 30'000;
SetEstimate(states, kInitialBitrateBps);
NetworkStateEstimate network_estimate;
network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(200);
states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
for (int i = 0; i < 100; ++i) {
UpdateRateControl(states, BandwidthUsage::kBwNormal,
kEstimatedThroughputBps,
states.simulated_clock->TimeInMilliseconds());
states.simulated_clock->AdvanceTimeMilliseconds(100);
}
DataRate estimate_after_increase = states.aimd_rate_control->LatestEstimate();
ASSERT_EQ(estimate_after_increase,
network_estimate.link_capacity_upper * 0.85);
// A lower network estimate does not decrease the estimate immediately,
// but the estimate is not allowed to increase.
network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(100);
network_estimate.link_capacity_lower = DataRate::KilobitsPerSec(80);
states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
for (int i = 0; i < 10; ++i) {
UpdateRateControl(states, BandwidthUsage::kBwNormal,
kEstimatedThroughputBps,
states.simulated_clock->TimeInMilliseconds());
states.simulated_clock->AdvanceTimeMilliseconds(100);
EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
estimate_after_increase);
}
// If the detector detects and overuse, BWE drops to a value relative the
// network estimate.
UpdateRateControl(states, BandwidthUsage::kBwOverusing,
kEstimatedThroughputBps,
states.simulated_clock->TimeInMilliseconds());
EXPECT_LT(states.aimd_rate_control->LatestEstimate(),
network_estimate.link_capacity_lower);
EXPECT_GT(states.aimd_rate_control->LatestEstimate().bps(),
kEstimatedThroughputBps);
}
TEST(AimdRateControlTest, EstimateDoesNotIncreaseInAlrIfNetworkEstimateNotSet) {
// When alr is detected, the delay based estimator is not allowed to increase
// bwe since there will be no feedback from the network if the new estimate