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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 | 148 |
| 149 namespace webrtc { | 149 namespace webrtc { |
| 150 | 150 |
| 151 DelayBasedBwe::BitrateEstimator::BitrateEstimator() | 151 DelayBasedBwe::BitrateEstimator::BitrateEstimator() |
| 152 : sum_(0), | 152 : sum_(0), |
| 153 current_win_ms_(0), | 153 current_win_ms_(0), |
| 154 prev_time_ms_(-1), | 154 prev_time_ms_(-1), |
| 155 bitrate_estimate_(-1.0f), | 155 bitrate_estimate_(-1.0f), |
| 156 bitrate_estimate_var_(50.0f), | 156 bitrate_estimate_var_(50.0f), |
| 157 old_estimator_(kBitrateWindowMs, 8000), | 157 old_estimator_(kBitrateWindowMs, 8000), |
| 158 in_experiment_(BitrateEstimateExperimentIsEnabled()) {} | 158 in_experiment_(BitrateEstimateExperimentIsEnabled()), |
| 159 last_result_was_valid_(false) {} | |
| 159 | 160 |
| 160 void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) { | 161 void DelayBasedBwe::BitrateEstimator::Update(int64_t now_ms, int bytes) { |
| 161 if (!in_experiment_) { | 162 if (!in_experiment_) { |
| 162 old_estimator_.Update(bytes, now_ms); | 163 old_estimator_.Update(bytes, now_ms); |
| 163 rtc::Optional<uint32_t> rate = old_estimator_.Rate(now_ms); | 164 rtc::Optional<uint32_t> rate = old_estimator_.Rate(now_ms); |
| 164 bitrate_estimate_ = -1.0f; | 165 bitrate_estimate_ = -1.0f; |
| 165 if (rate) | 166 if (rate) { |
| 166 bitrate_estimate_ = *rate / 1000.0f; | 167 bitrate_estimate_ = *rate / 1000.0f; |
| 168 last_result_was_valid_ = true; | |
|
terelius
2017/03/29 15:14:29
I'm a little bit worried that this might reset the
michaelt
2017/04/11 11:04:33
Ok the hack is removed.
| |
| 169 } else if (last_result_was_valid_) { | |
| 170 old_estimator_.Reset(); | |
| 171 last_result_was_valid_ = false; | |
| 172 } | |
| 167 return; | 173 return; |
| 168 } | 174 } |
| 169 int rate_window_ms = kRateWindowMs; | 175 int rate_window_ms = kRateWindowMs; |
| 170 // We use a larger window at the beginning to get a more stable sample that | 176 // We use a larger window at the beginning to get a more stable sample that |
| 171 // we can use to initialize the estimate. | 177 // we can use to initialize the estimate. |
| 172 if (bitrate_estimate_ < 0.f) | 178 if (bitrate_estimate_ < 0.f) |
| 173 rate_window_ms = kInitialRateWindowMs; | 179 rate_window_ms = kInitialRateWindowMs; |
| 174 float bitrate_sample = UpdateWindow(now_ms, bytes, rate_window_ms); | 180 float bitrate_sample = UpdateWindow(now_ms, bytes, rate_window_ms); |
| 175 if (bitrate_sample < 0.0f) | 181 if (bitrate_sample < 0.0f) |
| 176 return; | 182 return; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 233 DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) | 239 DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log, const Clock* clock) |
| 234 : in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()), | 240 : in_trendline_experiment_(TrendlineFilterExperimentIsEnabled()), |
| 235 in_median_slope_experiment_(MedianSlopeFilterExperimentIsEnabled()), | 241 in_median_slope_experiment_(MedianSlopeFilterExperimentIsEnabled()), |
| 236 event_log_(event_log), | 242 event_log_(event_log), |
| 237 clock_(clock), | 243 clock_(clock), |
| 238 inter_arrival_(), | 244 inter_arrival_(), |
| 239 kalman_estimator_(), | 245 kalman_estimator_(), |
| 240 trendline_estimator_(), | 246 trendline_estimator_(), |
| 241 detector_(), | 247 detector_(), |
| 242 receiver_incoming_bitrate_(), | 248 receiver_incoming_bitrate_(), |
| 243 last_update_ms_(-1), | |
| 244 last_seen_packet_ms_(-1), | 249 last_seen_packet_ms_(-1), |
| 245 uma_recorded_(false), | 250 uma_recorded_(false), |
| 246 probe_bitrate_estimator_(event_log), | 251 probe_bitrate_estimator_(event_log), |
| 247 trendline_window_size_(kDefaultTrendlineWindowSize), | 252 trendline_window_size_(kDefaultTrendlineWindowSize), |
| 248 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), | 253 trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), |
| 249 trendline_threshold_gain_(kDefaultTrendlineThresholdGain), | 254 trendline_threshold_gain_(kDefaultTrendlineThresholdGain), |
| 250 probing_interval_estimator_(&rate_control_), | 255 probing_interval_estimator_(&rate_control_), |
| 251 median_slope_window_size_(kDefaultMedianSlopeWindowSize), | 256 median_slope_window_size_(kDefaultMedianSlopeWindowSize), |
| 252 median_slope_threshold_gain_(kDefaultMedianSlopeThresholdGain), | 257 median_slope_threshold_gain_(kDefaultMedianSlopeThresholdGain), |
| 253 consecutive_delayed_feedbacks_(0), | 258 consecutive_delayed_feedbacks_(0), |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 283 std::vector<PacketFeedback> sorted_packet_feedback_vector; | 288 std::vector<PacketFeedback> sorted_packet_feedback_vector; |
| 284 SortPacketFeedbackVector(packet_feedback_vector, | 289 SortPacketFeedbackVector(packet_feedback_vector, |
| 285 &sorted_packet_feedback_vector); | 290 &sorted_packet_feedback_vector); |
| 286 | 291 |
| 287 if (!uma_recorded_) { | 292 if (!uma_recorded_) { |
| 288 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, | 293 RTC_HISTOGRAM_ENUMERATION(kBweTypeHistogram, |
| 289 BweNames::kSendSideTransportSeqNum, | 294 BweNames::kSendSideTransportSeqNum, |
| 290 BweNames::kBweNamesMax); | 295 BweNames::kBweNamesMax); |
| 291 uma_recorded_ = true; | 296 uma_recorded_ = true; |
| 292 } | 297 } |
| 293 Result aggregated_result; | 298 bool overusing = false; |
| 294 bool delayed_feedback = true; | 299 bool delayed_feedback = true; |
| 295 for (const auto& packet_feedback : sorted_packet_feedback_vector) { | 300 for (const auto& packet_feedback : sorted_packet_feedback_vector) { |
| 296 if (packet_feedback.send_time_ms < 0) | 301 if (packet_feedback.send_time_ms < 0) |
| 297 continue; | 302 continue; |
| 298 delayed_feedback = false; | 303 delayed_feedback = false; |
| 299 Result result = IncomingPacketFeedback(packet_feedback); | 304 IncomingPacketFeedback(packet_feedback); |
| 300 if (result.updated) | 305 overusing |= detector_.State() == kBwOverusing; |
| 301 aggregated_result = result; | |
| 302 } | 306 } |
| 303 if (delayed_feedback) { | 307 if (delayed_feedback) { |
| 304 ++consecutive_delayed_feedbacks_; | 308 ++consecutive_delayed_feedbacks_; |
| 305 } else { | 309 } else { |
| 306 consecutive_delayed_feedbacks_ = 0; | 310 consecutive_delayed_feedbacks_ = 0; |
| 307 } | 311 } |
| 308 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { | 312 if (consecutive_delayed_feedbacks_ >= kMaxConsecutiveFailedLookups) { |
| 309 aggregated_result = OnLongFeedbackDelay( | 313 consecutive_delayed_feedbacks_ = 0; |
| 314 return OnLongFeedbackDelay( | |
| 310 sorted_packet_feedback_vector.back().arrival_time_ms); | 315 sorted_packet_feedback_vector.back().arrival_time_ms); |
| 311 consecutive_delayed_feedbacks_ = 0; | |
| 312 } | 316 } |
| 313 return aggregated_result; | 317 return MaybeUpdateEstimate(overusing); |
| 314 } | 318 } |
| 315 | 319 |
| 316 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( | 320 DelayBasedBwe::Result DelayBasedBwe::OnLongFeedbackDelay( |
| 317 int64_t arrival_time_ms) { | 321 int64_t arrival_time_ms) { |
| 318 // Estimate should always be valid since a start bitrate always is set in the | 322 // Estimate should always be valid since a start bitrate always is set in the |
| 319 // Call constructor. An alternative would be to return an empty Result here, | 323 // Call constructor. An alternative would be to return an empty Result here, |
| 320 // or to estimate the throughput based on the feedback we received. | 324 // or to estimate the throughput based on the feedback we received. |
| 321 RTC_DCHECK(rate_control_.ValidEstimate()); | 325 RTC_DCHECK(rate_control_.ValidEstimate()); |
| 322 rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, | 326 rate_control_.SetEstimate(rate_control_.LatestEstimate() / 2, |
| 323 arrival_time_ms); | 327 arrival_time_ms); |
| 324 Result result; | 328 Result result; |
| 325 result.updated = true; | 329 result.updated = true; |
| 326 result.probe = false; | 330 result.probe = false; |
| 327 result.target_bitrate_bps = rate_control_.LatestEstimate(); | 331 result.target_bitrate_bps = rate_control_.LatestEstimate(); |
| 328 LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " | 332 LOG(LS_WARNING) << "Long feedback delay detected, reducing BWE to " |
| 329 << result.target_bitrate_bps; | 333 << result.target_bitrate_bps; |
| 330 return result; | 334 return result; |
| 331 } | 335 } |
| 332 | 336 |
| 333 DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedback( | 337 void DelayBasedBwe::IncomingPacketFeedback( |
| 334 const PacketFeedback& packet_feedback) { | 338 const PacketFeedback& packet_feedback) { |
| 335 int64_t now_ms = clock_->TimeInMilliseconds(); | 339 int64_t now_ms = clock_->TimeInMilliseconds(); |
| 336 | 340 |
| 337 receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, | 341 receiver_incoming_bitrate_.Update(packet_feedback.arrival_time_ms, |
| 338 packet_feedback.payload_size); | 342 packet_feedback.payload_size); |
| 339 Result result; | 343 Result result; |
| 340 // Reset if the stream has timed out. | 344 // Reset if the stream has timed out. |
| 341 if (last_seen_packet_ms_ == -1 || | 345 if (last_seen_packet_ms_ == -1 || |
| 342 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { | 346 now_ms - last_seen_packet_ms_ > kStreamTimeOutMs) { |
| 343 inter_arrival_.reset( | 347 inter_arrival_.reset( |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 packet_feedback.arrival_time_ms); | 388 packet_feedback.arrival_time_ms); |
| 385 } else { | 389 } else { |
| 386 kalman_estimator_->Update(t_delta, ts_delta_ms, size_delta, | 390 kalman_estimator_->Update(t_delta, ts_delta_ms, size_delta, |
| 387 detector_.State(), | 391 detector_.State(), |
| 388 packet_feedback.arrival_time_ms); | 392 packet_feedback.arrival_time_ms); |
| 389 detector_.Detect(kalman_estimator_->offset(), ts_delta_ms, | 393 detector_.Detect(kalman_estimator_->offset(), ts_delta_ms, |
| 390 kalman_estimator_->num_of_deltas(), | 394 kalman_estimator_->num_of_deltas(), |
| 391 packet_feedback.arrival_time_ms); | 395 packet_feedback.arrival_time_ms); |
| 392 } | 396 } |
| 393 } | 397 } |
| 394 | |
| 395 int probing_bps = 0; | |
| 396 if (packet_feedback.pacing_info.probe_cluster_id != | 398 if (packet_feedback.pacing_info.probe_cluster_id != |
| 397 PacedPacketInfo::kNotAProbe) { | 399 PacedPacketInfo::kNotAProbe) { |
| 398 probing_bps = | 400 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); |
| 399 probe_bitrate_estimator_.HandleProbeAndEstimateBitrate(packet_feedback); | |
| 400 } | 401 } |
| 402 } | |
| 403 | |
| 404 DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate(bool overusing) { | |
| 405 Result result; | |
| 401 rtc::Optional<uint32_t> acked_bitrate_bps = | 406 rtc::Optional<uint32_t> acked_bitrate_bps = |
| 402 receiver_incoming_bitrate_.bitrate_bps(); | 407 receiver_incoming_bitrate_.bitrate_bps(); |
| 408 int64_t now_ms = clock_->TimeInMilliseconds(); | |
| 409 rtc::Optional<int> probe_bitrate_bps = | |
| 410 probe_bitrate_estimator_.FetchAndResetLastEstimatedBitrateBps(); | |
| 403 // Currently overusing the bandwidth. | 411 // Currently overusing the bandwidth. |
| 404 if (detector_.State() == kBwOverusing) { | 412 if (overusing) { |
| 405 if (acked_bitrate_bps && | 413 if (acked_bitrate_bps && |
| 406 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { | 414 rate_control_.TimeToReduceFurther(now_ms, *acked_bitrate_bps)) { |
| 407 result.updated = | 415 result.updated = |
| 408 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 416 UpdateEstimate(now_ms, acked_bitrate_bps, overusing, &result); |
| 409 acked_bitrate_bps, &result.target_bitrate_bps); | |
| 410 } | 417 } |
| 411 } else if (probing_bps > 0) { | 418 } else { |
| 412 // No overuse, but probing measured a bitrate. | 419 if (probe_bitrate_bps) { |
| 413 rate_control_.SetEstimate(probing_bps, packet_feedback.arrival_time_ms); | 420 rate_control_.SetEstimate(*probe_bitrate_bps, now_ms); |
| 414 result.probe = true; | 421 result.probe = true; |
| 422 } | |
| 415 result.updated = | 423 result.updated = |
| 416 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | 424 UpdateEstimate(now_ms, acked_bitrate_bps, overusing, &result); |
| 417 acked_bitrate_bps, &result.target_bitrate_bps); | |
| 418 } | |
| 419 if (!result.updated && | |
| 420 (last_update_ms_ == -1 || | |
| 421 now_ms - last_update_ms_ > rate_control_.GetFeedbackInterval())) { | |
| 422 result.updated = | |
| 423 UpdateEstimate(packet_feedback.arrival_time_ms, now_ms, | |
| 424 acked_bitrate_bps, &result.target_bitrate_bps); | |
| 425 } | 425 } |
| 426 if (result.updated) { | 426 if (result.updated) { |
| 427 last_update_ms_ = now_ms; | |
| 428 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, | 427 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, |
| 429 result.target_bitrate_bps); | 428 result.target_bitrate_bps); |
| 430 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || | 429 if (event_log_ && (result.target_bitrate_bps != last_logged_bitrate_ || |
| 431 detector_.State() != last_logged_state_)) { | 430 detector_.State() != last_logged_state_)) { |
| 432 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, | 431 event_log_->LogDelayBasedBweUpdate(result.target_bitrate_bps, |
| 433 detector_.State()); | 432 detector_.State()); |
| 434 last_logged_bitrate_ = result.target_bitrate_bps; | 433 last_logged_bitrate_ = result.target_bitrate_bps; |
| 435 last_logged_state_ = detector_.State(); | 434 last_logged_state_ = detector_.State(); |
| 436 } | 435 } |
| 437 } | 436 } |
| 438 | |
| 439 return result; | 437 return result; |
| 440 } | 438 } |
| 441 | 439 |
| 442 bool DelayBasedBwe::UpdateEstimate(int64_t arrival_time_ms, | 440 bool DelayBasedBwe::UpdateEstimate(int64_t now_ms, |
| 443 int64_t now_ms, | |
| 444 rtc::Optional<uint32_t> acked_bitrate_bps, | 441 rtc::Optional<uint32_t> acked_bitrate_bps, |
| 445 uint32_t* target_bitrate_bps) { | 442 bool overusing, |
| 443 Result* result) { | |
| 446 // TODO(terelius): RateControlInput::noise_var is deprecated and will be | 444 // TODO(terelius): RateControlInput::noise_var is deprecated and will be |
| 447 // removed. In the meantime, we set it to zero. | 445 // removed. In the meantime, we set it to zero. |
| 448 const RateControlInput input(detector_.State(), acked_bitrate_bps, 0); | 446 const RateControlInput input(overusing ? kBwOverusing : detector_.State(), |
| 447 acked_bitrate_bps, 0); | |
| 449 rate_control_.Update(&input, now_ms); | 448 rate_control_.Update(&input, now_ms); |
| 450 *target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); | 449 result->target_bitrate_bps = rate_control_.UpdateBandwidthEstimate(now_ms); |
| 450 BWE_TEST_LOGGING_PLOT(1, "target_bitrate_bps", now_ms, | |
| 451 result->target_bitrate_bps); | |
| 451 return rate_control_.ValidEstimate(); | 452 return rate_control_.ValidEstimate(); |
| 452 } | 453 } |
| 453 | 454 |
| 454 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { | 455 void DelayBasedBwe::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) { |
| 455 rate_control_.SetRtt(avg_rtt_ms); | 456 rate_control_.SetRtt(avg_rtt_ms); |
| 456 } | 457 } |
| 457 | 458 |
| 458 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, | 459 bool DelayBasedBwe::LatestEstimate(std::vector<uint32_t>* ssrcs, |
| 459 uint32_t* bitrate_bps) const { | 460 uint32_t* bitrate_bps) const { |
| 460 // Currently accessed from both the process thread (see | 461 // Currently accessed from both the process thread (see |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 479 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { | 480 void DelayBasedBwe::SetMinBitrate(int min_bitrate_bps) { |
| 480 // Called from both the configuration thread and the network thread. Shouldn't | 481 // Called from both the configuration thread and the network thread. Shouldn't |
| 481 // be called from the network thread in the future. | 482 // be called from the network thread in the future. |
| 482 rate_control_.SetMinBitrate(min_bitrate_bps); | 483 rate_control_.SetMinBitrate(min_bitrate_bps); |
| 483 } | 484 } |
| 484 | 485 |
| 485 int64_t DelayBasedBwe::GetProbingIntervalMs() const { | 486 int64_t DelayBasedBwe::GetProbingIntervalMs() const { |
| 486 return probing_interval_estimator_.GetIntervalMs(); | 487 return probing_interval_estimator_.GetIntervalMs(); |
| 487 } | 488 } |
| 488 } // namespace webrtc | 489 } // namespace webrtc |
| OLD | NEW |