Chromium Code Reviews| 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 |