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