OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |