diff options
Diffstat (limited to 'third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc')
-rw-r--r-- | third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc | 184 |
1 files changed, 112 insertions, 72 deletions
diff --git a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc index ef200869a6..8e1a3c4698 100644 --- a/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc +++ b/third_party/libwebrtc/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc @@ -132,7 +132,7 @@ LossBasedBweV2::LossBasedBweV2(const FieldTrialsView* key_value_config) instant_upper_bound_temporal_weights_.resize( config_->observation_window_size); CalculateTemporalWeights(); - hold_duration_ = kInitHoldDuration; + last_hold_info_.duration = kInitHoldDuration; } bool LossBasedBweV2::IsEnabled() const { @@ -149,6 +149,10 @@ bool LossBasedBweV2::ReadyToUseInStartPhase() const { return IsReady() && config_->use_in_start_phase; } +bool LossBasedBweV2::UseInStartPhase() const { + return config_->use_in_start_phase; +} + LossBasedBweV2::Result LossBasedBweV2::GetLossBasedResult() const { if (!IsReady()) { if (!IsEnabled()) { @@ -289,50 +293,69 @@ void LossBasedBweV2::UpdateBandwidthEstimate( /*new_estimate=*/best_candidate.loss_limited_bandwidth); // Bound the best candidate by the acked bitrate. if (increasing_when_loss_limited && IsValid(acknowledged_bitrate_)) { + double rampup_factor = config_->bandwidth_rampup_upper_bound_factor; + if (IsValid(last_hold_info_.rate) && + acknowledged_bitrate_ < + config_->bandwidth_rampup_hold_threshold * last_hold_info_.rate) { + rampup_factor = config_->bandwidth_rampup_upper_bound_factor_in_hold; + } + best_candidate.loss_limited_bandwidth = std::max(current_best_estimate_.loss_limited_bandwidth, std::min(best_candidate.loss_limited_bandwidth, - config_->bandwidth_rampup_upper_bound_factor * - (*acknowledged_bitrate_))); + rampup_factor * (*acknowledged_bitrate_))); + // Increase current estimate by at least 1kbps to make sure that the state + // will be switched to kIncreasing, thus padding is triggered. + if (loss_based_result_.state == LossBasedState::kDecreasing && + best_candidate.loss_limited_bandwidth == + current_best_estimate_.loss_limited_bandwidth) { + best_candidate.loss_limited_bandwidth = + current_best_estimate_.loss_limited_bandwidth + + DataRate::BitsPerSec(1); + } } } - current_best_estimate_ = best_candidate; - UpdateResult(); - - if (IsInLossLimitedState() && - (recovering_after_loss_timestamp_.IsInfinite() || - recovering_after_loss_timestamp_ + config_->delayed_increase_window < - last_send_time_most_recent_observation_)) { - bandwidth_limit_in_current_window_ = - std::max(kCongestionControllerMinBitrate, - current_best_estimate_.loss_limited_bandwidth * - config_->max_increase_factor); - recovering_after_loss_timestamp_ = last_send_time_most_recent_observation_; - } -} - -void LossBasedBweV2::UpdateResult() { DataRate bounded_bandwidth_estimate = DataRate::PlusInfinity(); if (IsValid(delay_based_estimate_)) { bounded_bandwidth_estimate = std::max(GetInstantLowerBound(), - std::min({current_best_estimate_.loss_limited_bandwidth, + std::min({best_candidate.loss_limited_bandwidth, GetInstantUpperBound(), delay_based_estimate_})); } else { - bounded_bandwidth_estimate = - std::max(GetInstantLowerBound(), - std::min(current_best_estimate_.loss_limited_bandwidth, - GetInstantUpperBound())); + bounded_bandwidth_estimate = std::max( + GetInstantLowerBound(), std::min(best_candidate.loss_limited_bandwidth, + GetInstantUpperBound())); + } + if (config_->bound_best_candidate && + bounded_bandwidth_estimate < best_candidate.loss_limited_bandwidth) { + RTC_LOG(LS_INFO) << "Resetting loss based BWE to " + << bounded_bandwidth_estimate.kbps() + << "due to loss. Avg loss rate: " + << GetAverageReportedLossRatio(); + current_best_estimate_.loss_limited_bandwidth = bounded_bandwidth_estimate; + current_best_estimate_.inherent_loss = 0; + } else { + current_best_estimate_ = best_candidate; + if (config_->lower_bound_by_acked_rate_factor > 0.0) { + current_best_estimate_.loss_limited_bandwidth = + std::max(current_best_estimate_.loss_limited_bandwidth, + GetInstantLowerBound()); + } } if (loss_based_result_.state == LossBasedState::kDecreasing && - last_hold_timestamp_ > last_send_time_most_recent_observation_ && + last_hold_info_.timestamp > last_send_time_most_recent_observation_ && bounded_bandwidth_estimate < delay_based_estimate_) { - // BWE is not allowed to increase during the HOLD duration. The purpose of + // Ensure that acked rate is the lower bound of HOLD rate. + if (config_->lower_bound_by_acked_rate_factor > 0.0) { + last_hold_info_.rate = + std::max(GetInstantLowerBound(), last_hold_info_.rate); + } + // BWE is not allowed to increase above the HOLD rate. The purpose of // HOLD is to not immediately ramp up BWE to a rate that may cause loss. - loss_based_result_.bandwidth_estimate = std::min( - loss_based_result_.bandwidth_estimate, bounded_bandwidth_estimate); + loss_based_result_.bandwidth_estimate = + std::min(last_hold_info_.rate, bounded_bandwidth_estimate); return; } @@ -359,22 +382,38 @@ void LossBasedBweV2::UpdateResult() { RTC_LOG(LS_INFO) << this << " " << "Switch to HOLD. Bounded BWE: " << bounded_bandwidth_estimate.kbps() - << ", duration: " << hold_duration_.seconds(); - last_hold_timestamp_ = - last_send_time_most_recent_observation_ + hold_duration_; - hold_duration_ = std::min(kMaxHoldDuration, - hold_duration_ * config_->hold_duration_factor); + << ", duration: " << last_hold_info_.duration.ms(); + last_hold_info_ = { + .timestamp = last_send_time_most_recent_observation_ + + last_hold_info_.duration, + .duration = + std::min(kMaxHoldDuration, last_hold_info_.duration * + config_->hold_duration_factor), + .rate = bounded_bandwidth_estimate}; } last_padding_info_ = PaddingInfo(); loss_based_result_.state = LossBasedState::kDecreasing; } else { - // Reset the HOLD duration if delay based estimate works to avoid getting + // Reset the HOLD info if delay based estimate works to avoid getting // stuck in low bitrate. - hold_duration_ = kInitHoldDuration; + last_hold_info_ = {.timestamp = Timestamp::MinusInfinity(), + .duration = kInitHoldDuration, + .rate = DataRate::PlusInfinity()}; last_padding_info_ = PaddingInfo(); loss_based_result_.state = LossBasedState::kDelayBasedEstimate; } loss_based_result_.bandwidth_estimate = bounded_bandwidth_estimate; + + if (IsInLossLimitedState() && + (recovering_after_loss_timestamp_.IsInfinite() || + recovering_after_loss_timestamp_ + config_->delayed_increase_window < + last_send_time_most_recent_observation_)) { + bandwidth_limit_in_current_window_ = + std::max(kCongestionControllerMinBitrate, + current_best_estimate_.loss_limited_bandwidth * + config_->max_increase_factor); + recovering_after_loss_timestamp_ = last_send_time_most_recent_observation_; + } } bool LossBasedBweV2::IsEstimateIncreasingWhenLossLimited( @@ -394,6 +433,10 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( FieldTrialParameter<bool> enabled("Enabled", true); FieldTrialParameter<double> bandwidth_rampup_upper_bound_factor( "BwRampupUpperBoundFactor", 1000000.0); + FieldTrialParameter<double> bandwidth_rampup_upper_bound_factor_in_hold( + "BwRampupUpperBoundInHoldFactor", 1000000.0); + FieldTrialParameter<double> bandwidth_rampup_hold_threshold( + "BwRampupUpperBoundHoldThreshold", 1.3); FieldTrialParameter<double> rampup_acceleration_max_factor( "BwRampupAccelMaxFactor", 0.0); FieldTrialParameter<TimeDelta> rampup_acceleration_maxout_time( @@ -445,12 +488,6 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( FieldTrialParameter<bool> not_increase_if_inherent_loss_less_than_average_loss( "NotIncreaseIfInherentLossLessThanAverageLoss", true); - FieldTrialParameter<double> high_loss_rate_threshold("HighLossRateThreshold", - 1.0); - FieldTrialParameter<DataRate> bandwidth_cap_at_high_loss_rate( - "BandwidthCapAtHighLossRate", DataRate::KilobitsPerSec(500.0)); - FieldTrialParameter<double> slope_of_bwe_high_loss_func( - "SlopeOfBweHighLossFunc", 1000); FieldTrialParameter<bool> not_use_acked_rate_in_alr("NotUseAckedRateInAlr", true); FieldTrialParameter<bool> use_in_start_phase("UseInStartPhase", false); @@ -461,9 +498,12 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( FieldTrialParameter<bool> use_byte_loss_rate("UseByteLossRate", false); FieldTrialParameter<TimeDelta> padding_duration("PaddingDuration", TimeDelta::Zero()); + FieldTrialParameter<bool> bound_best_candidate("BoundBestCandidate", false); if (key_value_config) { ParseFieldTrial({&enabled, &bandwidth_rampup_upper_bound_factor, + &bandwidth_rampup_upper_bound_factor_in_hold, + &bandwidth_rampup_hold_threshold, &rampup_acceleration_max_factor, &rampup_acceleration_maxout_time, &candidate_factors, @@ -491,16 +531,14 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( &max_increase_factor, &delayed_increase_window, ¬_increase_if_inherent_loss_less_than_average_loss, - &high_loss_rate_threshold, - &bandwidth_cap_at_high_loss_rate, - &slope_of_bwe_high_loss_func, ¬_use_acked_rate_in_alr, &use_in_start_phase, &min_num_observations, &lower_bound_by_acked_rate_factor, &hold_duration_factor, &use_byte_loss_rate, - &padding_duration}, + &padding_duration, + &bound_best_candidate}, key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2")); } @@ -511,6 +549,10 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( config.emplace(Config()); config->bandwidth_rampup_upper_bound_factor = bandwidth_rampup_upper_bound_factor.Get(); + config->bandwidth_rampup_upper_bound_factor_in_hold = + bandwidth_rampup_upper_bound_factor_in_hold.Get(); + config->bandwidth_rampup_hold_threshold = + bandwidth_rampup_hold_threshold.Get(); config->rampup_acceleration_max_factor = rampup_acceleration_max_factor.Get(); config->rampup_acceleration_maxout_time = rampup_acceleration_maxout_time.Get(); @@ -553,10 +595,6 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( config->delayed_increase_window = delayed_increase_window.Get(); config->not_increase_if_inherent_loss_less_than_average_loss = not_increase_if_inherent_loss_less_than_average_loss.Get(); - config->high_loss_rate_threshold = high_loss_rate_threshold.Get(); - config->bandwidth_cap_at_high_loss_rate = - bandwidth_cap_at_high_loss_rate.Get(); - config->slope_of_bwe_high_loss_func = slope_of_bwe_high_loss_func.Get(); config->not_use_acked_rate_in_alr = not_use_acked_rate_in_alr.Get(); config->use_in_start_phase = use_in_start_phase.Get(); config->min_num_observations = min_num_observations.Get(); @@ -565,7 +603,7 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig( config->hold_duration_factor = hold_duration_factor.Get(); config->use_byte_loss_rate = use_byte_loss_rate.Get(); config->padding_duration = padding_duration.Get(); - + config->bound_best_candidate = bound_best_candidate.Get(); return config; } @@ -582,6 +620,18 @@ bool LossBasedBweV2::IsConfigValid() const { << config_->bandwidth_rampup_upper_bound_factor; valid = false; } + if (config_->bandwidth_rampup_upper_bound_factor_in_hold <= 1.0) { + RTC_LOG(LS_WARNING) << "The bandwidth rampup upper bound factor in hold " + "must be greater than 1: " + << config_->bandwidth_rampup_upper_bound_factor_in_hold; + valid = false; + } + if (config_->bandwidth_rampup_hold_threshold < 0.0) { + RTC_LOG(LS_WARNING) << "The bandwidth rampup hold threshold must" + "must be non-negative.: " + << config_->bandwidth_rampup_hold_threshold; + valid = false; + } if (config_->rampup_acceleration_max_factor < 0.0) { RTC_LOG(LS_WARNING) << "The rampup acceleration max factor must be non-negative.: " @@ -739,12 +789,6 @@ bool LossBasedBweV2::IsConfigValid() const { << config_->delayed_increase_window.ms(); valid = false; } - if (config_->high_loss_rate_threshold <= 0.0 || - config_->high_loss_rate_threshold > 1.0) { - RTC_LOG(LS_WARNING) << "The high loss rate threshold must be in (0, 1]: " - << config_->high_loss_rate_threshold; - valid = false; - } if (config_->min_num_observations <= 0) { RTC_LOG(LS_WARNING) << "The min number of observations must be positive: " << config_->min_num_observations; @@ -834,15 +878,19 @@ DataRate LossBasedBweV2::GetCandidateBandwidthUpperBound() const { std::vector<LossBasedBweV2::ChannelParameters> LossBasedBweV2::GetCandidates( bool in_alr) const { + ChannelParameters best_estimate = current_best_estimate_; std::vector<DataRate> bandwidths; for (double candidate_factor : config_->candidate_factors) { bandwidths.push_back(candidate_factor * - current_best_estimate_.loss_limited_bandwidth); + best_estimate.loss_limited_bandwidth); } if (acknowledged_bitrate_.has_value() && config_->append_acknowledged_rate_candidate) { - if (!(config_->not_use_acked_rate_in_alr && in_alr)) { + if (!(config_->not_use_acked_rate_in_alr && in_alr) || + (config_->padding_duration > TimeDelta::Zero() && + last_padding_info_.padding_timestamp + config_->padding_duration >= + last_send_time_most_recent_observation_)) { bandwidths.push_back(*acknowledged_bitrate_ * config_->bandwidth_backoff_lower_bound_factor); } @@ -850,13 +898,13 @@ std::vector<LossBasedBweV2::ChannelParameters> LossBasedBweV2::GetCandidates( if (IsValid(delay_based_estimate_) && config_->append_delay_based_estimate_candidate) { - if (delay_based_estimate_ > current_best_estimate_.loss_limited_bandwidth) { + if (delay_based_estimate_ > best_estimate.loss_limited_bandwidth) { bandwidths.push_back(delay_based_estimate_); } } if (in_alr && config_->append_upper_bound_candidate_in_alr && - current_best_estimate_.loss_limited_bandwidth > GetInstantUpperBound()) { + best_estimate.loss_limited_bandwidth > GetInstantUpperBound()) { bandwidths.push_back(GetInstantUpperBound()); } @@ -866,10 +914,10 @@ std::vector<LossBasedBweV2::ChannelParameters> LossBasedBweV2::GetCandidates( std::vector<ChannelParameters> candidates; candidates.resize(bandwidths.size()); for (size_t i = 0; i < bandwidths.size(); ++i) { - ChannelParameters candidate = current_best_estimate_; - candidate.loss_limited_bandwidth = std::min( - bandwidths[i], std::max(current_best_estimate_.loss_limited_bandwidth, - candidate_bandwidth_upper_bound)); + ChannelParameters candidate = best_estimate; + candidate.loss_limited_bandwidth = + std::min(bandwidths[i], std::max(best_estimate.loss_limited_bandwidth, + candidate_bandwidth_upper_bound)); candidate.inherent_loss = GetFeasibleInherentLoss(candidate); candidates[i] = candidate; } @@ -1037,14 +1085,6 @@ void LossBasedBweV2::CalculateInstantUpperBound() { instant_limit = config_->instant_upper_bound_bandwidth_balance / (average_reported_loss_ratio - config_->instant_upper_bound_loss_offset); - if (average_reported_loss_ratio > config_->high_loss_rate_threshold) { - instant_limit = std::min( - instant_limit, DataRate::KilobitsPerSec(std::max( - static_cast<double>(min_bitrate_.kbps()), - config_->bandwidth_cap_at_high_loss_rate.kbps() - - config_->slope_of_bwe_high_loss_func * - average_reported_loss_ratio))); - } } cached_instant_upper_bound_ = instant_limit; |