OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |