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

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

Powered by Google App Engine
This is Rietveld 408576698