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 f2338b9c00e21c47d002b7b4c0539f0f2ec73d1c..a52106d2ca963b1ef0471b8c14fced63eeb066a8 100644 |
| --- a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc |
| +++ b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc |
| @@ -12,6 +12,7 @@ |
| #include <algorithm> |
| #include <cmath> |
| +#include <string> |
| #include "webrtc/base/checks.h" |
| #include "webrtc/base/logging.h" |
| @@ -35,6 +36,10 @@ const int64_t kFeedbackIntervalMs = 1500; |
| const int64_t kFeedbackTimeoutIntervals = 3; |
| const int64_t kTimeoutIntervalMs = 1000; |
| +const float kDefaultLowLossThreshold = 0.02f; |
| +const float kDefaultHighLossThreshold = 0.1f; |
| +const int kDefaultBitrateThresholdKbps = 0; |
| + |
| struct UmaRampUpMetric { |
| const char* metric_name; |
| int bitrate_kbps; |
| @@ -47,6 +52,49 @@ const UmaRampUpMetric kUmaRampupMetrics[] = { |
| const size_t kNumUmaRampupMetrics = |
| sizeof(kUmaRampupMetrics) / sizeof(kUmaRampupMetrics[0]); |
| +const char kBweLosExperiment[] = "WebRTC-BweLossExperiment"; |
| + |
| +bool BweLossExperimentIsEnabled() { |
| + std::string experiment_string = |
| + webrtc::field_trial::FindFullName(kBweLosExperiment); |
| + // The experiment is enabled iff the field trial string begins with "Enabled". |
| + return experiment_string.find("Enabled") == 0; |
| +} |
| + |
| +bool ReadBweLossExperimentParameters(float* low_loss_threshold, |
| + float* high_loss_threshold, |
| + uint32_t* bitrate_threshold_kbps) { |
| + RTC_DCHECK(low_loss_threshold); |
| + RTC_DCHECK(high_loss_threshold); |
| + RTC_DCHECK(bitrate_threshold_kbps); |
| + std::string experiment_string = |
| + webrtc::field_trial::FindFullName(kBweLosExperiment); |
| + int parsed_values = |
| + sscanf(experiment_string.c_str(), "Enabled-%f,%f,%u", low_loss_threshold, |
| + high_loss_threshold, bitrate_threshold_kbps); |
| + if (parsed_values == 3) { |
| + RTC_CHECK_GT(*low_loss_threshold, 0.0f) |
| + << "Loss threshold must be greater than 0."; |
| + RTC_CHECK_LE(*low_loss_threshold, 1.0f) |
| + << "Loss threshold must be less than or equal to 1."; |
| + RTC_CHECK_GT(*high_loss_threshold, 0.0f) |
| + << "Loss threshold must be greater than 0."; |
| + RTC_CHECK_LE(*high_loss_threshold, 1.0f) |
| + << "Loss threshold must be less than or equal to 1."; |
| + RTC_CHECK_LE(*low_loss_threshold, *high_loss_threshold) |
| + << "The low loss threshold must be less than or equal to the high loss " |
| + "threshold."; |
| + RTC_CHECK_GE(*bitrate_threshold_kbps, 0) |
|
terelius
2017/03/31 08:24:33
I'd like to also check that bitrate_threshold_kbps
stefan-webrtc
2017/03/31 13:51:05
Done.
|
| + << "Bitrate threshold can't be negative."; |
| + return true; |
| + } |
| + LOG(LS_WARNING) << "Failed to parse parameters for BweLossExperiment " |
| + "experiment from field trial string. Using default."; |
| + *low_loss_threshold = kDefaultLowLossThreshold; |
| + *high_loss_threshold = kDefaultHighLossThreshold; |
| + *bitrate_threshold_kbps = kDefaultBitrateThresholdKbps; |
| + return false; |
| +} |
| } // namespace |
| SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) |
| @@ -74,8 +122,22 @@ SendSideBandwidthEstimation::SendSideBandwidthEstimation(RtcEventLog* event_log) |
| event_log_(event_log), |
| last_rtc_event_log_ms_(-1), |
| in_timeout_experiment_( |
| - webrtc::field_trial::IsEnabled("WebRTC-FeedbackTimeout")) { |
| + webrtc::field_trial::IsEnabled("WebRTC-FeedbackTimeout")), |
| + low_loss_threshold_(kDefaultLowLossThreshold), |
| + high_loss_threshold_(kDefaultHighLossThreshold), |
| + bitrate_threshold_bps_(1000 * kDefaultBitrateThresholdKbps) { |
| RTC_DCHECK(event_log); |
| + if (BweLossExperimentIsEnabled()) { |
| + uint32_t bitrate_threshold_kbps; |
| + if (ReadBweLossExperimentParameters(&low_loss_threshold_, |
| + &high_loss_threshold_, |
| + &bitrate_threshold_kbps)) { |
| + LOG(LS_INFO) << "Enabled BweLossExperiment with parameters " |
| + << low_loss_threshold_ << ", " << high_loss_threshold_ |
| + << ", " << bitrate_threshold_kbps; |
| + bitrate_threshold_bps_ = bitrate_threshold_kbps * 1000; |
| + } |
| + } |
| } |
| SendSideBandwidthEstimation::~SendSideBandwidthEstimation() {} |
| @@ -229,7 +291,12 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| 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) { |
| + // We only care about loss above a given bitrate threshold. |
| + float loss = last_fraction_loss_ / 256.0f; |
| + // We only make decisions based on loss when the bitrate is above a |
| + // threshold. This is a crude way of handling loss which is uncorrelated |
| + // to congestion. |
| + if (bitrate_ < bitrate_threshold_bps_ || loss <= low_loss_threshold_) { |
| // Loss < 2%: Increase rate by 8% of the min bitrate in the last |
| // kBweIncreaseIntervalMs. |
| // Note that by remembering the bitrate over the last second one can |
| @@ -247,23 +314,25 @@ void SendSideBandwidthEstimation::UpdateEstimate(int64_t now_ms) { |
| // (gives a little extra increase at low rates, negligible at higher |
| // rates). |
| bitrate_ += 1000; |
| - } else if (last_fraction_loss_ <= 26) { |
| - // Loss between 2% - 10%: Do nothing. |
| - } else { |
| - // 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_)) { |
| - time_last_decrease_ms_ = now_ms; |
| - |
| - // Reduce rate: |
| - // newRate = rate * (1 - 0.5*lossRate); |
| - // where packetLoss = 256*lossRate; |
| - bitrate_ = static_cast<uint32_t>( |
| - (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / |
| - 512.0); |
| - has_decreased_since_last_fraction_loss_ = true; |
| + } else if (bitrate_ > bitrate_threshold_bps_) { |
| + if (loss <= high_loss_threshold_) { |
| + // Loss between 2% - 10%: Do nothing. |
| + } else { |
| + // 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_)) { |
| + time_last_decrease_ms_ = now_ms; |
| + |
| + // Reduce rate: |
| + // newRate = rate * (1 - 0.5*lossRate); |
| + // where packetLoss = 256*lossRate; |
| + bitrate_ = static_cast<uint32_t>( |
| + (bitrate_ * static_cast<double>(512 - last_fraction_loss_)) / |
| + 512.0); |
| + has_decreased_since_last_fraction_loss_ = true; |
| + } |
| } |
| } |
| } else if (time_since_feedback_ms > |