Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc

Issue 1417723005: Prevent BWE rampdowns without new loss reports. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698