Ensure that loss based BWE can switch to kIncreasing state when it wants to increase.
Increasing BWE by 1kbps should be safe/no-op in practice, and it ensures that padding in kIncreasing state will be triggered.
Bug: webrtc:12707
Change-Id: I82493d07a80abd60c93d9cff74baf0a55e77f2b7
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/325286
Commit-Queue: Diep Bui <diepbp@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41046}
diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
index e26fcc6..ab8fbc2 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc
@@ -294,6 +294,15 @@
std::min(best_candidate.loss_limited_bandwidth,
config_->bandwidth_rampup_upper_bound_factor *
(*acknowledged_bitrate_)));
+ // Increase current estimate by at least 1kbps to make sure that the state
+ // will be switched to kIncreasing, thus padding is triggered.
+ if (loss_based_result_.state == LossBasedState::kDecreasing &&
+ best_candidate.loss_limited_bandwidth ==
+ current_best_estimate_.loss_limited_bandwidth) {
+ best_candidate.loss_limited_bandwidth =
+ current_best_estimate_.loss_limited_bandwidth +
+ DataRate::KilobitsPerSec(1);
+ }
}
}
diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc
index 347e2a8..771db63 100644
--- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc
+++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc
@@ -795,7 +795,7 @@
// The estimate is capped by acked_bitrate * BwRampupUpperBoundFactor.
EXPECT_EQ(result.bandwidth_estimate, estimate_1 * 0.9 * 1.2);
- // But if acked bitrate decrease, BWE does not decrease when there is no
+ // But if acked bitrate decreases, BWE does not decrease when there is no
// loss.
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(estimate_1 * 0.9);
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
@@ -809,6 +809,54 @@
result.bandwidth_estimate);
}
+// Ensure that the state can switch to kIncrease even when the bandwidth is
+// bounded by acked bitrate.
+TEST_F(LossBasedBweV2Test, EnsureIncreaseEvenIfAckedBitrateBound) {
+ ExplicitKeyValueConfig key_value_config(ShortObservationConfig(
+ "LossThresholdOfHighBandwidthPreference:0.99,"
+ "BwRampupUpperBoundFactor:1.2,"
+ // Set InstantUpperBoundBwBalance high to disable InstantUpperBound cap.
+ "InstantUpperBoundBwBalance:10000kbps,"));
+ std::vector<PacketResult> enough_feedback_1 =
+ CreatePacketResultsWith100pLossRate(
+ /*first_packet_timestamp=*/Timestamp::Zero());
+ LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
+ DataRate delay_based_estimate = DataRate::KilobitsPerSec(5000);
+
+ loss_based_bandwidth_estimator.SetBandwidthEstimate(
+ DataRate::KilobitsPerSec(600));
+ loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
+ DataRate::KilobitsPerSec(300));
+ loss_based_bandwidth_estimator.UpdateBandwidthEstimate(enough_feedback_1,
+ delay_based_estimate,
+ /*in_alr=*/false);
+ ASSERT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
+ LossBasedState::kDecreasing);
+ LossBasedBweV2::Result result =
+ loss_based_bandwidth_estimator.GetLossBasedResult();
+ DataRate estimate_1 = result.bandwidth_estimate;
+ ASSERT_LT(estimate_1.kbps(), 600);
+
+ // Set a low acked bitrate.
+ loss_based_bandwidth_estimator.SetAcknowledgedBitrate(estimate_1 / 2);
+
+ int feedback_count = 1;
+ while (feedback_count < 5 && result.state != LossBasedState::kIncreasing) {
+ loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
+ CreatePacketResultsWithReceivedPackets(
+ /*first_packet_timestamp=*/Timestamp::Zero() +
+ feedback_count++ * kObservationDurationLowerBound),
+ delay_based_estimate,
+ /*in_alr=*/false);
+ result = loss_based_bandwidth_estimator.GetLossBasedResult();
+ }
+
+ ASSERT_EQ(result.state, LossBasedState::kIncreasing);
+ // The estimate increases by 1kbps.
+ EXPECT_EQ(result.bandwidth_estimate,
+ estimate_1 + DataRate::KilobitsPerSec(1));
+}
+
// After loss based bwe backs off, the estimate is bounded during the delayed
// window.
TEST_F(LossBasedBweV2Test,