Chromium Code Reviews| 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 |