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

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

Powered by Google App Engine
This is Rietveld 408576698