Chromium Code Reviews| Index: webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc |
| diff --git a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc |
| index e47d4917e9fd66e46cf765b12aff157e16e8b571..f8247909059eab17e80e4582ec3b880745d7afa5 100644 |
| --- a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc |
| +++ b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc |
| @@ -29,6 +29,10 @@ const int kLimitNumPackets = 20; |
| const int kDefaultMinBitrateBps = 10000; |
| const int kDefaultMaxBitrateBps = 1000000000; |
| const int64_t kLowBitrateLogPeriodMs = 10000; |
| +// Expecting that RTCP feedback is sent uniformly within [0.5, 1.5]s intervals. |
| +const int64_t kFeedbackIntervalMs = 1500; |
| +const int64_t kFeedbackTimeoutIntervals = 3; |
| +const int64_t kTimeoutIntervalMs = 1000; |
| struct UmaRampUpMetric { |
| const char* metric_name; |
| @@ -52,7 +56,9 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) |
| max_bitrate_configured_(kDefaultMaxBitrateBps), |
| last_low_bitrate_log_ms_(-1), |
| has_decreased_since_last_fraction_loss_(false), |
| - time_last_receiver_block_ms_(-1), |
| + last_feedback_ms_(-1), |
| + last_packet_report_ms_(-1), |
| + last_timeout_ms_(-1), |
| last_fraction_loss_(0), |
| last_round_trip_time_ms_(0), |
| bwe_incoming_(0), |
| @@ -63,7 +69,9 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) |
| bitrate_at_2_seconds_kbps_(0), |
| uma_update_state_(kNoUpdate), |
| rampup_uma_stats_updated_(kNumUmaRampupMetrics, false), |
| - event_log_(event_log) { |
| + event_log_(event_log), |
| + in_timeout_experiment_(webrtc::field_trial::FindFullName( |
| + "WebRTC-SendSideBwe") == "Enabled") { |
| RTC_DCHECK(event_log); |
| } |
| @@ -127,6 +135,7 @@ void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, |
| int64_t rtt, |
| int number_of_packets, |
| int64_t now_ms) { |
| + last_feedback_ms_ = now_ms; |
| if (first_report_time_ms_ == -1) |
| first_report_time_ms_ = now_ms; |
| @@ -152,9 +161,9 @@ void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss, |
| // Reset accumulators. |
| lost_packets_since_last_loss_update_Q8_ = 0; |
| expected_packets_since_last_loss_update_ = 0; |
| + last_packet_report_ms_ = now_ms; |
| + UpdateEstimate(now_ms); |
|
terelius
2016/08/23 17:33:29
Nice. I've been meaning to try moving the UpdateEs
|
| } |
| - time_last_receiver_block_ms_ = now_ms; |
| - UpdateEstimate(now_ms); |
| UpdateUmaStats(now_ms, rtt, (fraction_loss * number_of_packets) >> 8); |
| } |
| @@ -198,8 +207,9 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| uint32_t prev_bitrate = bitrate_; |
| if (bwe_incoming_ > bitrate_) |
| bitrate_ = CapBitrateToThresholds(now_ms, bwe_incoming_); |
| - if (delay_based_bitrate_bps_ > bitrate_) |
| + if (delay_based_bitrate_bps_ > bitrate_) { |
| bitrate_ = CapBitrateToThresholds(now_ms, delay_based_bitrate_bps_); |
| + } |
| if (bitrate_ != prev_bitrate) { |
| min_bitrate_history_.clear(); |
| min_bitrate_history_.push_back(std::make_pair(now_ms, bitrate_)); |
| @@ -207,10 +217,14 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| } |
| } |
| UpdateMinHistory(now_ms); |
| - // Only start updating bitrate when receiving receiver blocks. |
| - // TODO(pbos): Handle the case when no receiver report is received for a very |
| - // long time. |
| - if (time_last_receiver_block_ms_ != -1) { |
| + if (last_packet_report_ms_ == -1) { |
| + // No feedback received. |
| + bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
| + return; |
| + } |
| + int64_t time_since_packet_report_ms = now_ms - last_packet_report_ms_; |
| + int64_t time_since_feedback_ms = now_ms - last_feedback_ms_; |
| + if (time_since_packet_report_ms < 1.2 * kFeedbackIntervalMs) { |
| if (last_fraction_loss_ <= 5) { |
| // Loss < 2%: Increase rate by 8% of the min bitrate in the last |
| // kBweIncreaseIntervalMs. |
| @@ -220,7 +234,8 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| // If sending a constant 100kbps it can rampup immediatly to 108kbps |
| // whenever a receiver report is received with lower packet loss. |
| // If instead one would do: bitrate_ *= 1.08^(delta time), it would |
| - // take over one second since the lower packet loss to achieve 108kbps. |
| + // take over one second since the lower packet loss to achieve |
| + // 108kbps. |
| bitrate_ = static_cast<uint32_t>( |
| min_bitrate_history_.front().second * 1.08 + 0.5); |
| @@ -235,8 +250,8 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| } else if (last_fraction_loss_ <= 26) { |
| // Loss between 2% - 10%: Do nothing. |
| } else { |
| - // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs + |
| - // rtt. |
| + // Loss > 10%: Limit the rate decreases to once a kBweDecreaseIntervalMs |
| + // + rtt. |
| if (!has_decreased_since_last_fraction_loss_ && |
| (now_ms - time_last_decrease_ms_) >= |
| (kBweDecreaseIntervalMs + last_round_trip_time_ms_)) { |
| @@ -254,6 +269,16 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| bitrate_, last_fraction_loss_, |
| expected_packets_since_last_loss_update_); |
| } |
| + } else if (time_since_feedback_ms > |
| + kFeedbackTimeoutIntervals * kFeedbackIntervalMs && |
| + (last_timeout_ms_ == -1 || |
| + now_ms - last_timeout_ms_ > kTimeoutIntervalMs)) { |
| + if (in_timeout_experiment_) { |
| + LOG(LS_WARNING) << "Feedback timed out (" << time_since_feedback_ms |
| + << " ms), reducing bitrate."; |
| + bitrate_ *= 0.8; |
| + last_timeout_ms_ = now_ms; |
|
terelius
2016/08/23 17:33:29
Should the accumulators (expected_packets_since_la
stefan-webrtc
2016/09/04 11:17:35
Perhaps we should reset those too.
|
| + } |
| } |
| bitrate_ = CapBitrateToThresholds(now_ms, bitrate_); |
| } |