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 25 matching lines...) Expand all Loading... |
36 const UmaRampUpMetric kUmaRampupMetrics[] = { | 36 const UmaRampUpMetric kUmaRampupMetrics[] = { |
37 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, | 37 {"WebRTC.BWE.RampUpTimeTo500kbpsInMs", 500}, |
38 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, | 38 {"WebRTC.BWE.RampUpTimeTo1000kbpsInMs", 1000}, |
39 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; | 39 {"WebRTC.BWE.RampUpTimeTo2000kbpsInMs", 2000}}; |
40 const size_t kNumUmaRampupMetrics = | 40 const size_t kNumUmaRampupMetrics = |
41 sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); | 41 sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); |
42 | 42 |
43 } | 43 } |
44 | 44 |
45 SendSideBandwidthEstimation::SendSideBandwidthEstimation() | 45 SendSideBandwidthEstimation::SendSideBandwidthEstimation() |
46 : accumulate_lost_packets_Q8_(0), | 46 : lost_packets_since_last_loss_update_Q8_(0), |
47 accumulate_expected_packets_(0), | 47 expected_packets_since_last_loss_update_(0), |
48 bitrate_(0), | 48 bitrate_(0), |
49 min_bitrate_configured_(kDefaultMinBitrateBps), | 49 min_bitrate_configured_(kDefaultMinBitrateBps), |
50 max_bitrate_configured_(kDefaultMaxBitrateBps), | 50 max_bitrate_configured_(kDefaultMaxBitrateBps), |
51 last_low_bitrate_log_ms_(-1), | 51 last_low_bitrate_log_ms_(-1), |
52 time_last_receiver_block_ms_(0), | 52 has_decreased_since_last_fraction_loss_(false), |
| 53 time_last_receiver_block_ms_(-1), |
53 last_fraction_loss_(0), | 54 last_fraction_loss_(0), |
54 last_round_trip_time_ms_(0), | 55 last_round_trip_time_ms_(0), |
55 bwe_incoming_(0), | 56 bwe_incoming_(0), |
56 time_last_decrease_ms_(0), | 57 time_last_decrease_ms_(0), |
57 first_report_time_ms_(-1), | 58 first_report_time_ms_(-1), |
58 initially_lost_packets_(0), | 59 initially_lost_packets_(0), |
59 bitrate_at_2_seconds_kbps_(0), | 60 bitrate_at_2_seconds_kbps_(0), |
60 uma_update_state_(kNoUpdate), | 61 uma_update_state_(kNoUpdate), |
61 rampup_uma_stats_updated_(kNumUmaRampupMetrics, false) { | 62 rampup_uma_stats_updated_(kNumUmaRampupMetrics, false) {} |
62 } | |
63 | 63 |
64 SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {} | 64 SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {} |
65 | 65 |
66 void SendSideBandwidthEstimation::SetSendBitrate(int bitrate) { | 66 void SendSideBandwidthEstimation::SetSendBitrate(int bitrate) { |
67 RTC_DCHECK_GT(bitrate, 0); | 67 RTC_DCHECK_GT(bitrate, 0); |
68 bitrate_ = bitrate; | 68 bitrate_ = bitrate; |
69 | 69 |
70 // Clear last sent bitrate history so the new value can be used directly | 70 // Clear last sent bitrate history so the new value can be used directly |
71 // and not capped. | 71 // and not capped. |
72 min_bitrate_history_.clear(); | 72 min_bitrate_history_.clear(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 first_report_time_ms_ = now_ms; | 110 first_report_time_ms_ = now_ms; |
111 | 111 |
112 // Update RTT. | 112 // Update RTT. |
113 last_round_trip_time_ms_ = rtt; | 113 last_round_trip_time_ms_ = rtt; |
114 | 114 |
115 // Check sequence number diff and weight loss report | 115 // Check sequence number diff and weight loss report |
116 if (number_of_packets > 0) { | 116 if (number_of_packets > 0) { |
117 // Calculate number of lost packets. | 117 // Calculate number of lost packets. |
118 const int num_lost_packets_Q8 = fraction_loss * number_of_packets; | 118 const int num_lost_packets_Q8 = fraction_loss * number_of_packets; |
119 // Accumulate reports. | 119 // Accumulate reports. |
120 accumulate_lost_packets_Q8_ += num_lost_packets_Q8; | 120 lost_packets_since_last_loss_update_Q8_ += num_lost_packets_Q8; |
121 accumulate_expected_packets_ += number_of_packets; | 121 expected_packets_since_last_loss_update_ += number_of_packets; |
122 | 122 |
123 // Report loss if the total report is based on sufficiently many packets. | 123 // Don't generate a loss rate until it can be based on enough packets. |
124 if (accumulate_expected_packets_ >= kLimitNumPackets) { | 124 if (expected_packets_since_last_loss_update_ < kLimitNumPackets) |
125 last_fraction_loss_ = | 125 return; |
126 accumulate_lost_packets_Q8_ / accumulate_expected_packets_; | |
127 | 126 |
128 // Reset accumulators. | 127 has_decreased_since_last_fraction_loss_ = false; |
129 accumulate_lost_packets_Q8_ = 0; | 128 last_fraction_loss_ = lost_packets_since_last_loss_update_Q8_ / |
130 accumulate_expected_packets_ = 0; | 129 expected_packets_since_last_loss_update_; |
131 } else { | 130 |
132 // Early return without updating estimate. | 131 // Reset accumulators. |
133 return; | 132 lost_packets_since_last_loss_update_Q8_ = 0; |
134 } | 133 expected_packets_since_last_loss_update_ = 0; |
135 } | 134 } |
136 time_last_receiver_block_ms_ = now_ms; | 135 time_last_receiver_block_ms_ = now_ms; |
137 UpdateEstimate(now_ms); | 136 UpdateEstimate(now_ms); |
138 UpdateUmaStats(now_ms, rtt, (fraction_loss * number_of_packets) >> 8); | 137 UpdateUmaStats(now_ms, rtt, (fraction_loss * number_of_packets) >> 8); |
139 } | 138 } |
140 | 139 |
141 void SendSideBandwidthEstimation::UpdateUmaStats(int64_t now_ms, | 140 void SendSideBandwidthEstimation::UpdateUmaStats(int64_t now_ms, |
142 int64_t rtt, | 141 int64_t rtt, |
143 int lost_packets) { | 142 int lost_packets) { |
144 int bitrate_kbps = static_cast<int>((bitrate_ + 500) / 1000); | 143 int bitrate_kbps = static_cast<int>((bitrate_ + 500) / 1000); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 // packet loss reported, to allow startup bitrate probing. | 178 // packet loss reported, to allow startup bitrate probing. |
180 if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms) && | 179 if (last_fraction_loss_ == 0 && IsInStartPhase(now_ms) && |
181 bwe_incoming_ > bitrate_) { | 180 bwe_incoming_ > bitrate_) { |
182 bitrate_ = CapBitrateToThresholds(now_ms, bwe_incoming_); | 181 bitrate_ = CapBitrateToThresholds(now_ms, bwe_incoming_); |
183 min_bitrate_history_.clear(); | 182 min_bitrate_history_.clear(); |
184 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); | 183 min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); |
185 return; | 184 return; |
186 } | 185 } |
187 UpdateMinHistory(now_ms); | 186 UpdateMinHistory(now_ms); |
188 // Only start updating bitrate when receiving receiver blocks. | 187 // Only start updating bitrate when receiving receiver blocks. |
189 if (time_last_receiver_block_ms_ != 0) { | 188 // TODO(pbos): Handle the case when no receiver report is received for a very |
| 189 // long time. |
| 190 if (time_last_receiver_block_ms_ != -1) { |
190 if (last_fraction_loss_ <= 5) { | 191 if (last_fraction_loss_ <= 5) { |
191 // Loss < 2%: Increase rate by 8% of the min bitrate in the last | 192 // Loss < 2%: Increase rate by 8% of the min bitrate in the last |
192 // kBweIncreaseIntervalMs. | 193 // kBweIncreaseIntervalMs. |
193 // Note that by remembering the bitrate over the last second one can | 194 // Note that by remembering the bitrate over the last second one can |
194 // rampup up one second faster than if only allowed to start ramping | 195 // rampup up one second faster than if only allowed to start ramping |
195 // at 8% per second rate now. E.g.: | 196 // at 8% per second rate now. E.g.: |
196 // If sending a constant 100kbps it can rampup immediatly to 108kbps | 197 // If sending a constant 100kbps it can rampup immediatly to 108kbps |
197 // whenever a receiver report is received with lower packet loss. | 198 // whenever a receiver report is received with lower packet loss. |
198 // If instead one would do: bitrate_ *= 1.08^(delta time), it would | 199 // If instead one would do: bitrate_ *= 1.08^(delta time), it would |
199 // take over one second since the lower packet loss to achieve 108kbps. | 200 // take over one second since the lower packet loss to achieve 108kbps. |
200 bitrate_ = static_cast<uint32_t>( | 201 bitrate_ = static_cast<uint32_t>( |
201 min_bitrate_history_.front().second * 1.08 + 0.5); | 202 min_bitrate_history_.front().second * 1.08 + 0.5); |
202 | 203 |
203 // Add 1 kbps extra, just to make sure that we do not get stuck | 204 // Add 1 kbps extra, just to make sure that we do not get stuck |
204 // (gives a little extra increase at low rates, negligible at higher | 205 // (gives a little extra increase at low rates, negligible at higher |
205 // rates). | 206 // rates). |
206 bitrate_ += 1000; | 207 bitrate_ += 1000; |
207 | 208 |
208 } else if (last_fraction_loss_ <= 26) { | 209 } else if (last_fraction_loss_ <= 26) { |
209 // Loss between 2% - 10%: Do nothing. | 210 // Loss between 2% - 10%: Do nothing. |
210 | |
211 } else { | 211 } else { |
212 // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs + | 212 // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs + |
213 // rtt. | 213 // rtt. |
214 if ((now_ms - time_last_decrease_ms_) >= | 214 if (!has_decreased_since_last_fraction_loss_ && |
215 (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { | 215 (now_ms - time_last_decrease_ms_) >= |
| 216 (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { |
216 time_last_decrease_ms_ = now_ms; | 217 time_last_decrease_ms_ = now_ms; |
217 | 218 |
218 // Reduce rate: | 219 // Reduce rate: |
219 // newRate = rate * (1 - 0.5*lossRate); | 220 // newRate = rate * (1 - 0.5*lossRate); |
220 // where packetLoss = 256*lossRate; | 221 // where packetLoss = 256*lossRate; |
221 bitrate_ = static_cast<uint32_t>( | 222 bitrate_ = static_cast<uint32_t>( |
222 (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / | 223 (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / |
223 512.0); | 224 512.0); |
| 225 has_decreased_since_last_fraction_loss_ = true; |
224 } | 226 } |
225 } | 227 } |
226 } | 228 } |
227 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); | 229 bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
228 } | 230 } |
229 | 231 |
230 bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const { | 232 bool SendSideBandwidthEstimation::IsInStartPhase(int64_t now_ms) const { |
231 return first_report_time_ms_ == -1 || | 233 return first_report_time_ms_ == -1 || |
232 now_ms - first_report_time_ms_ < kStartPhaseMs; | 234 now_ms - first_report_time_ms_ < kStartPhaseMs; |
233 } | 235 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 | 268 LOG(LS_WARNING) << "Estimated available bandwidth " << bitrate / 1000 |
267 << " kbps is below configured min bitrate " | 269 << " kbps is below configured min bitrate " |
268 << min_bitrate_configured_ / 1000 << " kbps."; | 270 << min_bitrate_configured_ / 1000 << " kbps."; |
269 last_low_bitrate_log_ms_ = now_ms; | 271 last_low_bitrate_log_ms_ = now_ms; |
270 } | 272 } |
271 bitrate = min_bitrate_configured_; | 273 bitrate = min_bitrate_configured_; |
272 } | 274 } |
273 return bitrate; | 275 return bitrate; |
274 } | 276 } |
275 } // namespace webrtc | 277 } // namespace webrtc |
OLD | NEW |