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

Side by Side Diff: webrtc/modules/congestion_controller/probe_controller.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
11 #include "webrtc/modules/congestion_controller/probe_controller.h" 11 #include "webrtc/modules/congestion_controller/probe_controller.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <initializer_list> 14 #include <initializer_list>
15 15
16 #include "webrtc/rtc_base/logging.h" 16 #include "webrtc/rtc_base/logging.h"
17 #include "webrtc/rtc_base/safe_conversions.h" 17 #include "webrtc/rtc_base/safe_conversions.h"
18 #include "webrtc/system_wrappers/include/field_trial.h"
18 #include "webrtc/system_wrappers/include/metrics.h" 19 #include "webrtc/system_wrappers/include/metrics.h"
19 20
20 namespace webrtc { 21 namespace webrtc {
21 22
22 namespace { 23 namespace {
23 // Maximum waiting time from the time of initiating probing to getting 24 // Maximum waiting time from the time of initiating probing to getting
24 // the measured results back. 25 // the measured results back.
25 constexpr int64_t kMaxWaitingTimeForProbingResultMs = 1000; 26 constexpr int64_t kMaxWaitingTimeForProbingResultMs = 1000;
26 27
27 // Value of |min_bitrate_to_probe_further_bps_| that indicates 28 // Value of |min_bitrate_to_probe_further_bps_| that indicates
28 // further probing is disabled. 29 // further probing is disabled.
29 constexpr int kExponentialProbingDisabled = 0; 30 constexpr int kExponentialProbingDisabled = 0;
30 31
31 // Default probing bitrate limit. Applied only when the application didn't 32 // Default probing bitrate limit. Applied only when the application didn't
32 // specify max bitrate. 33 // specify max bitrate.
33 constexpr int64_t kDefaultMaxProbingBitrateBps = 5000000; 34 constexpr int64_t kDefaultMaxProbingBitrateBps = 5000000;
34 35
35 // This is a limit on how often probing can be done when there is a BW 36 // This is a limit on how often probing can be done when there is a BW
36 // drop detected in ALR. 37 // drop detected in ALR.
37 constexpr int64_t kAlrProbingIntervalMinMs = 5000; 38 constexpr int64_t kMinAlrProbingIntervalMs = 5000;
38 39
39 // Interval between probes when ALR periodic probing is enabled. 40 // Interval between probes when ALR periodic probing is enabled.
40 constexpr int64_t kAlrPeriodicProbingIntervalMs = 5000; 41 constexpr int64_t kAlrPeriodicProbingIntervalMs = 5000;
41 42
42 // Minimum probe bitrate percentage to probe further for repeated probes, 43 // Minimum probe bitrate percentage to probe further for repeated probes,
43 // relative to the previous probe. For example, if 1Mbps probe results in 44 // relative to the previous probe. For example, if 1Mbps probe results in
44 // 80kbps, then we'll probe again at 1.6Mbps. In that case second probe won't be 45 // 80kbps, then we'll probe again at 1.6Mbps. In that case second probe won't be
45 // sent if we get 600kbps from the first one. 46 // sent if we get 600kbps from the first one.
46 constexpr int kRepeatedProbeMinPercentage = 70; 47 constexpr int kRepeatedProbeMinPercentage = 70;
47 48
49 // Timeout for probing after leaving ALR. If the bitrate drops significantly,
50 // (as determined by the delay based estimator) and we leave ALR, then we will
51 // send a probe if we recover within |kLeftAlrTimeoutMs| ms.
52 constexpr int kAlrEndedTimeoutMs = 3000;
53
54 // Use probing to recover faster after large bitrate estimate drops.
55 constexpr char kBweRapidRecoveryExperiment[] =
56 "WebRTC-BweRapidRecoveryExperiment";
57
48 } // namespace 58 } // namespace
49 59
50 ProbeController::ProbeController(PacedSender* pacer, const Clock* clock) 60 ProbeController::ProbeController(PacedSender* pacer, const Clock* clock)
51 : pacer_(pacer), clock_(clock), enable_periodic_alr_probing_(false) { 61 : pacer_(pacer), clock_(clock), enable_periodic_alr_probing_(false) {
52 Reset(); 62 Reset();
63 in_rapid_recovery_experiment_ = webrtc::field_trial::FindFullName(
64 kBweRapidRecoveryExperiment) == "Enabled";
53 } 65 }
54 66
55 void ProbeController::SetBitrates(int64_t min_bitrate_bps, 67 void ProbeController::SetBitrates(int64_t min_bitrate_bps,
56 int64_t start_bitrate_bps, 68 int64_t start_bitrate_bps,
57 int64_t max_bitrate_bps) { 69 int64_t max_bitrate_bps) {
58 rtc::CritScope cs(&critsect_); 70 rtc::CritScope cs(&critsect_);
59 71
60 if (start_bitrate_bps > 0) { 72 if (start_bitrate_bps > 0) {
61 start_bitrate_bps_ = start_bitrate_bps; 73 start_bitrate_bps_ = start_bitrate_bps;
62 estimated_bitrate_bps_ = start_bitrate_bps; 74 estimated_bitrate_bps_ = start_bitrate_bps;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 << " Minimum to probe further: " 151 << " Minimum to probe further: "
140 << min_bitrate_to_probe_further_bps_; 152 << min_bitrate_to_probe_further_bps_;
141 153
142 if (min_bitrate_to_probe_further_bps_ != kExponentialProbingDisabled && 154 if (min_bitrate_to_probe_further_bps_ != kExponentialProbingDisabled &&
143 bitrate_bps > min_bitrate_to_probe_further_bps_) { 155 bitrate_bps > min_bitrate_to_probe_further_bps_) {
144 // Double the probing bitrate. 156 // Double the probing bitrate.
145 InitiateProbing(now_ms, {2 * bitrate_bps}, true); 157 InitiateProbing(now_ms, {2 * bitrate_bps}, true);
146 } 158 }
147 } 159 }
148 160
149 // Detect a drop in estimated BW when operating in ALR and not already
150 // probing. The current response is to initiate a single probe session at the
151 // previous bitrate and immediately use the reported bitrate as the new
152 // bitrate.
153 //
154 // If the probe session fails, the assumption is that this drop was a
155 // real one from a competing flow or something else on the network and
156 // it ramps up from bitrate_bps.
157 if (state_ == State::kProbingComplete &&
158 pacer_->GetApplicationLimitedRegionStartTime() &&
159 bitrate_bps < 2 * estimated_bitrate_bps_ / 3 &&
160 (now_ms - last_alr_probing_time_) > kAlrProbingIntervalMinMs) {
161 LOG(LS_INFO) << "Detected big BW drop in ALR, start probe.";
162 // Track how often we probe in response to BW drop in ALR.
163 RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.AlrProbingIntervalInS",
164 (now_ms - last_alr_probing_time_) / 1000);
165 InitiateProbing(now_ms, {estimated_bitrate_bps_}, false);
166 last_alr_probing_time_ = now_ms;
167
168 // TODO(isheriff): May want to track when we did ALR probing in order
169 // to reset |last_alr_probing_time_| if we validate that it was a
170 // drop due to exogenous event.
171 }
172
173 estimated_bitrate_bps_ = bitrate_bps; 161 estimated_bitrate_bps_ = bitrate_bps;
174 } 162 }
175 163
176 void ProbeController::EnablePeriodicAlrProbing(bool enable) { 164 void ProbeController::EnablePeriodicAlrProbing(bool enable) {
177 rtc::CritScope cs(&critsect_); 165 rtc::CritScope cs(&critsect_);
178 enable_periodic_alr_probing_ = enable; 166 enable_periodic_alr_probing_ = enable;
179 } 167 }
180 168
169 void ProbeController::SetAlrEndedTimeMs(int64_t alr_end_time_ms) {
170 rtc::CritScope cs(&critsect_);
171 alr_end_time_ms_.emplace(alr_end_time_ms);
172 }
173
174 void ProbeController::RequestProbe(uint32_t suggested_probing_bitrate_bps) {
175 int64_t now_ms = clock_->TimeInMilliseconds();
176 rtc::CritScope cs(&critsect_);
177 // Called once we have returned to normal state after a large drop in
178 // estimated bandwidth. The current response is to initiate a single probe
179 // session (if not already probing) at the previous bitrate.
180 //
181 // If the probe session fails, the assumption is that this drop was a
182 // real one from a competing flow or a network change.
183 if (state_ == State::kProbingComplete &&
184 suggested_probing_bitrate_bps > estimated_bitrate_bps_ &&
philipel 2017/07/25 11:26:04 You might want to use a factor of the probing bitr
terelius 2017/07/27 21:02:45 Done. I set the "probe uncertainty" to 5% of the t
185 (now_ms - last_bwe_drop_probing_time_ms_) > kMinAlrProbingIntervalMs) {
186 bool in_alr = pacer_->GetApplicationLimitedRegionStartTime().has_value();
187 bool alr_ended_recently =
188 (alr_end_time_ms_.has_value() &&
philipel 2017/07/25 11:26:04 I think it's cleaner to implement ALR end time in
terelius 2017/07/27 21:02:45 In principle, I agree. However, that would require
terelius 2017/07/28 17:14:47 Since the method you proposed will involve changes
philipel 2017/07/31 09:40:17 Acknowledged.
189 now_ms - alr_end_time_ms_.value() < kAlrEndedTimeoutMs);
190 if (in_alr || alr_ended_recently || in_rapid_recovery_experiment_) {
191 LOG(LS_INFO) << "Detected big bandwidth drop, start probing.";
192 // Track how often we probe in response to bandwidth drop in ALR.
193 RTC_HISTOGRAM_COUNTS_10000(
194 "WebRTC.BWE.BweDropProbingIntervalInS",
195 (now_ms - last_bwe_drop_probing_time_ms_) / 1000);
196 InitiateProbing(now_ms, {suggested_probing_bitrate_bps}, false);
197 last_bwe_drop_probing_time_ms_ = now_ms;
198
199 // TODO(isheriff): May want to track when we did ALR probing in order
philipel 2017/07/25 11:26:04 Does this comment make sense anymore? Otherwise re
terelius 2017/07/27 21:02:45 I have no idea what it means/meant. I just copied
terelius 2017/07/28 17:14:47 Removed it.
200 // to reset |last_bwe_drop_probing_time_ms_| if we validate that it was a
201 // drop due to exogenous event.
202 }
203 }
204 }
205
181 void ProbeController::Reset() { 206 void ProbeController::Reset() {
182 rtc::CritScope cs(&critsect_); 207 rtc::CritScope cs(&critsect_);
183 network_state_ = kNetworkUp; 208 network_state_ = kNetworkUp;
184 state_ = State::kInit; 209 state_ = State::kInit;
185 min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled; 210 min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
186 time_last_probing_initiated_ms_ = 0; 211 time_last_probing_initiated_ms_ = 0;
187 estimated_bitrate_bps_ = 0; 212 estimated_bitrate_bps_ = 0;
188 start_bitrate_bps_ = 0; 213 start_bitrate_bps_ = 0;
189 max_bitrate_bps_ = 0; 214 max_bitrate_bps_ = 0;
190 last_alr_probing_time_ = clock_->TimeInMilliseconds(); 215 last_bwe_drop_probing_time_ms_ = clock_->TimeInMilliseconds();
216 alr_end_time_ms_.reset();
191 mid_call_probing_waiting_for_result_ = false; 217 mid_call_probing_waiting_for_result_ = false;
192 } 218 }
193 219
194 void ProbeController::Process() { 220 void ProbeController::Process() {
195 rtc::CritScope cs(&critsect_); 221 rtc::CritScope cs(&critsect_);
196 222
197 int64_t now_ms = clock_->TimeInMilliseconds(); 223 int64_t now_ms = clock_->TimeInMilliseconds();
198 224
199 if (now_ms - time_last_probing_initiated_ms_ > 225 if (now_ms - time_last_probing_initiated_ms_ >
200 kMaxWaitingTimeForProbingResultMs) { 226 kMaxWaitingTimeForProbingResultMs) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 state_ = State::kWaitingForProbingResult; 268 state_ = State::kWaitingForProbingResult;
243 min_bitrate_to_probe_further_bps_ = 269 min_bitrate_to_probe_further_bps_ =
244 (*(bitrates_to_probe.end() - 1)) * kRepeatedProbeMinPercentage / 100; 270 (*(bitrates_to_probe.end() - 1)) * kRepeatedProbeMinPercentage / 100;
245 } else { 271 } else {
246 state_ = State::kProbingComplete; 272 state_ = State::kProbingComplete;
247 min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled; 273 min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled;
248 } 274 }
249 } 275 }
250 276
251 } // namespace webrtc 277 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698