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

Side by Side Diff: webrtc/modules/congestion_controller/delay_based_bwe.cc

Issue 2986563002: Add probing to recover faster from large bitrate drops. (Closed)
Patch Set: Created 3 years, 5 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) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 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 28 matching lines...) Expand all
39 // after the API has been changed. 39 // after the API has been changed.
40 constexpr uint32_t kFixedSsrc = 0; 40 constexpr uint32_t kFixedSsrc = 0;
41 41
42 // Parameters for linear least squares fit of regression line to noisy data. 42 // Parameters for linear least squares fit of regression line to noisy data.
43 constexpr size_t kDefaultTrendlineWindowSize = 20; 43 constexpr size_t kDefaultTrendlineWindowSize = 20;
44 constexpr double kDefaultTrendlineSmoothingCoeff = 0.9; 44 constexpr double kDefaultTrendlineSmoothingCoeff = 0.9;
45 constexpr double kDefaultTrendlineThresholdGain = 4.0; 45 constexpr double kDefaultTrendlineThresholdGain = 4.0;
46 46
47 constexpr int kMaxConsecutiveFailedLookups = 5; 47 constexpr int kMaxConsecutiveFailedLookups = 5;
48 48
49 // If the bitrate drops to a factor |kBitrateDropThreshold| or lower
50 // and we recover within |kBitrateDropTimeLimitMs|, then we'll send
51 // a probe at a fraction |kBitrateDropProbeFraction| of the original bitrate.
52 constexpr double kBitrateDropThreshold = 0.5;
53 constexpr int kBitrateDropTimeLimitMs = 3000;
54 constexpr double kBitrateDropProbeFraction = 0.85;
55
49 const char kBweSparseUpdateExperiment[] = "WebRTC-BweSparseUpdateExperiment"; 56 const char kBweSparseUpdateExperiment[] = "WebRTC-BweSparseUpdateExperiment";
50 57
51 bool BweSparseUpdateExperimentIsEnabled() { 58 bool BweSparseUpdateExperimentIsEnabled() {
52 std::string experiment_string = 59 std::string experiment_string =
53 webrtc::field_trial::FindFullName(kBweSparseUpdateExperiment); 60 webrtc::field_trial::FindFullName(kBweSparseUpdateExperiment);
54 return experiment_string == "Enabled"; 61 return experiment_string == "Enabled";
55 } 62 }
56 } // namespace 63 } // namespace
57 64
58 namespace webrtc { 65 namespace webrtc {
59 66
67 DelayBasedBwe::Result::Result()
68 : updated(false),
69 probe(false),
70 target_bitrate_bps(0),
71 suggested_probe_bps() {}
72
73 DelayBasedBwe::Result::Result(bool probe, uint32_t target_bitrate_bps)
74 : updated(true),
75 probe(probe),
76 target_bitrate_bps(target_bitrate_bps),
77 suggested_probe_bps() {}
78
79 DelayBasedBwe::Result::Result(bool probe,
80 uint32_t target_bitrate_bps,
81 uint32_t suggested_probe_bps)
82 : updated(true),
83 probe(probe),
84 target_bitrate_bps(target_bitrate_bps),
85 suggested_probe_bps(suggested_probe_bps) {}
86
87 DelayBasedBwe::Result::~Result() {}
88
60 DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) 89 DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock)
61 : event_log_(event_log), 90 : event_log_(event_log),
62 clock_(clock), 91 clock_(clock),
63 inter_arrival_(), 92 inter_arrival_(),
64 trendline_estimator_(), 93 trendline_estimator_(),
65 detector_(), 94 detector_(),
66 last_seen_packet_ms_(-1), 95 last_seen_packet_ms_(-1),
67 uma_recorded_(false), 96 uma_recorded_(false),
68 probe_bitrate_estimator_(event_log), 97 probe_bitrate_estimator_(event_log),
69 trendline_window_size_(kDefaultTrendlineWindowSize), 98 trendline_window_size_(kDefaultTrendlineWindowSize),
(...skipping 25 matching lines...) Expand all
95 } 124 }
96 125
97 if (!uma_recorded_) { 126 if (!uma_recorded_) {
98 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, 127 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram,
99 BweNames::kSendSideTransportSeqNum, 128 BweNames::kSendSideTransportSeqNum,
100 BweNames::kBweNamesMax); 129 BweNames::kBweNamesMax);
101 uma_recorded_ = true; 130 uma_recorded_ = true;
102 } 131 }
103 bool overusing = false; 132 bool overusing = false;
104 bool delayed_feedback = true; 133 bool delayed_feedback = true;
134 bool request_probe = false;
135 BandwidthUsage prev_detector_state = detector_.State();
105 for (const auto& packet_feedback : packet_feedback_vector) { 136 for (const auto& packet_feedback : packet_feedback_vector) {
106 if (packet_feedback.send_time_ms < 0) 137 if (packet_feedback.send_time_ms < 0)
107 continue; 138 continue;
108 delayed_feedback = false; 139 delayed_feedback = false;
109 IncomingPacketFeedback(packet_feedback); 140 IncomingPacketFeedback(packet_feedback);
110 if (!in_sparse_update_experiment_) 141 if (!in_sparse_update_experiment_)
111 overusing |= (detector_.State() == BandwidthUsage::kBwOverusing); 142 overusing |= (detector_.State() == BandwidthUsage::kBwOverusing);
143 if (prev_detector_state == BandwidthUsage::kBwUnderusing &&
144 detector_.State() == BandwidthUsage::kBwNormal) {
145 request_probe = true;
146 }
147 prev_detector_state = detector_.State();
112 } 148 }
113 if (in_sparse_update_experiment_) 149 if (in_sparse_update_experiment_)
114 overusing = (detector_.State() == BandwidthUsage::kBwOverusing); 150 overusing = (detector_.State() == BandwidthUsage::kBwOverusing);
151
115 if (delayed_feedback) { 152 if (delayed_feedback) {
116 ++consecutive_delayed_feedbacks_; 153 ++consecutive_delayed_feedbacks_;
117 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { 154 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) {
118 consecutive_delayed_feedbacks_ = 0; 155 consecutive_delayed_feedbacks_ = 0;
119 return OnLongFeedbackDelay(packet_feedback_vector.back().arrival_time_ms); 156 return OnLongFeedbackDelay(packet_feedback_vector.back().arrival_time_ms);
120 } 157 }
121 } else { 158 } else {
122 consecutive_delayed_feedbacks_ = 0; 159 consecutive_delayed_feedbacks_ = 0;
123 return MaybeUpdateEstimate(overusing, acked_bitrate_bps); 160 return MaybeUpdateEstimate(overusing, acked_bitrate_bps, request_probe);
124 } 161 }
125 return Result(); 162 return Result();
126 } 163 }
127 164
128 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( 165 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay(
129 int64_t arrival_time_ms) { 166 int64_t arrival_time_ms) {
130 // Estimate should always be valid since a start bitrate always is set in the 167 // Estimate should always be valid since a start bitrate always is set in the
131 // Call constructor. An alternative would be to return an empty Result here, 168 // Call constructor. An alternative would be to return an empty Result here,
132 // or to estimate the throughput based on the feedback we received. 169 // or to estimate the throughput based on the feedback we received.
133 RTC_DCHECK(rate_control_.ValidEstimate()); 170 RTC_DCHECK(rate_control_.ValidEstimate());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 packet_feedback.arrival_time_ms); 219 packet_feedback.arrival_time_ms);
183 } 220 }
184 if (packet_feedback.pacing_info.probe_cluster_id != 221 if (packet_feedback.pacing_info.probe_cluster_id !=
185 PacedPacketInfo::kNotAProbe) { 222 PacedPacketInfo::kNotAProbe) {
186 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); 223 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback);
187 } 224 }
188 } 225 }
189 226
190 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate( 227 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(
191 bool overusing, 228 bool overusing,
192 rtc::Optional<uint32_t> acked_bitrate_bps) { 229 rtc::Optional<uint32_t> acked_bitrate_bps,
230 bool request_probe) {
193 Result result; 231 Result result;
194 int64_t now_ms = clock_->TimeInMilliseconds(); 232 int64_t now_ms = clock_->TimeInMilliseconds();
195 233
196 rtc::Optional<int> probe_bitrate_bps = 234 rtc::Optional<int> probe_bitrate_bps =
197 probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); 235 probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps();
198 // Currently overusing the bandwidth. 236 // Currently overusing the bandwidth.
199 if (overusing) { 237 if (overusing) {
200 if (acked_bitrate_bps && 238 if (acked_bitrate_bps &&
201 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { 239 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) {
202 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing, 240 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing,
(...skipping 13 matching lines...) Expand all
216 } 254 }
217 } else { 255 } else {
218 if (probe_bitrate_bps) { 256 if (probe_bitrate_bps) {
219 result.probe = true; 257 result.probe = true;
220 result.updated = true; 258 result.updated = true;
221 result.target_bitrate_bps = *probe_bitrate_bps; 259 result.target_bitrate_bps = *probe_bitrate_bps;
222 rate_control_.SetEstimate(*probe_bitrate_bps, now_ms); 260 rate_control_.SetEstimate(*probe_bitrate_bps, now_ms);
223 } else { 261 } else {
224 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing, 262 result.updated = UpdateEstimate(now_ms, acked_bitrate_bps, overusing,
225 &result.target_bitrate_bps); 263 &result.target_bitrate_bps);
264 if (request_probe &&
265 result.target_bitrate_bps <
266 kBitrateDropProbeFraction * bitrate_before_last_large_drop_ &&
philipel 2017/07/25 11:26:04 I think a slightly clearer way of doing this check
terelius 2017/07/27 21:02:45 It is not the same thing. However, it seems a bit
terelius 2017/07/28 17:14:47 Moved the entire drop detection into the ProbeCont
267 now_ms - time_of_last_large_drop_ms_ < kBitrateDropTimeLimitMs) {
268 result.suggested_probe_bps = static_cast<rtc::Optional<uint32_t>>(
philipel 2017/07/25 11:26:04 result.suggested_probe_bps.emplace
terelius 2017/07/27 21:02:45 Done.
269 kBitrateDropProbeFraction * bitrate_before_last_large_drop_);
270 }
226 } 271 }
227 } 272 }
228 if (result.updated) { 273 if (result.updated) {
229 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, 274 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms,
230 result.target_bitrate_bps); 275 result.target_bitrate_bps);
231 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || 276 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ ||
232 detector_.State() != last_logged_state_)) { 277 detector_.State() != last_logged_state_)) {
233 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, 278 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps,
234 detector_.State()); 279 detector_.State());
235 last_logged_bitrate_ = result.target_bitrate_bps; 280 last_logged_bitrate_ = result.target_bitrate_bps;
236 last_logged_state_ = detector_.State(); 281 last_logged_state_ = detector_.State();
237 } 282 }
238 } 283 }
239 return result; 284 return result;
240 } 285 }
241 286
242 bool DelayBasedBwe::UpdateEstimate(int64_t now_ms, 287 bool DelayBasedBwe::UpdateEstimate(int64_t now_ms,
243 rtc::Optional<uint32_t> acked_bitrate_bps, 288 rtc::Optional<uint32_t> acked_bitrate_bps,
244 bool overusing, 289 bool overusing,
245 uint32_t* target_bitrate_bps) { 290 uint32_t* target_bitrate_bps) {
246 // TODO(terelius): RateControlInput::noise_var is deprecated and will be 291 // TODO(terelius): RateControlInput::noise_var is deprecated and will be
247 // removed. In the meantime, we set it to zero. 292 // removed. In the meantime, we set it to zero.
248 const RateControlInput input( 293 const RateControlInput input(
249 overusing ? BandwidthUsage::kBwOverusing : detector_.State(), 294 overusing ? BandwidthUsage::kBwOverusing : detector_.State(),
250 acked_bitrate_bps, 0); 295 acked_bitrate_bps, 0);
251 uint32_t prev_target_bitrate_bps = rate_control_.LatestEstimate(); 296 uint32_t prev_target_bitrate_bps = rate_control_.LatestEstimate();
252 *target_bitrate_bps = rate_control_.Update(&input, now_ms); 297 *target_bitrate_bps = rate_control_.Update(&input, now_ms);
298 if (*target_bitrate_bps < kBitrateDropThreshold * prev_target_bitrate_bps) {
299 time_of_last_large_drop_ms_ = now_ms;
300 bitrate_before_last_large_drop_ = prev_target_bitrate_bps;
301 }
253 return rate_control_.ValidEstimate() && 302 return rate_control_.ValidEstimate() &&
254 prev_target_bitrate_bps != *target_bitrate_bps; 303 prev_target_bitrate_bps != *target_bitrate_bps;
255 } 304 }
256 305
257 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { 306 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
258 rate_control_.SetRtt(avg_rtt_ms); 307 rate_control_.SetRtt(avg_rtt_ms);
259 } 308 }
260 309
261 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, 310 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs,
262 uint32_t* bitrate_bps) const { 311 uint32_t* bitrate_bps) const {
(...skipping 19 matching lines...) Expand all
282 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { 331 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) {
283 // Called from both the configuration thread and the network thread. Shouldn't 332 // Called from both the configuration thread and the network thread. Shouldn't
284 // be called from the network thread in the future. 333 // be called from the network thread in the future.
285 rate_control_.SetMinBitrate(min_bitrate_bps); 334 rate_control_.SetMinBitrate(min_bitrate_bps);
286 } 335 }
287 336
288 int64_t DelayBasedBwe::GetExpectedBwePeriodMs() const { 337 int64_t DelayBasedBwe::GetExpectedBwePeriodMs() const {
289 return rate_control_.GetExpectedBandwidthPeriodMs(); 338 return rate_control_.GetExpectedBandwidthPeriodMs();
290 } 339 }
291 } // namespace webrtc 340 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698