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 |