| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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/bitrate_controller/send_side_bandwidth_estimation.h" | 11 #include "webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h" |
| 12 | 12 |
| 13 #include <cmath> | 13 #include <cmath> |
| 14 | 14 |
| 15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/system_wrappers/interface/field_trial.h" | 16 #include "webrtc/system_wrappers/interface/field_trial.h" |
| 17 #include "webrtc/system_wrappers/interface/logging.h" | 17 #include "webrtc/system_wrappers/interface/logging.h" |
| 18 #include "webrtc/system_wrappers/interface/metrics.h" | 18 #include "webrtc/system_wrappers/interface/metrics.h" |
| 19 | 19 |
| 20 namespace webrtc { | 20 namespace webrtc { |
| 21 namespace { | 21 namespace { |
| 22 const int64_t kBweIncreaseIntervalMs = 1000; | 22 const int64_t kBweIncreaseIntervalMs = 1000; |
| 23 const int64_t kBweDecreaseIntervalMs = 300; | 23 const int64_t kBweDecreaseIntervalMs = 300; |
| 24 const int64_t kStartPhaseMs = 2000; | 24 const int64_t kStartPhaseMs = 2000; |
| 25 const int64_t kBweConverganceTimeMs = 20000; | 25 const int64_t kBweConverganceTimeMs = 20000; |
| 26 const int kLimitNumPackets = 20; | 26 const int kLimitNumPackets = 20; |
| 27 const int kAvgPacketSizeBytes = 1000; | |
| 28 const int kDefaultMinBitrateBps = 10000; | 27 const int kDefaultMinBitrateBps = 10000; |
| 29 const int kDefaultMaxBitrateBps = 1000000000; | 28 const int kDefaultMaxBitrateBps = 1000000000; |
| 30 const int64_t kLowBitrateLogPeriodMs = 10000; | 29 const int64_t kLowBitrateLogPeriodMs = 10000; |
| 31 | 30 |
| 32 struct UmaRampUpMetric { | 31 struct UmaRampUpMetric { |
| 33 const char* metric_name; | 32 const char* metric_name; |
| 34 int bitrate_kbps; | 33 int bitrate_kbps; |
| 35 }; | 34 }; |
| 36 | 35 |
| 37 const UmaRampUpMetric kUmaRampupMetrics[] = { | 36 const UmaRampUpMetric kUmaRampupMetrics[] = { |
| 38 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, | 37 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, |
| 39 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, | 38 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, |
| 40 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; | 39 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; |
| 41 const size_t kNumUmaRampupMetrics = | 40 const size_t kNumUmaRampupMetrics = |
| 42 sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); | 41 sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); |
| 43 | 42 |
| 44 // Calculate the rate that TCP-Friendly Rate Control (TFRC) would apply. | |
| 45 // The formula in RFC 3448, Section 3.1, is used. | |
| 46 uint32_t CalcTfrcBps(int64_t rtt, uint8_t loss) { | |
| 47 if (rtt == 0 || loss == 0) { | |
| 48 // Input variables out of range. | |
| 49 return 0; | |
| 50 } | |
| 51 double R = static_cast<double>(rtt) / 1000; // RTT in seconds. | |
| 52 int b = 1; // Number of packets acknowledged by a single TCP acknowledgement: | |
| 53 // recommended = 1. | |
| 54 double t_RTO = 4.0 * R; // TCP retransmission timeout value in seconds | |
| 55 // recommended = 4*R. | |
| 56 double p = static_cast<double>(loss) / 255; // Packet loss rate in [0, 1). | |
| 57 double s = static_cast<double>(kAvgPacketSizeBytes); | |
| 58 | |
| 59 // Calculate send rate in bytes/second. | |
| 60 double X = | |
| 61 s / (R * std::sqrt(2 * b * p / 3) + | |
| 62 (t_RTO * (3 * std::sqrt(3 * b * p / 8) * p * (1 + 32 * p * p)))); | |
| 63 | |
| 64 // Convert to bits/second. | |
| 65 return (static_cast<uint32_t>(X * 8)); | |
| 66 } | |
| 67 } | 43 } |
| 68 | 44 |
| 69 SendSideBandwidthEstimation::SendSideBandwidthEstimation() | 45 SendSideBandwidthEstimation::SendSideBandwidthEstimation() |
| 70 : accumulate_lost_packets_Q8_(0), | 46 : accumulate_lost_packets_Q8_(0), |
| 71 accumulate_expected_packets_(0), | 47 accumulate_expected_packets_(0), |
| 72 bitrate_(0), | 48 bitrate_(0), |
| 73 min_bitrate_configured_(kDefaultMinBitrateBps), | 49 min_bitrate_configured_(kDefaultMinBitrateBps), |
| 74 max_bitrate_configured_(kDefaultMaxBitrateBps), | 50 max_bitrate_configured_(kDefaultMaxBitrateBps), |
| 75 last_low_bitrate_log_ms_(-1), | 51 last_low_bitrate_log_ms_(-1), |
| 76 time_last_receiver_block_ms_(0), | 52 time_last_receiver_block_ms_(0), |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 if ((now_ms - time_last_decrease_ms_) >= | 214 if ((now_ms - time_last_decrease_ms_) >= |
| 239 (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { | 215 (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { |
| 240 time_last_decrease_ms_ = now_ms; | 216 time_last_decrease_ms_ = now_ms; |
| 241 | 217 |
| 242 // Reduce rate: | 218 // Reduce rate: |
| 243 // newRate = rate * (1 - 0.5*lossRate); | 219 // newRate = rate * (1 - 0.5*lossRate); |
| 244 // where packetLoss = 256*lossRate; | 220 // where packetLoss = 256*lossRate; |
| 245 bitrate_ = static_cast<uint32_t>( | 221 bitrate_ = static_cast<uint32_t>( |
| 246 (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / | 222 (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / |
| 247 512.0); | 223 512.0); |
| 248 | |
| 249 // Calculate what rate TFRC would apply in this situation and to not | |
| 250 // reduce further than it. | |
| 251 bitrate_ = std::max( | |
| 252 bitrate_, | |
| 253 CalcTfrcBps(last_round_trip_time_ms_, last_fraction_loss_)); | |
| 254 } | 224 } |
| 255 } | 225 } |
| 256 } | 226 } |
| 257 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); | 227 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
| 258 } | 228 } |
| 259 | 229 |
| 260 bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const { | 230 bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const { |
| 261 return first_report_time_ms_ == -1 || | 231 return first_report_time_ms_ == -1 || |
| 262 now_ms - first_report_time_ms_ < kStartPhaseMs; | 232 now_ms - first_report_time_ms_ < kStartPhaseMs; |
| 263 } | 233 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 | 266 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 |
| 297 << " kbps is below configured min bitrate " | 267 << " kbps is below configured min bitrate " |
| 298 << min_bitrate_configured_ / 1000 << " kbps."; | 268 << min_bitrate_configured_ / 1000 << " kbps."; |
| 299 last_low_bitrate_log_ms_ = now_ms; | 269 last_low_bitrate_log_ms_ = now_ms; |
| 300 } | 270 } |
| 301 bitrate = min_bitrate_configured_; | 271 bitrate = min_bitrate_configured_; |
| 302 } | 272 } |
| 303 return bitrate; | 273 return bitrate; |
| 304 } | 274 } |
| 305 } // namespace webrtc | 275 } // namespace webrtc |
| OLD | NEW |