Add field trial for limiting probes and delay based estimates to link
capacity.
Allow delay based estimate to increase up to 85% of the current NetworkStateEstimate
even if in ALR. The estimate may not increase higher than that.
WebRTC-Bwe-EstimateBoundedIncrease/ratio:0.85,ignore_acked:true
Bug: none
Change-Id: I6f34af7fab03082ca168e624ddea06f216790fbc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/252442
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36096}
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.cc b/modules/remote_bitrate_estimator/aimd_rate_control.cc
index a3da2b5..bf1d431 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -95,11 +95,12 @@
estimate_bounded_backoff_(
IsNotDisabled(*key_value_config,
"WebRTC-Bwe-EstimateBoundedBackoff")),
- estimate_bounded_increase_(
- IsNotDisabled(*key_value_config,
- "WebRTC-Bwe-EstimateBoundedIncrease")),
initial_backoff_interval_("initial_backoff_interval"),
link_capacity_fix_("link_capacity_fix") {
+ ParseFieldTrial(
+ {&disable_estimate_bounded_increase_, &estimate_bounded_increase_ratio_,
+ &ignore_throughput_limit_if_network_estimate_},
+ key_value_config->Lookup("WebRTC-Bwe-EstimateBoundedIncrease"));
// E.g
// WebRTC-BweAimdRateControlConfig/initial_backoff_interval:100ms/
ParseFieldTrial({&initial_backoff_interval_, &link_capacity_fix_},
@@ -272,27 +273,34 @@
ChangeState(input, at_time);
- // We limit the new bitrate based on the troughput to avoid unlimited bitrate
- // increases. We allow a bit more lag at very low rates to not too easily get
- // stuck if the encoder produces uneven outputs.
- const DataRate troughput_based_limit =
- 1.5 * estimated_throughput + DataRate::KilobitsPerSec(10);
-
switch (rate_control_state_) {
case RateControlState::kRcHold:
break;
- case RateControlState::kRcIncrease:
+ case RateControlState::kRcIncrease: {
if (estimated_throughput > link_capacity_.UpperBound())
link_capacity_.Reset();
- // Do not increase the delay based estimate in alr since the estimator
- // will not be able to get transport feedback necessary to detect if
- // the new estimate is correct.
- // If we have previously increased above the limit (for instance due to
- // probing), we don't allow further changes.
- if (current_bitrate_ < troughput_based_limit &&
- !(send_side_ && in_alr_ && no_bitrate_increase_in_alr_)) {
+ // We limit the new bitrate based on the troughput to avoid unlimited
+ // bitrate increases. We allow a bit more lag at very low rates to not too
+ // easily get stuck if the encoder produces uneven outputs.
+ DataRate increase_limit =
+ 1.5 * estimated_throughput + DataRate::KilobitsPerSec(10);
+ if (ignore_throughput_limit_if_network_estimate_ && network_estimate_ &&
+ network_estimate_->link_capacity_upper.IsFinite()) {
+ // If we have a Network estimate, we do allow the estimate to increase.
+ increase_limit = network_estimate_->link_capacity_upper *
+ estimate_bounded_increase_ratio_.Get();
+ } else if (send_side_ && in_alr_ && no_bitrate_increase_in_alr_) {
+ // Do not increase the delay based estimate in alr since the estimator
+ // will not be able to get transport feedback necessary to detect if
+ // the new estimate is correct.
+ // If we have previously increased above the limit (for instance due to
+ // probing), we don't allow further changes.
+ increase_limit = current_bitrate_;
+ }
+
+ if (current_bitrate_ < increase_limit) {
DataRate increased_bitrate = DataRate::MinusInfinity();
if (link_capacity_.has_estimate()) {
// The link_capacity estimate is reset if the measured throughput
@@ -309,11 +317,11 @@
at_time, time_last_bitrate_change_, current_bitrate_);
increased_bitrate = current_bitrate_ + multiplicative_increase;
}
- new_bitrate = std::min(increased_bitrate, troughput_based_limit);
+ new_bitrate = std::min(increased_bitrate, increase_limit);
}
-
time_last_bitrate_change_ = at_time;
break;
+ }
case RateControlState::kRcDecrease: {
DataRate decreased_bitrate = DataRate::PlusInfinity();
@@ -368,8 +376,10 @@
}
DataRate AimdRateControl::ClampBitrate(DataRate new_bitrate) const {
- if (estimate_bounded_increase_ && network_estimate_) {
- DataRate upper_bound = network_estimate_->link_capacity_upper;
+ if (!disable_estimate_bounded_increase_ && network_estimate_ &&
+ 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);
}
new_bitrate = std::max(new_bitrate, min_configured_bitrate_);
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.h b/modules/remote_bitrate_estimator/aimd_rate_control.h
index 3e0d541..12dec32 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -107,9 +107,12 @@
// Use estimated link capacity lower bound if it is higher than the
// acknowledged rate when backing off due to overuse.
const bool estimate_bounded_backoff_;
- // Use estimated link capacity upper bound as upper limit for increasing
- // bitrate over the acknowledged rate.
- const bool estimate_bounded_increase_;
+ // If false, uses estimated link capacity upper bound *
+ // `estimate_bounded_increase_ratio_` as upper limit for the estimate.
+ FieldTrialFlag disable_estimate_bounded_increase_{"Disabled"};
+ FieldTrialParameter<double> estimate_bounded_increase_ratio_{"ratio", 1.0};
+ FieldTrialParameter<bool> ignore_throughput_limit_if_network_estimate_{
+ "ignore_acked", false};
absl::optional<DataRate> last_decrease_;
FieldTrialOptional<TimeDelta> initial_backoff_interval_;
FieldTrialFlag link_capacity_fix_;
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
index 6cbccf6..34aafb4 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
@@ -274,4 +274,72 @@
kInitialBitrateBps);
}
+TEST(AimdRateControlTest, EstimateNotLimitedByNetworkEstimateIfDisabled) {
+ test::ScopedFieldTrials override_field_trials(
+ "WebRTC-Bwe-EstimateBoundedIncrease/Disabled/");
+ auto states = CreateAimdRateControlStates(/*send_side=*/true);
+ constexpr int kInitialBitrateBps = 123000;
+ SetEstimate(states, kInitialBitrateBps);
+ states.aimd_rate_control->SetInApplicationLimitedRegion(false);
+ NetworkStateEstimate network_estimate;
+ network_estimate.link_capacity_upper = DataRate::KilobitsPerSec(150);
+ states.aimd_rate_control->SetNetworkStateEstimate(network_estimate);
+
+ for (int i = 0; i < 100; ++i) {
+ UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
+ states.simulated_clock->TimeInMilliseconds());
+ states.simulated_clock->AdvanceTimeMilliseconds(100);
+ }
+ EXPECT_GT(states.aimd_rate_control->LatestEstimate(),
+ network_estimate.link_capacity_upper);
+}
+
+TEST(AimdRateControlTest, EstimateLimitedByNetworkEstimateInAlrIfSet) {
+ // Even if alr is detected, the delay based estimator is allowed to increase
+ // up to a percentage of upper link capacity.
+ test::ScopedFieldTrials override_field_trials(
+ "WebRTC-Bwe-EstimateBoundedIncrease/ratio:0.85,ignore_acked:true/"
+ "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
+ auto states = CreateAimdRateControlStates(/*send_side=*/true);
+ constexpr int kInitialBitrateBps = 123000;
+ SetEstimate(states, kInitialBitrateBps);
+ states.aimd_rate_control->SetInApplicationLimitedRegion(true);
+
+ 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, absl::nullopt,
+ states.simulated_clock->TimeInMilliseconds());
+ states.simulated_clock->AdvanceTimeMilliseconds(100);
+ }
+ EXPECT_EQ(states.aimd_rate_control->LatestEstimate(),
+ network_estimate.link_capacity_upper * 0.85);
+}
+
+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
+ // is correct.
+ test::ScopedFieldTrials override_field_trials(
+ "WebRTC-Bwe-EstimateBoundedIncrease/ratio:0.85,ignore_acked:true/"
+ "WebRTC-DontIncreaseDelayBasedBweInAlr/Enabled/");
+ auto states = CreateAimdRateControlStates(/*send_side=*/true);
+ constexpr int kInitialBitrateBps = 123000;
+ SetEstimate(states, kInitialBitrateBps);
+ states.aimd_rate_control->SetInApplicationLimitedRegion(true);
+ UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
+ states.simulated_clock->TimeInMilliseconds());
+ ASSERT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
+ kInitialBitrateBps);
+
+ for (int i = 0; i < 100; ++i) {
+ UpdateRateControl(states, BandwidthUsage::kBwNormal, absl::nullopt,
+ states.simulated_clock->TimeInMilliseconds());
+ states.simulated_clock->AdvanceTimeMilliseconds(100);
+ }
+ EXPECT_EQ(states.aimd_rate_control->LatestEstimate().bps(),
+ kInitialBitrateBps);
+}
+
} // namespace webrtc