Fix increase in send rate when not receiving feedback
Store the last known throughput estimate and use that if we're lacking a new measurement.
Bug: webrtc:9363
Change-Id: Ib7a9a495b446bd0f5799382cc095ccff894e0c2b
Reviewed-on: https://webrtc-review.googlesource.com/81749
Commit-Queue: Anastasia Koloskova <koloskova@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23565}
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.cc b/modules/remote_bitrate_estimator/aimd_rate_control.cc
index 19bfbb9..52a41e4 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.cc
@@ -58,6 +58,7 @@
: min_configured_bitrate_bps_(congestion_controller::GetMinBitrateBps()),
max_configured_bitrate_bps_(30000000),
current_bitrate_bps_(max_configured_bitrate_bps_),
+ latest_incoming_bitrate_bps_(current_bitrate_bps_),
avg_max_bitrate_kbps_(-1.0f),
var_max_bitrate_kbps_(0.4f),
rate_control_state_(kRcHold),
@@ -79,6 +80,7 @@
void AimdRateControl::SetStartBitrate(int start_bitrate_bps) {
current_bitrate_bps_ = start_bitrate_bps;
+ latest_incoming_bitrate_bps_ = current_bitrate_bps_;
bitrate_is_initialized_ = true;
}
@@ -132,6 +134,7 @@
// Set the initial bit rate value to what we're receiving the first half
// second.
+ // TODO(bugs.webrtc.org/9379): The comment above doesn't match to the code.
if (!bitrate_is_initialized_) {
const int64_t kInitializationTimeMs = 5000;
RTC_DCHECK_LE(kBitrateWindowMs, kInitializationTimeMs);
@@ -187,7 +190,9 @@
const RateControlInput& input,
int64_t now_ms) {
uint32_t incoming_bitrate_bps =
- input.incoming_bitrate.value_or(current_bitrate_bps_);
+ input.incoming_bitrate.value_or(latest_incoming_bitrate_bps_);
+ if (input.incoming_bitrate)
+ latest_incoming_bitrate_bps_ = *input.incoming_bitrate;
// An over-use should always trigger us to reduce the bitrate, even though
// we have not yet established our first estimate. By acting on the over-use,
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control.h b/modules/remote_bitrate_estimator/aimd_rate_control.h
index a9ecb67..9791c1d4 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control.h
+++ b/modules/remote_bitrate_estimator/aimd_rate_control.h
@@ -75,6 +75,7 @@
uint32_t min_configured_bitrate_bps_;
uint32_t max_configured_bitrate_bps_;
uint32_t current_bitrate_bps_;
+ uint32_t latest_incoming_bitrate_bps_;
float avg_max_bitrate_kbps_;
float var_max_bitrate_kbps_;
RateControlState rate_control_state_;
diff --git a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
index f6844b0..de88682 100644
--- a/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
+++ b/modules/remote_bitrate_estimator/aimd_rate_control_unittest.cc
@@ -43,7 +43,7 @@
void UpdateRateControl(const AimdRateControlStates& states,
const BandwidthUsage& bandwidth_usage,
- int bitrate,
+ rtc::Optional<uint32_t> bitrate,
int64_t now_ms) {
RateControlInput input(bandwidth_usage, bitrate, now_ms);
states.aimd_rate_control->Update(&input, now_ms);
@@ -247,4 +247,26 @@
states.aimd_rate_control->GetExpectedBandwidthPeriodMs());
}
+TEST(AimdRateControlTest, SendingRateBoundedWhenThroughputNotEstimated) {
+ auto states = CreateAimdRateControlStates();
+ constexpr int kInitialBitrateBps = 123000;
+ UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
+ states.simulated_clock->TimeInMilliseconds());
+ // AimdRateControl sets the initial bit rate to what it receives after
+ // five seconds has passed.
+ // TODO(bugs.webrtc.org/9379): The comment in the AimdRateControl does not
+ // match the constant.
+ constexpr int kInitializationTimeMs = 5000;
+ states.simulated_clock->AdvanceTimeMilliseconds(kInitializationTimeMs + 1);
+ UpdateRateControl(states, BandwidthUsage::kBwNormal, kInitialBitrateBps,
+ states.simulated_clock->TimeInMilliseconds());
+ for (int i = 0; i < 100; ++i) {
+ UpdateRateControl(states, BandwidthUsage::kBwNormal, rtc::nullopt,
+ states.simulated_clock->TimeInMilliseconds());
+ states.simulated_clock->AdvanceTimeMilliseconds(100);
+ }
+ EXPECT_LE(states.aimd_rate_control->LatestEstimate(),
+ kInitialBitrateBps * 1.5 + 10000);
+}
+
} // namespace webrtc