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 |
(...skipping 12 matching lines...) Expand all Loading... |
23 namespace { | 23 namespace { |
24 const int64_t kBweIncreaseIntervalMs = 1000; | 24 const int64_t kBweIncreaseIntervalMs = 1000; |
25 const int64_t kBweDecreaseIntervalMs = 300; | 25 const int64_t kBweDecreaseIntervalMs = 300; |
26 const int64_t kStartPhaseMs = 2000; | 26 const int64_t kStartPhaseMs = 2000; |
27 const int64_t kBweConverganceTimeMs = 20000; | 27 const int64_t kBweConverganceTimeMs = 20000; |
28 const int kLimitNumPackets = 20; | 28 const int kLimitNumPackets = 20; |
29 const int kDefaultMinBitrateBps = 10000; | 29 const int kDefaultMinBitrateBps = 10000; |
30 const int kDefaultMaxBitrateBps = 1000000000; | 30 const int kDefaultMaxBitrateBps = 1000000000; |
31 const int64_t kLowBitrateLogPeriodMs = 10000; | 31 const int64_t kLowBitrateLogPeriodMs = 10000; |
32 const int64_t kRtcEventLogPeriodMs = 5000; | 32 const int64_t kRtcEventLogPeriodMs = 5000; |
| 33 // Expecting that RTCP feedback is sent uniformly within [0.5, 1.5]s intervals. |
| 34 const int64_t kFeedbackIntervalMs = 1500; |
| 35 const int64_t kFeedbackTimeoutIntervals = 3; |
| 36 const int64_t kTimeoutIntervalMs = 1000; |
33 | 37 |
34 struct UmaRampUpMetric { | 38 struct UmaRampUpMetric { |
35 const char* metric_name; | 39 const char* metric_name; |
36 int bitrate_kbps; | 40 int bitrate_kbps; |
37 }; | 41 }; |
38 | 42 |
39 const UmaRampUpMetric kUmaRampupMetrics[] = { | 43 const UmaRampUpMetric kUmaRampupMetrics[] = { |
40 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, | 44 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, |
41 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, | 45 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, |
42 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; | 46 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; |
43 const size_t kNumUmaRampupMetrics = | 47 const size_t kNumUmaRampupMetrics = |
44 sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); | 48 sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); |
45 | 49 |
46 } // namespace | 50 } // namespace |
47 | 51 |
48 SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) | 52 SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) |
49 : lost_packets_since_last_loss_update_Q8_(0), | 53 : lost_packets_since_last_loss_update_Q8_(0), |
50 expected_packets_since_last_loss_update_(0), | 54 expected_packets_since_last_loss_update_(0), |
51 bitrate_(0), | 55 bitrate_(0), |
52 min_bitrate_configured_(kDefaultMinBitrateBps), | 56 min_bitrate_configured_(kDefaultMinBitrateBps), |
53 max_bitrate_configured_(kDefaultMaxBitrateBps), | 57 max_bitrate_configured_(kDefaultMaxBitrateBps), |
54 last_low_bitrate_log_ms_(-1), | 58 last_low_bitrate_log_ms_(-1), |
55 has_decreased_since_last_fraction_loss_(false), | 59 has_decreased_since_last_fraction_loss_(false), |
56 time_last_receiver_block_ms_(-1), | 60 last_feedback_ms_(-1), |
| 61 last_packet_report_ms_(-1), |
| 62 last_timeout_ms_(-1), |
57 last_fraction_loss_(0), | 63 last_fraction_loss_(0), |
58 last_logged_fraction_loss_(0), | 64 last_logged_fraction_loss_(0), |
59 last_round_trip_time_ms_(0), | 65 last_round_trip_time_ms_(0), |
60 bwe_incoming_(0), | 66 bwe_incoming_(0), |
61 delay_based_bitrate_bps_(0), | 67 delay_based_bitrate_bps_(0), |
62 time_last_decrease_ms_(0), | 68 time_last_decrease_ms_(0), |
63 first_report_time_ms_(-1), | 69 first_report_time_ms_(-1), |
64 initially_lost_packets_(0), | 70 initially_lost_packets_(0), |
65 bitrate_at_2_seconds_kbps_(0), | 71 bitrate_at_2_seconds_kbps_(0), |
66 uma_update_state_(kNoUpdate), | 72 uma_update_state_(kNoUpdate), |
67 rampup_uma_stats_updated_(kNumUmaRampupMetrics, false), | 73 rampup_uma_stats_updated_(kNumUmaRampupMetrics, false), |
68 event_log_(event_log), | 74 event_log_(event_log), |
69 last_rtc_event_log_ms_(-1) { | 75 last_rtc_event_log_ms_(-1), |
| 76 in_timeout_experiment_(webrtc::field_trial::FindFullName( |
| 77 "WebRTC-SendSideBwe") == "Enabled") { |
70 RTC_DCHECK(event_log); | 78 RTC_DCHECK(event_log); |
71 } | 79 } |
72 | 80 |
73 SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {} | 81 SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {} |
74 | 82 |
75 void SendSideBandwidthEstimation::SetBitrates(int send_bitrate, | 83 void SendSideBandwidthEstimation::SetBitrates(int send_bitrate, |
76 int min_bitrate, | 84 int min_bitrate, |
77 int max_bitrate) { | 85 int max_bitrate) { |
78 if (send_bitrate > 0) | 86 if (send_bitrate > 0) |
79 SetSendBitrate(send_bitrate); | 87 SetSendBitrate(send_bitrate); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 int64_t now_ms, | 131 int64_t now_ms, |
124 uint32_t bitrate_bps) { | 132 uint32_t bitrate_bps) { |
125 delay_based_bitrate_bps_ = bitrate_bps; | 133 delay_based_bitrate_bps_ = bitrate_bps; |
126 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); | 134 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
127 } | 135 } |
128 | 136 |
129 void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, | 137 void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, |
130 int64_t rtt, | 138 int64_t rtt, |
131 int number_of_packets, | 139 int number_of_packets, |
132 int64_t now_ms) { | 140 int64_t now_ms) { |
| 141 last_feedback_ms_ = now_ms; |
133 if (first_report_time_ms_ == -1) | 142 if (first_report_time_ms_ == -1) |
134 first_report_time_ms_ = now_ms; | 143 first_report_time_ms_ = now_ms; |
135 | 144 |
136 // Update RTT. | 145 // Update RTT. |
137 last_round_trip_time_ms_ = rtt; | 146 last_round_trip_time_ms_ = rtt; |
138 | 147 |
139 // Check sequence number diff and weight loss report | 148 // Check sequence number diff and weight loss report |
140 if (number_of_packets > 0) { | 149 if (number_of_packets > 0) { |
141 // Calculate number of lost packets. | 150 // Calculate number of lost packets. |
142 const int num_lost_packets_Q8 = fraction_loss * number_of_packets; | 151 const int num_lost_packets_Q8 = fraction_loss * number_of_packets; |
143 // Accumulate reports. | 152 // Accumulate reports. |
144 lost_packets_since_last_loss_update_Q8_ += num_lost_packets_Q8; | 153 lost_packets_since_last_loss_update_Q8_ += num_lost_packets_Q8; |
145 expected_packets_since_last_loss_update_ += number_of_packets; | 154 expected_packets_since_last_loss_update_ += number_of_packets; |
146 | 155 |
147 // Don't generate a loss rate until it can be based on enough packets. | 156 // Don't generate a loss rate until it can be based on enough packets. |
148 if (expected_packets_since_last_loss_update_ < kLimitNumPackets) | 157 if (expected_packets_since_last_loss_update_ < kLimitNumPackets) |
149 return; | 158 return; |
150 | 159 |
151 has_decreased_since_last_fraction_loss_ = false; | 160 has_decreased_since_last_fraction_loss_ = false; |
152 last_fraction_loss_ = lost_packets_since_last_loss_update_Q8_ / | 161 last_fraction_loss_ = lost_packets_since_last_loss_update_Q8_ / |
153 expected_packets_since_last_loss_update_; | 162 expected_packets_since_last_loss_update_; |
154 | 163 |
155 // Reset accumulators. | 164 // Reset accumulators. |
156 lost_packets_since_last_loss_update_Q8_ = 0; | 165 lost_packets_since_last_loss_update_Q8_ = 0; |
157 expected_packets_since_last_loss_update_ = 0; | 166 expected_packets_since_last_loss_update_ = 0; |
| 167 last_packet_report_ms_ = now_ms; |
| 168 UpdateEstimate(now_ms); |
158 } | 169 } |
159 time_last_receiver_block_ms_ = now_ms; | |
160 UpdateEstimate(now_ms); | |
161 UpdateUmaStats(now_ms, rtt, (fraction_loss * number_of_packets) >> 8); | 170 UpdateUmaStats(now_ms, rtt, (fraction_loss * number_of_packets) >> 8); |
162 } | 171 } |
163 | 172 |
164 void SendSideBandwidthEstimation::UpdateUmaStats(int64_t now_ms, | 173 void SendSideBandwidthEstimation::UpdateUmaStats(int64_t now_ms, |
165 int64_t rtt, | 174 int64_t rtt, |
166 int lost_packets) { | 175 int lost_packets) { |
167 int bitrate_kbps = static_cast<int>((bitrate_ + 500) / 1000); | 176 int bitrate_kbps = static_cast<int>((bitrate_ + 500) / 1000); |
168 for (size_t i = 0; i < kNumUmaRampupMetrics; ++i) { | 177 for (size_t i = 0; i < kNumUmaRampupMetrics; ++i) { |
169 if (!rampup_uma_stats_updated_[i] && | 178 if (!rampup_uma_stats_updated_[i] && |
170 bitrate_kbps >= kUmaRampupMetrics[i].bitrate_kbps) { | 179 bitrate_kbps >= kUmaRampupMetrics[i].bitrate_kbps) { |
(...skipping 23 matching lines...) Expand all Loading... |
194 } | 203 } |
195 } | 204 } |
196 | 205 |
197 void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { | 206 void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
198 // We trust the REMB and/or delay-based estimate during the first 2 seconds if | 207 // We trust the REMB and/or delay-based estimate during the first 2 seconds if |
199 // we haven't had any packet loss reported, to allow startup bitrate probing. | 208 // we haven't had any packet loss reported, to allow startup bitrate probing. |
200 if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms)) { | 209 if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms)) { |
201 uint32_t prev_bitrate = bitrate_; | 210 uint32_t prev_bitrate = bitrate_; |
202 if (bwe_incoming_ > bitrate_) | 211 if (bwe_incoming_ > bitrate_) |
203 bitrate_ = CapBitrateToThresholds(now_ms, bwe_incoming_); | 212 bitrate_ = CapBitrateToThresholds(now_ms, bwe_incoming_); |
204 if (delay_based_bitrate_bps_ > bitrate_) | 213 if (delay_based_bitrate_bps_ > bitrate_) { |
205 bitrate_ = CapBitrateToThresholds(now_ms, delay_based_bitrate_bps_); | 214 bitrate_ = CapBitrateToThresholds(now_ms, delay_based_bitrate_bps_); |
| 215 } |
206 if (bitrate_ != prev_bitrate) { | 216 if (bitrate_ != prev_bitrate) { |
207 min_bitrate_history_.clear(); | 217 min_bitrate_history_.clear(); |
208 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); | 218 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); |
209 return; | 219 return; |
210 } | 220 } |
211 } | 221 } |
212 UpdateMinHistory(now_ms); | 222 UpdateMinHistory(now_ms); |
213 // Only start updating bitrate when receiving receiver blocks. | 223 if (last_packet_report_ms_ == -1) { |
214 // TODO(pbos): Handle the case when no receiver report is received for a very | 224 // No feedback received. |
215 // long time. | 225 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
216 if (time_last_receiver_block_ms_ != -1) { | 226 return; |
| 227 } |
| 228 int64_t time_since_packet_report_ms = now_ms - last_packet_report_ms_; |
| 229 int64_t time_since_feedback_ms = now_ms - last_feedback_ms_; |
| 230 if (time_since_packet_report_ms < 1.2 * kFeedbackIntervalMs) { |
217 if (last_fraction_loss_ <= 5) { | 231 if (last_fraction_loss_ <= 5) { |
218 // Loss < 2%: Increase rate by 8% of the min bitrate in the last | 232 // Loss < 2%: Increase rate by 8% of the min bitrate in the last |
219 // kBweIncreaseIntervalMs. | 233 // kBweIncreaseIntervalMs. |
220 // Note that by remembering the bitrate over the last second one can | 234 // Note that by remembering the bitrate over the last second one can |
221 // rampup up one second faster than if only allowed to start ramping | 235 // rampup up one second faster than if only allowed to start ramping |
222 // at 8% per second rate now. E.g.: | 236 // at 8% per second rate now. E.g.: |
223 // If sending a constant 100kbps it can rampup immediatly to 108kbps | 237 // If sending a constant 100kbps it can rampup immediatly to 108kbps |
224 // whenever a receiver report is received with lower packet loss. | 238 // whenever a receiver report is received with lower packet loss. |
225 // If instead one would do: bitrate_ *= 1.08^(delta time), it would | 239 // If instead one would do: bitrate_ *= 1.08^(delta time), it would |
226 // take over one second since the lower packet loss to achieve 108kbps. | 240 // take over one second since the lower packet loss to achieve |
| 241 // 108kbps. |
227 bitrate_ = static_cast<uint32_t>( | 242 bitrate_ = static_cast<uint32_t>( |
228 min_bitrate_history_.front().second * 1.08 + 0.5); | 243 min_bitrate_history_.front().second * 1.08 + 0.5); |
229 | 244 |
230 // Add 1 kbps extra, just to make sure that we do not get stuck | 245 // Add 1 kbps extra, just to make sure that we do not get stuck |
231 // (gives a little extra increase at low rates, negligible at higher | 246 // (gives a little extra increase at low rates, negligible at higher |
232 // rates). | 247 // rates). |
233 bitrate_ += 1000; | 248 bitrate_ += 1000; |
234 } else if (last_fraction_loss_ <= 26) { | 249 } else if (last_fraction_loss_ <= 26) { |
235 // Loss between 2% - 10%: Do nothing. | 250 // Loss between 2% - 10%: Do nothing. |
236 } else { | 251 } else { |
237 // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs + | 252 // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs |
238 // rtt. | 253 // + rtt. |
239 if (!has_decreased_since_last_fraction_loss_ && | 254 if (!has_decreased_since_last_fraction_loss_ && |
240 (now_ms - time_last_decrease_ms_) >= | 255 (now_ms - time_last_decrease_ms_) >= |
241 (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { | 256 (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { |
242 time_last_decrease_ms_ = now_ms; | 257 time_last_decrease_ms_ = now_ms; |
243 | 258 |
244 // Reduce rate: | 259 // Reduce rate: |
245 // newRate = rate * (1 - 0.5*lossRate); | 260 // newRate = rate * (1 - 0.5*lossRate); |
246 // where packetLoss = 256*lossRate; | 261 // where packetLoss = 256*lossRate; |
247 bitrate_ = static_cast<uint32_t>( | 262 bitrate_ = static_cast<uint32_t>( |
248 (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / | 263 (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / |
249 512.0); | 264 512.0); |
250 has_decreased_since_last_fraction_loss_ = true; | 265 has_decreased_since_last_fraction_loss_ = true; |
251 } | 266 } |
252 } | 267 } |
| 268 } else if (time_since_feedback_ms > |
| 269 kFeedbackTimeoutIntervals * kFeedbackIntervalMs && |
| 270 (last_timeout_ms_ == -1 || |
| 271 now_ms - last_timeout_ms_ > kTimeoutIntervalMs)) { |
| 272 if (in_timeout_experiment_) { |
| 273 LOG(LS_WARNING) << "Feedback timed out (" << time_since_feedback_ms |
| 274 << " ms), reducing bitrate."; |
| 275 bitrate_ *= 0.8; |
| 276 // Reset accumulators since we've already acted on missing feedback and |
| 277 // shouldn't to act again on these old lost packets. |
| 278 lost_packets_since_last_loss_update_Q8_ = 0; |
| 279 expected_packets_since_last_loss_update_ = 0; |
| 280 last_timeout_ms_ = now_ms; |
| 281 } |
253 } | 282 } |
254 uint32_t capped_bitrate = CapBitrateToThresholds(now_ms, bitrate_); | 283 uint32_t capped_bitrate = CapBitrateToThresholds(now_ms, bitrate_); |
255 if (capped_bitrate != bitrate_ || | 284 if (capped_bitrate != bitrate_ || |
256 last_fraction_loss_ != last_logged_fraction_loss_ || | 285 last_fraction_loss_ != last_logged_fraction_loss_ || |
257 last_rtc_event_log_ms_ == -1 || | 286 last_rtc_event_log_ms_ == -1 || |
258 now_ms - last_rtc_event_log_ms_ > kRtcEventLogPeriodMs) { | 287 now_ms - last_rtc_event_log_ms_ > kRtcEventLogPeriodMs) { |
259 event_log_->LogBwePacketLossEvent(capped_bitrate, last_fraction_loss_, | 288 event_log_->LogBwePacketLossEvent(capped_bitrate, last_fraction_loss_, |
260 expected_packets_since_last_loss_update_); | 289 expected_packets_since_last_loss_update_); |
261 last_logged_fraction_loss_ = last_fraction_loss_; | 290 last_logged_fraction_loss_ = last_fraction_loss_; |
262 last_rtc_event_log_ms_ = now_ms; | 291 last_rtc_event_log_ms_ = now_ms; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 | 335 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 |
307 << " kbps is below configured min bitrate " | 336 << " kbps is below configured min bitrate " |
308 << min_bitrate_configured_ / 1000 << " kbps."; | 337 << min_bitrate_configured_ / 1000 << " kbps."; |
309 last_low_bitrate_log_ms_ = now_ms; | 338 last_low_bitrate_log_ms_ = now_ms; |
310 } | 339 } |
311 bitrate = min_bitrate_configured_; | 340 bitrate = min_bitrate_configured_; |
312 } | 341 } |
313 return bitrate; | 342 return bitrate; |
314 } | 343 } |
315 } // namespace webrtc | 344 } // namespace webrtc |
OLD | NEW |