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; | 27 const int kAvgPacketSizeBytes = 1000; |
28 const int kDefaultMinBitrateBps = 10000; | 28 const int kDefaultMinBitrateBps = 10000; |
29 const int kDefaultMaxBitrateBps = 1000000000; | 29 const int kDefaultMaxBitrateBps = 1000000000; |
| 30 const int64_t kLowBitrateLogPeriodMs = 10000; |
30 | 31 |
31 struct UmaRampUpMetric { | 32 struct UmaRampUpMetric { |
32 const char* metric_name; | 33 const char* metric_name; |
33 int bitrate_kbps; | 34 int bitrate_kbps; |
34 }; | 35 }; |
35 | 36 |
36 const UmaRampUpMetric kUmaRampupMetrics[] = { | 37 const UmaRampUpMetric kUmaRampupMetrics[] = { |
37 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, | 38 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, |
38 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, | 39 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, |
39 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; | 40 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; |
(...skipping 24 matching lines...) Expand all Loading... |
64 return (static_cast<uint32_t>(X * 8)); | 65 return (static_cast<uint32_t>(X * 8)); |
65 } | 66 } |
66 } | 67 } |
67 | 68 |
68 SendSideBandwidthEstimation::SendSideBandwidthEstimation() | 69 SendSideBandwidthEstimation::SendSideBandwidthEstimation() |
69 : accumulate_lost_packets_Q8_(0), | 70 : accumulate_lost_packets_Q8_(0), |
70 accumulate_expected_packets_(0), | 71 accumulate_expected_packets_(0), |
71 bitrate_(0), | 72 bitrate_(0), |
72 min_bitrate_configured_(kDefaultMinBitrateBps), | 73 min_bitrate_configured_(kDefaultMinBitrateBps), |
73 max_bitrate_configured_(kDefaultMaxBitrateBps), | 74 max_bitrate_configured_(kDefaultMaxBitrateBps), |
| 75 last_low_bitrate_log_ms_(-1), |
74 time_last_receiver_block_ms_(0), | 76 time_last_receiver_block_ms_(0), |
75 last_fraction_loss_(0), | 77 last_fraction_loss_(0), |
76 last_round_trip_time_ms_(0), | 78 last_round_trip_time_ms_(0), |
77 bwe_incoming_(0), | 79 bwe_incoming_(0), |
78 time_last_decrease_ms_(0), | 80 time_last_decrease_ms_(0), |
79 first_report_time_ms_(-1), | 81 first_report_time_ms_(-1), |
80 initially_lost_packets_(0), | 82 initially_lost_packets_(0), |
81 bitrate_at_2_seconds_kbps_(0), | 83 bitrate_at_2_seconds_kbps_(0), |
82 uma_update_state_(kNoUpdate), | 84 uma_update_state_(kNoUpdate), |
83 rampup_uma_stats_updated_(kNumUmaRampupMetrics, false) { | 85 rampup_uma_stats_updated_(kNumUmaRampupMetrics, false) { |
(...skipping 27 matching lines...) Expand all Loading... |
111 } | 113 } |
112 | 114 |
113 void SendSideBandwidthEstimation::CurrentEstimate(int* bitrate, | 115 void SendSideBandwidthEstimation::CurrentEstimate(int* bitrate, |
114 uint8_t* loss, | 116 uint8_t* loss, |
115 int64_t* rtt) const { | 117 int64_t* rtt) const { |
116 *bitrate = bitrate_; | 118 *bitrate = bitrate_; |
117 *loss = last_fraction_loss_; | 119 *loss = last_fraction_loss_; |
118 *rtt = last_round_trip_time_ms_; | 120 *rtt = last_round_trip_time_ms_; |
119 } | 121 } |
120 | 122 |
121 void SendSideBandwidthEstimation::UpdateReceiverEstimate(uint32_t bandwidth) { | 123 void SendSideBandwidthEstimation::UpdateReceiverEstimate( |
| 124 int64_t now_ms, uint32_t bandwidth) { |
122 bwe_incoming_ = bandwidth; | 125 bwe_incoming_ = bandwidth; |
123 bitrate_ = CapBitrateToThresholds(bitrate_); | 126 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
124 } | 127 } |
125 | 128 |
126 void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, | 129 void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, |
127 int64_t rtt, | 130 int64_t rtt, |
128 int number_of_packets, | 131 int number_of_packets, |
129 int64_t now_ms) { | 132 int64_t now_ms) { |
130 if (first_report_time_ms_ == -1) | 133 if (first_report_time_ms_ == -1) |
131 first_report_time_ms_ = now_ms; | 134 first_report_time_ms_ = now_ms; |
132 | 135 |
133 // Update RTT. | 136 // Update RTT. |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 RTC_HISTOGRAM_COUNTS( | 196 RTC_HISTOGRAM_COUNTS( |
194 "WebRTC.BWE.InitialVsConvergedDiff", bitrate_diff_kbps, 0, 2000, 50); | 197 "WebRTC.BWE.InitialVsConvergedDiff", bitrate_diff_kbps, 0, 2000, 50); |
195 } | 198 } |
196 } | 199 } |
197 | 200 |
198 void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { | 201 void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
199 // We trust the REMB during the first 2 seconds if we haven't had any | 202 // We trust the REMB during the first 2 seconds if we haven't had any |
200 // packet loss reported, to allow startup bitrate probing. | 203 // packet loss reported, to allow startup bitrate probing. |
201 if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms) && | 204 if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms) && |
202 bwe_incoming_ > bitrate_) { | 205 bwe_incoming_ > bitrate_) { |
203 bitrate_ = CapBitrateToThresholds(bwe_incoming_); | 206 bitrate_ = CapBitrateToThresholds(now_ms, bwe_incoming_); |
204 min_bitrate_history_.clear(); | 207 min_bitrate_history_.clear(); |
205 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); | 208 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); |
206 return; | 209 return; |
207 } | 210 } |
208 UpdateMinHistory(now_ms); | 211 UpdateMinHistory(now_ms); |
209 // Only start updating bitrate when receiving receiver blocks. | 212 // Only start updating bitrate when receiving receiver blocks. |
210 if (time_last_receiver_block_ms_ != 0) { | 213 if (time_last_receiver_block_ms_ != 0) { |
211 if (last_fraction_loss_ <= 5) { | 214 if (last_fraction_loss_ <= 5) { |
212 // Loss < 2%: Increase rate by 8% of the min bitrate in the last | 215 // Loss < 2%: Increase rate by 8% of the min bitrate in the last |
213 // kBweIncreaseIntervalMs. | 216 // kBweIncreaseIntervalMs. |
(...skipping 30 matching lines...) Expand all Loading... |
244 512.0); | 247 512.0); |
245 | 248 |
246 // Calculate what rate TFRC would apply in this situation and to not | 249 // Calculate what rate TFRC would apply in this situation and to not |
247 // reduce further than it. | 250 // reduce further than it. |
248 bitrate_ = std::max( | 251 bitrate_ = std::max( |
249 bitrate_, | 252 bitrate_, |
250 CalcTfrcBps(last_round_trip_time_ms_, last_fraction_loss_)); | 253 CalcTfrcBps(last_round_trip_time_ms_, last_fraction_loss_)); |
251 } | 254 } |
252 } | 255 } |
253 } | 256 } |
254 bitrate_ = CapBitrateToThresholds(bitrate_); | 257 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
255 } | 258 } |
256 | 259 |
257 bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const { | 260 bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const { |
258 return first_report_time_ms_ == -1 || | 261 return first_report_time_ms_ == -1 || |
259 now_ms - first_report_time_ms_ < kStartPhaseMs; | 262 now_ms - first_report_time_ms_ < kStartPhaseMs; |
260 } | 263 } |
261 | 264 |
262 void SendSideBandwidthEstimation::UpdateMinHistory(int64_t now_ms) { | 265 void SendSideBandwidthEstimation::UpdateMinHistory(int64_t now_ms) { |
263 // Remove old data points from history. | 266 // Remove old data points from history. |
264 // Since history precision is in ms, add one so it is able to increase | 267 // Since history precision is in ms, add one so it is able to increase |
265 // bitrate if it is off by as little as 0.5ms. | 268 // bitrate if it is off by as little as 0.5ms. |
266 while (!min_bitrate_history_.empty() && | 269 while (!min_bitrate_history_.empty() && |
267 now_ms - min_bitrate_history_.front().first + 1 > | 270 now_ms - min_bitrate_history_.front().first + 1 > |
268 kBweIncreaseIntervalMs) { | 271 kBweIncreaseIntervalMs) { |
269 min_bitrate_history_.pop_front(); | 272 min_bitrate_history_.pop_front(); |
270 } | 273 } |
271 | 274 |
272 // Typical minimum sliding-window algorithm: Pop values higher than current | 275 // Typical minimum sliding-window algorithm: Pop values higher than current |
273 // bitrate before pushing it. | 276 // bitrate before pushing it. |
274 while (!min_bitrate_history_.empty() && | 277 while (!min_bitrate_history_.empty() && |
275 bitrate_ <= min_bitrate_history_.back().second) { | 278 bitrate_ <= min_bitrate_history_.back().second) { |
276 min_bitrate_history_.pop_back(); | 279 min_bitrate_history_.pop_back(); |
277 } | 280 } |
278 | 281 |
279 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); | 282 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); |
280 } | 283 } |
281 | 284 |
282 uint32_t SendSideBandwidthEstimation::CapBitrateToThresholds(uint32_t bitrate) { | 285 uint32_t SendSideBandwidthEstimation::CapBitrateToThresholds( |
| 286 int64_t now_ms, uint32_t bitrate) { |
283 if (bwe_incoming_ > 0 && bitrate > bwe_incoming_) { | 287 if (bwe_incoming_ > 0 && bitrate > bwe_incoming_) { |
284 bitrate = bwe_incoming_; | 288 bitrate = bwe_incoming_; |
285 } | 289 } |
286 if (bitrate > max_bitrate_configured_) { | 290 if (bitrate > max_bitrate_configured_) { |
287 bitrate = max_bitrate_configured_; | 291 bitrate = max_bitrate_configured_; |
288 } | 292 } |
289 if (bitrate < min_bitrate_configured_) { | 293 if (bitrate < min_bitrate_configured_) { |
290 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 | 294 if (last_low_bitrate_log_ms_ == -1 || |
291 << " kbps is below configured min bitrate " | 295 now_ms - last_low_bitrate_log_ms_ > kLowBitrateLogPeriodMs) { |
292 << min_bitrate_configured_ / 1000 << " kbps."; | 296 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 |
| 297 << " kbps is below configured min bitrate " |
| 298 << min_bitrate_configured_ / 1000 << " kbps."; |
| 299 last_low_bitrate_log_ms_ = now_ms; |
| 300 } |
293 bitrate = min_bitrate_configured_; | 301 bitrate = min_bitrate_configured_; |
294 } | 302 } |
295 return bitrate; | 303 return bitrate; |
296 } | 304 } |
297 } // namespace webrtc | 305 } // namespace webrtc |
OLD | NEW |