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

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: Redid the experiment settings initialization slightly and set the default threshold back to 12.5. 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 25
25 AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps) 26 AimdRateControl::AimdRateControl(uint32_t min_bitrate_bps)
26 : min_configured_bitrate_bps_(min_bitrate_bps), 27 : min_configured_bitrate_bps_(min_bitrate_bps),
27 max_configured_bitrate_bps_(30000000), 28 max_configured_bitrate_bps_(30000000),
28 current_bitrate_bps_(max_configured_bitrate_bps_), 29 current_bitrate_bps_(max_configured_bitrate_bps_),
29 max_hold_rate_bps_(0),
30 avg_max_bitrate_kbps_(-1.0f), 30 avg_max_bitrate_kbps_(-1.0f),
31 var_max_bitrate_kbps_(0.4f), 31 var_max_bitrate_kbps_(0.4f),
32 rate_control_state_(kRcHold), 32 rate_control_state_(kRcHold),
33 came_from_state_(kRcDecrease),
34 rate_control_region_(kRcMaxUnknown), 33 rate_control_region_(kRcMaxUnknown),
35 time_last_bitrate_change_(-1), 34 time_last_bitrate_change_(-1),
36 current_input_(kBwNormal, 0, 1.0), 35 current_input_(kBwNormal, 0, 1.0),
37 updated_(false), 36 updated_(false),
38 time_first_incoming_estimate_(-1), 37 time_first_incoming_estimate_(-1),
39 bitrate_is_initialized_(false), 38 bitrate_is_initialized_(false),
40 beta_(0.9f), 39 beta_(0.85f),
41 rtt_(kDefaultRttMs), 40 rtt_(kDefaultRttMs),
42 time_of_last_log_(-1) {} 41 time_of_last_log_(-1),
42 in_experiment_(AdaptiveThresholdExperimentIsEnabled()) {
43 }
43 44
44 RateControlType AimdRateControl::GetControlType() const { 45 RateControlType AimdRateControl::GetControlType() const {
45 return kAimdControl; 46 return kAimdControl;
46 } 47 }
47 48
48 uint32_t AimdRateControl::GetMinBitrate() const { 49 uint32_t AimdRateControl::GetMinBitrate() const {
49 return min_configured_bitrate_bps_; 50 return min_configured_bitrate_bps_;
50 } 51 }
51 52
52 bool AimdRateControl::ValidEstimate() const { 53 bool AimdRateControl::ValidEstimate() const {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 if (now_ms - time_of_last_log_ > kLogIntervalMs) { 92 if (now_ms - time_of_last_log_ > kLogIntervalMs) {
92 time_of_last_log_ = now_ms; 93 time_of_last_log_ = now_ms;
93 } 94 }
94 return current_bitrate_bps_; 95 return current_bitrate_bps_;
95 } 96 }
96 97
97 void AimdRateControl::SetRtt(int64_t rtt) { 98 void AimdRateControl::SetRtt(int64_t rtt) {
98 rtt_ = rtt; 99 rtt_ = rtt;
99 } 100 }
100 101
101 RateControlRegion AimdRateControl::Update(const RateControlInput* input, 102 void AimdRateControl::Update(const RateControlInput* input, int64_t now_ms) {
102 int64_t now_ms) {
103 assert(input); 103 assert(input);
104 104
105 // Set the initial bit rate value to what we're receiving the first half 105 // Set the initial bit rate value to what we're receiving the first half
106 // second. 106 // second.
107 if (!bitrate_is_initialized_) { 107 if (!bitrate_is_initialized_) {
108 if (time_first_incoming_estimate_ < 0) { 108 if (time_first_incoming_estimate_ < 0) {
109 if (input->_incomingBitRate > 0) { 109 if (input->_incomingBitRate > 0) {
110 time_first_incoming_estimate_ = now_ms; 110 time_first_incoming_estimate_ = now_ms;
111 } 111 }
112 } else if (now_ms - time_first_incoming_estimate_ > 500 && 112 } else if (now_ms - time_first_incoming_estimate_ > 500 &&
113 input->_incomingBitRate > 0) { 113 input->_incomingBitRate > 0) {
114 current_bitrate_bps_ = input->_incomingBitRate; 114 current_bitrate_bps_ = input->_incomingBitRate;
115 bitrate_is_initialized_ = true; 115 bitrate_is_initialized_ = true;
116 } 116 }
117 } 117 }
118 118
119 if (updated_ && current_input_._bwState == kBwOverusing) { 119 if (updated_ && current_input_._bwState == kBwOverusing) {
120 // Only update delay factor and incoming bit rate. We always want to react 120 // Only update delay factor and incoming bit rate. We always want to react
121 // on an over-use. 121 // on an over-use.
122 current_input_._noiseVar = input->_noiseVar; 122 current_input_._noiseVar = input->_noiseVar;
123 current_input_._incomingBitRate = input->_incomingBitRate; 123 current_input_._incomingBitRate = input->_incomingBitRate;
124 } else { 124 } else {
125 updated_ = true; 125 updated_ = true;
126 current_input_ = *input; 126 current_input_ = *input;
127 } 127 }
128 return rate_control_region_;
129 } 128 }
130 129
131 void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) { 130 void AimdRateControl::SetEstimate(int bitrate_bps, int64_t now_ms) {
132 updated_ = true; 131 updated_ = true;
133 bitrate_is_initialized_ = true; 132 bitrate_is_initialized_ = true;
134 current_bitrate_bps_ = ChangeBitrate(bitrate_bps, bitrate_bps, now_ms); 133 current_bitrate_bps_ = ChangeBitrate(bitrate_bps, bitrate_bps, now_ms);
135 } 134 }
136 135
137 uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps, 136 uint32_t AimdRateControl::ChangeBitrate(uint32_t current_bitrate_bps,
138 uint32_t incoming_bitrate_bps, 137 uint32_t incoming_bitrate_bps,
139 int64_t now_ms) { 138 int64_t now_ms) {
140 if (!updated_) { 139 if (!updated_) {
141 return current_bitrate_bps_; 140 return current_bitrate_bps_;
142 } 141 }
143 updated_ = false; 142 updated_ = false;
144 ChangeState(current_input_, now_ms); 143 ChangeState(current_input_, now_ms);
145 // Calculated here because it's used in multiple places. 144 // Calculated here because it's used in multiple places.
146 const float incoming_bitrate_kbps = incoming_bitrate_bps / 1000.0f; 145 const float incoming_bitrate_kbps = incoming_bitrate_bps / 1000.0f;
147 // Calculate the max bit rate std dev given the normalized 146 // Calculate the max bit rate std dev given the normalized
148 // variance and the current incoming bit rate. 147 // variance and the current incoming bit rate.
149 const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ * 148 const float std_max_bit_rate = sqrt(var_max_bitrate_kbps_ *
150 avg_max_bitrate_kbps_); 149 avg_max_bitrate_kbps_);
151 bool fast_recovery_after_hold = false;
152 switch (rate_control_state_) { 150 switch (rate_control_state_) {
153 case kRcHold: { 151 case kRcHold:
154 max_hold_rate_bps_ = std::max(max_hold_rate_bps_, incoming_bitrate_bps);
155 break; 152 break;
156 } 153
157 case kRcIncrease: { 154 case kRcIncrease:
158 if (avg_max_bitrate_kbps_ >= 0) { 155 if (avg_max_bitrate_kbps_ >= 0 &&
159 if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ + 156 incoming_bitrate_kbps >
160 3 * std_max_bit_rate) { 157 avg_max_bitrate_kbps_ + 3 * std_max_bit_rate) {
161 ChangeRegion(kRcMaxUnknown); 158 ChangeRegion(kRcMaxUnknown);
162 avg_max_bitrate_kbps_ = -1.0; 159 avg_max_bitrate_kbps_ = -1.0;
163 } else if (incoming_bitrate_kbps > avg_max_bitrate_kbps_ +
164 2.5 * std_max_bit_rate) {
165 ChangeRegion(kRcAboveMax);
166 }
167 } 160 }
168 if (rate_control_region_ == kRcNearMax) { 161 if (rate_control_region_ == kRcNearMax) {
169 // Approximate the over-use estimator delay to 100 ms. 162 // Approximate the over-use estimator delay to 100 ms.
170 const int64_t response_time = rtt_ + 100; 163 const int64_t response_time = rtt_ + 100;
171 uint32_t additive_increase_bps = AdditiveRateIncrease( 164 uint32_t additive_increase_bps = AdditiveRateIncrease(
172 now_ms, time_last_bitrate_change_, response_time); 165 now_ms, time_last_bitrate_change_, response_time);
173 current_bitrate_bps += additive_increase_bps; 166 current_bitrate_bps += additive_increase_bps;
174 167
175 } else { 168 } else {
176 uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease( 169 uint32_t multiplicative_increase_bps = MultiplicativeRateIncrease(
177 now_ms, time_last_bitrate_change_, current_bitrate_bps); 170 now_ms, time_last_bitrate_change_, current_bitrate_bps);
178 current_bitrate_bps += multiplicative_increase_bps; 171 current_bitrate_bps += multiplicative_increase_bps;
179 } 172 }
180 173
181 if (max_hold_rate_bps_ > 0 &&
182 beta_ * max_hold_rate_bps_ > current_bitrate_bps) {
183 current_bitrate_bps = static_cast<uint32_t>(beta_ * max_hold_rate_bps_);
184 avg_max_bitrate_kbps_ = beta_ * max_hold_rate_bps_ / 1000.0f;
185 ChangeRegion(kRcNearMax);
186 fast_recovery_after_hold = true;
187 }
188 max_hold_rate_bps_ = 0;
189 time_last_bitrate_change_ = now_ms; 174 time_last_bitrate_change_ = now_ms;
190 break; 175 break;
191 } 176
192 case kRcDecrease: { 177 case kRcDecrease:
193 if (incoming_bitrate_bps < min_configured_bitrate_bps_) { 178 if (incoming_bitrate_bps < min_configured_bitrate_bps_) {
194 current_bitrate_bps = min_configured_bitrate_bps_; 179 current_bitrate_bps = min_configured_bitrate_bps_;
195 } else { 180 } else {
196 // Set bit rate to something slightly lower than max 181 // Set bit rate to something slightly lower than max
197 // to get rid of any self-induced delay. 182 // to get rid of any self-induced delay.
198 current_bitrate_bps = static_cast<uint32_t>(beta_ * 183 current_bitrate_bps = static_cast<uint32_t>(beta_ *
199 incoming_bitrate_bps + 0.5); 184 incoming_bitrate_bps + 0.5);
200 if (current_bitrate_bps > current_bitrate_bps_) { 185 if (current_bitrate_bps > current_bitrate_bps_) {
201 // Avoid increasing the rate when over-using. 186 // Avoid increasing the rate when over-using.
202 if (rate_control_region_ != kRcMaxUnknown) { 187 if (rate_control_region_ != kRcMaxUnknown) {
203 current_bitrate_bps = static_cast<uint32_t>( 188 current_bitrate_bps = static_cast<uint32_t>(
204 beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f); 189 beta_ * avg_max_bitrate_kbps_ * 1000 + 0.5f);
205 } 190 }
206 current_bitrate_bps = std::min(current_bitrate_bps, 191 current_bitrate_bps = std::min(current_bitrate_bps,
207 current_bitrate_bps_); 192 current_bitrate_bps_);
208 } 193 }
209 ChangeRegion(kRcNearMax); 194 ChangeRegion(kRcNearMax);
210 195
211 if (incoming_bitrate_kbps < avg_max_bitrate_kbps_ - 196 if (incoming_bitrate_kbps < avg_max_bitrate_kbps_ -
212 3 * std_max_bit_rate) { 197 3 * std_max_bit_rate) {
213 avg_max_bitrate_kbps_ = -1.0f; 198 avg_max_bitrate_kbps_ = -1.0f;
214 } 199 }
215 200
216 UpdateMaxBitRateEstimate(incoming_bitrate_kbps); 201 UpdateMaxBitRateEstimate(incoming_bitrate_kbps);
217 } 202 }
218 // Stay on hold until the pipes are cleared. 203 // Stay on hold until the pipes are cleared.
219 ChangeState(kRcHold); 204 ChangeState(kRcHold);
220 time_last_bitrate_change_ = now_ms; 205 time_last_bitrate_change_ = now_ms;
221 break; 206 break;
222 } 207
223 default: 208 default:
224 assert(false); 209 assert(false);
225 } 210 }
226 if (!fast_recovery_after_hold && (incoming_bitrate_bps > 100000 || 211 if ((incoming_bitrate_bps > 100000 || current_bitrate_bps > 150000) &&
227 current_bitrate_bps > 150000) &&
228 current_bitrate_bps > 1.5 * incoming_bitrate_bps) { 212 current_bitrate_bps > 1.5 * incoming_bitrate_bps) {
229 // Allow changing the bit rate if we are operating at very low rates 213 // Allow changing the bit rate if we are operating at very low rates
230 // Don't change the bit rate if the send side is too far off 214 // Don't change the bit rate if the send side is too far off
231 current_bitrate_bps = current_bitrate_bps_; 215 current_bitrate_bps = current_bitrate_bps_;
232 time_last_bitrate_change_ = now_ms; 216 time_last_bitrate_change_ = now_ms;
233 } 217 }
234 return current_bitrate_bps; 218 return current_bitrate_bps;
235 } 219 }
236 220
237 uint32_t AimdRateControl::MultiplicativeRateIncrease( 221 uint32_t AimdRateControl::MultiplicativeRateIncrease(
238 int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const { 222 int64_t now_ms, int64_t last_ms, uint32_t current_bitrate_bps) const {
239 double alpha = 1.08; 223 double alpha = 1.08;
240 if (last_ms > -1) { 224 if (last_ms > -1) {
241 int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms), 225 int time_since_last_update_ms = std::min(static_cast<int>(now_ms - last_ms),
242 1000); 226 1000);
243 alpha = pow(alpha, time_since_last_update_ms / 1000.0); 227 alpha = pow(alpha, time_since_last_update_ms / 1000.0);
244 } 228 }
245 uint32_t multiplicative_increase_bps = std::max( 229 uint32_t multiplicative_increase_bps = std::max(
246 current_bitrate_bps * (alpha - 1.0), 1000.0); 230 current_bitrate_bps * (alpha - 1.0), 1000.0);
247 return multiplicative_increase_bps; 231 return multiplicative_increase_bps;
248 } 232 }
249 233
250 uint32_t AimdRateControl::AdditiveRateIncrease( 234 uint32_t AimdRateControl::AdditiveRateIncrease(
251 int64_t now_ms, int64_t last_ms, int64_t response_time_ms) const { 235 int64_t now_ms, int64_t last_ms, int64_t response_time_ms) const {
252 assert(response_time_ms > 0); 236 assert(response_time_ms > 0);
253 double beta = 0.0; 237 double beta = 0.0;
254 if (last_ms > 0) { 238 if (last_ms > 0) {
255 beta = std::min((now_ms - last_ms) / 239 beta = std::min((now_ms - last_ms) / static_cast<double>(response_time_ms),
256 static_cast<double>(response_time_ms), 1.0); 240 1.0);
241 if (in_experiment_)
242 beta /= 2.0;
257 } 243 }
258 double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0; 244 double bits_per_frame = static_cast<double>(current_bitrate_bps_) / 30.0;
259 double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0)); 245 double packets_per_frame = std::ceil(bits_per_frame / (8.0 * 1200.0));
260 double avg_packet_size_bits = bits_per_frame / packets_per_frame; 246 double avg_packet_size_bits = bits_per_frame / packets_per_frame;
261 uint32_t additive_increase_bps = std::max( 247 uint32_t additive_increase_bps = std::max(
262 1000.0, beta * avg_packet_size_bits); 248 1000.0, beta * avg_packet_size_bits);
263 return additive_increase_bps; 249 return additive_increase_bps;
264 } 250 }
265 251
266 void AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) { 252 void AimdRateControl::UpdateMaxBitRateEstimate(float incoming_bitrate_kbps) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 case kBwUnderusing: 290 case kBwUnderusing:
305 ChangeState(kRcHold); 291 ChangeState(kRcHold);
306 break; 292 break;
307 default: 293 default:
308 assert(false); 294 assert(false);
309 } 295 }
310 } 296 }
311 297
312 void AimdRateControl::ChangeRegion(RateControlRegion region) { 298 void AimdRateControl::ChangeRegion(RateControlRegion region) {
313 rate_control_region_ = region; 299 rate_control_region_ = region;
314 switch (rate_control_region_) {
315 case kRcAboveMax:
316 case kRcMaxUnknown:
317 beta_ = 0.9f;
318 break;
319 case kRcNearMax:
320 beta_ = 0.95f;
321 break;
322 default:
323 assert(false);
324 }
325 } 300 }
326 301
327 void AimdRateControl::ChangeState(RateControlState new_state) { 302 void AimdRateControl::ChangeState(RateControlState new_state) {
328 came_from_state_ = rate_control_state_;
329 rate_control_state_ = new_state; 303 rate_control_state_ = new_state;
330 } 304 }
331 } // namespace webrtc 305 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698