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

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

Issue 2262213002: Stop increasing loss-based BWE if no feedback is received. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebase. Created 4 years, 3 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 12 matching lines...) Expand all
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698