Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: webrtc/modules/remote_bitrate_estimator/aimd_rate_control.cc

Issue 1151603008: Make the BWE threshold adaptive. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix string length issue. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h" 11 #include "webrtc/modules/remote_bitrate_estimator/aimd_rate_control.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <cassert> 14 #include <cassert>
15 #include <cmath> 15 #include <cmath>
16 16
17 #include "webrtc/modules/remote_bitrate_estimator/overuse_detector.h"
17 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h" 18 #include "webrtc/modules/remote_bitrate_estimator/test/bwe_test_logging.h"
18 19
19 namespace webrtc { 20 namespace webrtc {
20 21
21 static const int64_t kDefaultRttMs = 200; 22 static const int64_t kDefaultRttMs = 200;
22 static const int64_t kLogIntervalMs = 1000; 23 static const int64_t kLogIntervalMs = 1000;
23 static const double kWithinIncomingBitrateHysteresis = 1.05; 24 static const double kWithinIncomingBitrateHysteresis = 1.05;
24 static const int64_t kMaxFeedbackIntervalMs = 1000; 25 static const int64_t kMaxFeedbackIntervalMs = 1000;
25 26
26 AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps) 27 AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
27 : min_configured_bitrate_bps_(min_bitrate_bps), 28 : min_configured_bitrate_bps_(min_bitrate_bps),
28 max_configured_bitrate_bps_(30000000), 29 max_configured_bitrate_bps_(30000000),
29 current_bitrate_bps_(max_configured_bitrate_bps_), 30 current_bitrate_bps_(max_configured_bitrate_bps_),
30 max_hold_rate_bps_(0),
31 avg_max_bitrate_kbps_(-1.0f), 31 avg_max_bitrate_kbps_(-1.0f),
32 var_max_bitrate_kbps_(0.4f), 32 var_max_bitrate_kbps_(0.4f),
33 rate_control_state_(kRcHold), 33 rate_control_state_(kRcHold),
34 came_from_state_(kRcDecrease),
35 rate_control_region_(kRcMaxUnknown), 34 rate_control_region_(kRcMaxUnknown),
36 time_last_bitrate_change_(-1), 35 time_last_bitrate_change_(-1),
37 current_input_(kBwNormal, 0, 1.0), 36 current_input_(kBwNormal, 0, 1.0),
38 updated_(false), 37 updated_(false),
39 time_first_incoming_estimate_(-1), 38 time_first_incoming_estimate_(-1),
40 bitrate_is_initialized_(false), 39 bitrate_is_initialized_(false),
41 beta_(0.9f), 40 beta_(0.85f),
42 rtt_(kDefaultRttMs), 41 rtt_(kDefaultRttMs),
43 time_of_last_log_(-1) {} 42 time_of_last_log_(-1),
43 in_experiment_(AdaptiveThresholdExperimentIsEnabled()) {
44 }
44 45
45 uint32_t AimdRateControl::GetMinBitrate() const { 46 uint32_t AimdRateControl::GetMinBitrate() const {
46 return min_configured_bitrate_bps_; 47 return min_configured_bitrate_bps_;
47 } 48 }
48 49
49 bool AimdRateControl::ValidEstimate() const { 50 bool AimdRateControl::ValidEstimate() const {
50 return bitrate_is_initialized_; 51 return bitrate_is_initialized_;
51 } 52 }
52 53
53 int64_t AimdRateControl::GetFeedbackInterval() const { 54 int64_t AimdRateControl::GetFeedbackInterval() const {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 if (now_ms - time_of_last_log_ > kLogIntervalMs) { 89 if (now_ms - time_of_last_log_ > kLogIntervalMs) {
89 time_of_last_log_ = now_ms; 90 time_of_last_log_ = now_ms;
90 } 91 }
91 return current_bitrate_bps_; 92 return current_bitrate_bps_;
92 } 93 }
93 94
94 void AimdRateControl::SetRtt(int64_t rtt) { 95 void AimdRateControl::SetRtt(int64_t rtt) {
95 rtt_ = rtt; 96 rtt_ = rtt;
96 } 97 }
97 98
98 RateControlRegion AimdRateControl::Update(const RateControlInput* input, 99 void AimdRateControl::Update(const RateControlInput* input, int64_t now_ms) {
99 int64_t now_ms) {
100 assert(input); 100 assert(input);
101 101
102 // Set the initial bit rate value to what we're receiving the first half 102 // Set the initial bit rate value to what we're receiving the first half
103 // second. 103 // second.
104 if (!bitrate_is_initialized_) { 104 if (!bitrate_is_initialized_) {
105 if (time_first_incoming_estimate_ < 0) { 105 if (time_first_incoming_estimate_ < 0) {
106 if (input->_incomingBitRate > 0) { 106 if (input->_incomingBitRate > 0) {
107 time_first_incoming_estimate_ = now_ms; 107 time_first_incoming_estimate_ = now_ms;
108 } 108 }
109 } else if (now_ms - time_first_incoming_estimate_ > 500 && 109 } else if (now_ms - time_first_incoming_estimate_ > 500 &&
110 input->_incomingBitRate > 0) { 110 input->_incomingBitRate > 0) {
111 current_bitrate_bps_ = input->_incomingBitRate; 111 current_bitrate_bps_ = input->_incomingBitRate;
112 bitrate_is_initialized_ = true; 112 bitrate_is_initialized_ = true;
113 } 113 }
114 } 114 }
115 115
116 if (updated_ && current_input_._bwState == kBwOverusing) { 116 if (updated_ && current_input_._bwState == kBwOverusing) {
117 // Only update delay factor and incoming bit rate. We always want to react 117 // Only update delay factor and incoming bit rate. We always want to react
118 // on an over-use. 118 // on an over-use.
119 current_input_._noiseVar = input->_noiseVar; 119 current_input_._noiseVar = input->_noiseVar;
120 current_input_._incomingBitRate = input->_incomingBitRate; 120 current_input_._incomingBitRate = input->_incomingBitRate;
121 } else { 121 } else {
122 updated_ = true; 122 updated_ = true;
123 current_input_ = *input; 123 current_input_ = *input;
124 } 124 }
125 return rate_control_region_;
126 } 125 }
127 126
128 void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) { 127 void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
129 updated_ = true; 128 updated_ = true;
130 bitrate_is_initialized_ = true; 129 bitrate_is_initialized_ = true;
131 current_bitrate_bps_ = ChangeBitrate(bitrate_bps, bitrate_bps, now_ms); 130 current_bitrate_bps_ = ChangeBitrate(bitrate_bps, bitrate_bps, now_ms);
132 } 131 }
133 132
134 uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps, 133 uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps,
135 uint32_t incoming_bitrate_bps, 134 uint32_t incoming_bitrate_bps,
136 int64_t now_ms) { 135 int64_t now_ms) {
137 if (!updated_) { 136 if (!updated_) {
138 return current_bitrate_bps_; 137 return current_bitrate_bps_;
139 } 138 }
140 updated_ = false; 139 updated_ = false;
141 ChangeState(current_input_, now_ms); 140 ChangeState(current_input_, now_ms);
142 // Calculated here because it's used in multiple places. 141 // Calculated here because it's used in multiple places.
143 const float incoming_bitrate_kbps = incoming_bitrate_bps / 1000.0f; 142 const float incoming_bitrate_kbps = incoming_bitrate_bps / 1000.0f;
144 // Calculate the max bit rate std dev given the normalized 143 // Calculate the max bit rate std dev given the normalized
145 // variance and the current incoming bit rate. 144 // variance and the current incoming bit rate.
146 const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ * 145 const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ *
147 avg_max_bitrate_kbps_); 146 avg_max_bitrate_kbps_);
148 bool fast_recovery_after_hold = false;
149 switch (rate_control_state_) { 147 switch (rate_control_state_) {
150 case kRcHold: { 148 case kRcHold:
151 max_hold_rate_bps_ = std::max(max_hold_rate_bps_, incoming_bitrate_bps);
152 break; 149 break;
153 } 150
154 case kRcIncrease: { 151 case kRcIncrease:
155 if (avg_max_bitrate_kbps_ >= 0) { 152 if (avg_max_bitrate_kbps_ >= 0 &&
156 if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ + 153 incoming_bitrate_kbps >
157 3 * std_max_bit_rate) { 154 avg_max_bitrate_kbps_ + 3 * std_max_bit_rate) {
158 ChangeRegion(kRcMaxUnknown); 155 ChangeRegion(kRcMaxUnknown);
159 avg_max_bitrate_kbps_ = -1.0; 156 avg_max_bitrate_kbps_ = -1.0;
160 } else if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ +
161 2.5 * std_max_bit_rate) {
162 ChangeRegion(kRcAboveMax);
163 }
164 } 157 }
165 if (rate_control_region_ == kRcNearMax) { 158 if (rate_control_region_ == kRcNearMax) {
166 // Approximate the over-use estimator delay to 100 ms. 159 // Approximate the over-use estimator delay to 100 ms.
167 const int64_t response_time = rtt_ + 100; 160 const int64_t response_time = rtt_ + 100;
168 uint32_t additive_increase_bps = AdditiveRateIncrease( 161 uint32_t additive_increase_bps = AdditiveRateIncrease(
169 now_ms, time_last_bitrate_change_, response_time); 162 now_ms, time_last_bitrate_change_, response_time);
170 current_bitrate_bps += additive_increase_bps; 163 current_bitrate_bps += additive_increase_bps;
171 164
172 } else { 165 } else {
173 uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease( 166 uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease(
174 now_ms, time_last_bitrate_change_, current_bitrate_bps); 167 now_ms, time_last_bitrate_change_, current_bitrate_bps);
175 current_bitrate_bps += multiplicative_increase_bps; 168 current_bitrate_bps += multiplicative_increase_bps;
176 } 169 }
177 170
178 if (max_hold_rate_bps_ > 0 &&
179 beta_ * max_hold_rate_bps_ > current_bitrate_bps) {
180 current_bitrate_bps = static_cast<uint32_t>(beta_ * max_hold_rate_bps_);
181 avg_max_bitrate_kbps_ = beta_ * max_hold_rate_bps_ / 1000.0f;
182 ChangeRegion(kRcNearMax);
183 fast_recovery_after_hold = true;
184 }
185 max_hold_rate_bps_ = 0;
186 time_last_bitrate_change_ = now_ms; 171 time_last_bitrate_change_ = now_ms;
187 break; 172 break;
188 } 173
189 case kRcDecrease: { 174 case kRcDecrease:
190 if (incoming_bitrate_bps < min_configured_bitrate_bps_) { 175 if (incoming_bitrate_bps < min_configured_bitrate_bps_) {
191 current_bitrate_bps = min_configured_bitrate_bps_; 176 current_bitrate_bps = min_configured_bitrate_bps_;
192 } else { 177 } else {
193 // Set bit rate to something slightly lower than max 178 // Set bit rate to something slightly lower than max
194 // to get rid of any self-induced delay. 179 // to get rid of any self-induced delay.
195 current_bitrate_bps = static_cast<uint32_t>(beta_ * 180 current_bitrate_bps = static_cast<uint32_t>(beta_ *
196 incoming_bitrate_bps + 0.5); 181 incoming_bitrate_bps + 0.5);
197 if (current_bitrate_bps > current_bitrate_bps_) { 182 if (current_bitrate_bps > current_bitrate_bps_) {
198 // Avoid increasing the rate when over-using. 183 // Avoid increasing the rate when over-using.
199 if (rate_control_region_ != kRcMaxUnknown) { 184 if (rate_control_region_ != kRcMaxUnknown) {
200 current_bitrate_bps = static_cast<uint32_t>( 185 current_bitrate_bps = static_cast<uint32_t>(
201 beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f); 186 beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f);
202 } 187 }
203 current_bitrate_bps = std::min(current_bitrate_bps, 188 current_bitrate_bps = std::min(current_bitrate_bps,
204 current_bitrate_bps_); 189 current_bitrate_bps_);
205 } 190 }
206 ChangeRegion(kRcNearMax); 191 ChangeRegion(kRcNearMax);
207 192
208 if (incoming_bitrate_kbps < avg_max_bitrate_kbps_ - 193 if (incoming_bitrate_kbps < avg_max_bitrate_kbps_ -
209 3 * std_max_bit_rate) { 194 3 * std_max_bit_rate) {
210 avg_max_bitrate_kbps_ = -1.0f; 195 avg_max_bitrate_kbps_ = -1.0f;
211 } 196 }
212 197
213 UpdateMaxBitRateEstimate(incoming_bitrate_kbps); 198 UpdateMaxBitRateEstimate(incoming_bitrate_kbps);
214 } 199 }
215 // Stay on hold until the pipes are cleared. 200 // Stay on hold until the pipes are cleared.
216 ChangeState(kRcHold); 201 ChangeState(kRcHold);
217 time_last_bitrate_change_ = now_ms; 202 time_last_bitrate_change_ = now_ms;
218 break; 203 break;
219 } 204
220 default: 205 default:
221 assert(false); 206 assert(false);
222 } 207 }
223 if (!fast_recovery_after_hold && (incoming_bitrate_bps > 100000 || 208 if ((incoming_bitrate_bps > 100000 || current_bitrate_bps > 150000) &&
224 current_bitrate_bps > 150000) &&
225 current_bitrate_bps > 1.5 * incoming_bitrate_bps) { 209 current_bitrate_bps > 1.5 * incoming_bitrate_bps) {
226 // Allow changing the bit rate if we are operating at very low rates 210 // Allow changing the bit rate if we are operating at very low rates
227 // Don't change the bit rate if the send side is too far off 211 // Don't change the bit rate if the send side is too far off
228 current_bitrate_bps = current_bitrate_bps_; 212 current_bitrate_bps = current_bitrate_bps_;
229 time_last_bitrate_change_ = now_ms; 213 time_last_bitrate_change_ = now_ms;
230 } 214 }
231 return current_bitrate_bps; 215 return current_bitrate_bps;
232 } 216 }
233 217
234 uint32_t AimdRateControl::MultiplicativeRateIncrease( 218 uint32_t AimdRateControl::MultiplicativeRateIncrease(
235 int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const { 219 int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const {
236 double alpha = 1.08; 220 double alpha = 1.08;
237 if (last_ms > -1) { 221 if (last_ms > -1) {
238 int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms), 222 int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms),
239 1000); 223 1000);
240 alpha = pow(alpha, time_since_last_update_ms / 1000.0); 224 alpha = pow(alpha, time_since_last_update_ms / 1000.0);
241 } 225 }
242 uint32_t multiplicative_increase_bps = std::max( 226 uint32_t multiplicative_increase_bps = std::max(
243 current_bitrate_bps * (alpha - 1.0), 1000.0); 227 current_bitrate_bps * (alpha - 1.0), 1000.0);
244 return multiplicative_increase_bps; 228 return multiplicative_increase_bps;
245 } 229 }
246 230
247 uint32_t AimdRateControl::AdditiveRateIncrease( 231 uint32_t AimdRateControl::AdditiveRateIncrease(
248 int64_t now_ms, int64_t last_ms, int64_t response_time_ms) const { 232 int64_t now_ms, int64_t last_ms, int64_t response_time_ms) const {
249 assert(response_time_ms > 0); 233 assert(response_time_ms > 0);
250 double beta = 0.0; 234 double beta = 0.0;
251 if (last_ms > 0) { 235 if (last_ms > 0) {
252 beta = std::min((now_ms - last_ms) / 236 beta = std::min((now_ms - last_ms) / static_cast<double>(response_time_ms),
253 static_cast<double>(response_time_ms), 1.0); 237 1.0);
238 if (in_experiment_)
239 beta /= 2.0;
254 } 240 }
255 double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0; 241 double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0;
256 double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0)); 242 double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0));
257 double avg_packet_size_bits = bits_per_frame / packets_per_frame; 243 double avg_packet_size_bits = bits_per_frame / packets_per_frame;
258 uint32_t additive_increase_bps = std::max( 244 uint32_t additive_increase_bps = std::max(
259 1000.0, beta * avg_packet_size_bits); 245 1000.0, beta * avg_packet_size_bits);
260 return additive_increase_bps; 246 return additive_increase_bps;
261 } 247 }
262 248
263 void AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) { 249 void AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 case kBwUnderusing: 287 case kBwUnderusing:
302 ChangeState(kRcHold); 288 ChangeState(kRcHold);
303 break; 289 break;
304 default: 290 default:
305 assert(false); 291 assert(false);
306 } 292 }
307 } 293 }
308 294
309 void AimdRateControl::ChangeRegion(RateControlRegion region) { 295 void AimdRateControl::ChangeRegion(RateControlRegion region) {
310 rate_control_region_ = region; 296 rate_control_region_ = region;
311 switch (rate_control_region_) {
312 case kRcAboveMax:
313 case kRcMaxUnknown:
314 beta_ = 0.9f;
315 break;
316 case kRcNearMax:
317 beta_ = 0.95f;
318 break;
319 default:
320 assert(false);
321 }
322 } 297 }
323 298
324 void AimdRateControl::ChangeState(RateControlState new_state) { 299 void AimdRateControl::ChangeState(RateControlState new_state) {
325 came_from_state_ = rate_control_state_;
326 rate_control_state_ = new_state; 300 rate_control_state_ = new_state;
327 } 301 }
328 } // namespace webrtc 302 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698