Use acked bitrate as lower bound of loss based BWE.
This cl/ makes sure that the estimate cannot go lower than a factor of acked bitrate. The current flag LowerBoundByAckedRateFactor is set to 0, means we dont use it. Bug: webrtc:12707 Change-Id: I75d5881f0b85a374af3f7039b82c71aee97fb7b0 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/323881 Reviewed-by: Per Kjellander <perkj@webrtc.org> Commit-Queue: Diep Bui <diepbp@webrtc.org> Cr-Commit-Position: refs/heads/main@{#40958}
This commit is contained in:
parent
8e18e2e085
commit
8ef094f66a
@ -164,11 +164,14 @@ LossBasedBweV2::Result LossBasedBweV2::GetLossBasedResult() const {
|
||||
|
||||
if (IsValid(delay_based_estimate_)) {
|
||||
result.bandwidth_estimate =
|
||||
std::min({current_estimate_.loss_limited_bandwidth,
|
||||
GetInstantUpperBound(), delay_based_estimate_});
|
||||
std::max(GetInstantLowerBound(),
|
||||
std::min({current_estimate_.loss_limited_bandwidth,
|
||||
GetInstantUpperBound(), delay_based_estimate_}));
|
||||
} else {
|
||||
result.bandwidth_estimate = std::min(
|
||||
current_estimate_.loss_limited_bandwidth, GetInstantUpperBound());
|
||||
result.bandwidth_estimate =
|
||||
std::max(GetInstantLowerBound(),
|
||||
std::min(current_estimate_.loss_limited_bandwidth,
|
||||
GetInstantUpperBound()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -176,6 +179,7 @@ LossBasedBweV2::Result LossBasedBweV2::GetLossBasedResult() const {
|
||||
void LossBasedBweV2::SetAcknowledgedBitrate(DataRate acknowledged_bitrate) {
|
||||
if (IsValid(acknowledged_bitrate)) {
|
||||
acknowledged_bitrate_ = acknowledged_bitrate;
|
||||
CalculateInstantLowerBound();
|
||||
} else {
|
||||
RTC_LOG(LS_WARNING) << "The acknowledged bitrate must be finite: "
|
||||
<< ToString(acknowledged_bitrate);
|
||||
@ -195,6 +199,7 @@ void LossBasedBweV2::SetMinMaxBitrate(DataRate min_bitrate,
|
||||
DataRate max_bitrate) {
|
||||
if (IsValid(min_bitrate)) {
|
||||
min_bitrate_ = min_bitrate;
|
||||
CalculateInstantLowerBound();
|
||||
} else {
|
||||
RTC_LOG(LS_WARNING) << "The min bitrate must be finite: "
|
||||
<< ToString(min_bitrate);
|
||||
@ -393,6 +398,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
true);
|
||||
FieldTrialParameter<bool> use_in_start_phase("UseInStartPhase", false);
|
||||
FieldTrialParameter<int> min_num_observations("MinNumObservations", 3);
|
||||
FieldTrialParameter<double> lower_bound_by_acked_rate_factor(
|
||||
"LowerBoundByAckedRateFactor", 0.0);
|
||||
if (key_value_config) {
|
||||
ParseFieldTrial({&enabled,
|
||||
&bandwidth_rampup_upper_bound_factor,
|
||||
@ -428,7 +435,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
&slope_of_bwe_high_loss_func,
|
||||
¬_use_acked_rate_in_alr,
|
||||
&use_in_start_phase,
|
||||
&min_num_observations},
|
||||
&min_num_observations,
|
||||
&lower_bound_by_acked_rate_factor},
|
||||
key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2"));
|
||||
}
|
||||
|
||||
@ -488,6 +496,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
|
||||
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();
|
||||
config->lower_bound_by_acked_rate_factor =
|
||||
lower_bound_by_acked_rate_factor.Get();
|
||||
|
||||
return config;
|
||||
}
|
||||
@ -673,6 +683,13 @@ bool LossBasedBweV2::IsConfigValid() const {
|
||||
<< config_->min_num_observations;
|
||||
valid = false;
|
||||
}
|
||||
if (config_->lower_bound_by_acked_rate_factor < 0.0) {
|
||||
RTC_LOG(LS_WARNING)
|
||||
<< "The estimate lower bound by acknowledged rate factor must be "
|
||||
"non-negative: "
|
||||
<< config_->lower_bound_by_acked_rate_factor;
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
@ -913,6 +930,24 @@ void LossBasedBweV2::CalculateInstantUpperBound() {
|
||||
cached_instant_upper_bound_ = instant_limit;
|
||||
}
|
||||
|
||||
DataRate LossBasedBweV2::GetInstantLowerBound() const {
|
||||
return cached_instant_lower_bound_.value_or(DataRate::Zero());
|
||||
}
|
||||
|
||||
void LossBasedBweV2::CalculateInstantLowerBound() {
|
||||
DataRate instance_lower_bound = DataRate::Zero();
|
||||
if (IsValid(acknowledged_bitrate_) &&
|
||||
config_->lower_bound_by_acked_rate_factor > 0.0) {
|
||||
instance_lower_bound = config_->lower_bound_by_acked_rate_factor *
|
||||
acknowledged_bitrate_.value();
|
||||
}
|
||||
|
||||
if (IsValid(min_bitrate_)) {
|
||||
instance_lower_bound = std::max(instance_lower_bound, min_bitrate_);
|
||||
}
|
||||
cached_instant_lower_bound_ = instance_lower_bound;
|
||||
}
|
||||
|
||||
void LossBasedBweV2::CalculateTemporalWeights() {
|
||||
for (int i = 0; i < config_->observation_window_size; ++i) {
|
||||
temporal_weights_[i] = std::pow(config_->temporal_weight_factor, i);
|
||||
|
||||
@ -113,6 +113,7 @@ class LossBasedBweV2 {
|
||||
bool not_use_acked_rate_in_alr = false;
|
||||
bool use_in_start_phase = false;
|
||||
int min_num_observations = 0;
|
||||
double lower_bound_by_acked_rate_factor = 0.0;
|
||||
};
|
||||
|
||||
struct Derivatives {
|
||||
@ -154,6 +155,8 @@ class LossBasedBweV2 {
|
||||
DataRate GetSendingRate(DataRate instantaneous_sending_rate) const;
|
||||
DataRate GetInstantUpperBound() const;
|
||||
void CalculateInstantUpperBound();
|
||||
DataRate GetInstantLowerBound() const;
|
||||
void CalculateInstantLowerBound();
|
||||
|
||||
void CalculateTemporalWeights();
|
||||
void NewtonsMethodUpdate(ChannelParameters& channel_parameters) const;
|
||||
@ -173,6 +176,7 @@ class LossBasedBweV2 {
|
||||
Timestamp last_send_time_most_recent_observation_ = Timestamp::PlusInfinity();
|
||||
Timestamp last_time_estimate_reduced_ = Timestamp::MinusInfinity();
|
||||
absl::optional<DataRate> cached_instant_upper_bound_;
|
||||
absl::optional<DataRate> cached_instant_lower_bound_;
|
||||
std::vector<double> instant_upper_bound_temporal_weights_;
|
||||
std::vector<double> temporal_weights_;
|
||||
Timestamp recovering_after_loss_timestamp_ = Timestamp::MinusInfinity();
|
||||
|
||||
@ -1185,7 +1185,6 @@ TEST_F(LossBasedBweV2Test, NotBackOffToAckedRateInAlr) {
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_100p_loss_1, delay_based_estimate,
|
||||
|
||||
/*in_alr=*/true);
|
||||
|
||||
// Make sure that the estimate decreases but higher than acked rate.
|
||||
@ -1248,5 +1247,55 @@ TEST_F(LossBasedBweV2Test, ReadyToUseInStartPhase) {
|
||||
EXPECT_TRUE(loss_based_bandwidth_estimator.ReadyToUseInStartPhase());
|
||||
}
|
||||
|
||||
TEST_F(LossBasedBweV2Test, BoundEstimateByAckedRate) {
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
ShortObservationConfig("LowerBoundByAckedRateFactor:1.0"));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
loss_based_bandwidth_estimator.SetMinMaxBitrate(
|
||||
/*min_bitrate=*/DataRate::KilobitsPerSec(10),
|
||||
/*max_bitrate=*/DataRate::KilobitsPerSec(1000000));
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(500));
|
||||
|
||||
std::vector<PacketResult> enough_feedback_100p_loss_1 =
|
||||
CreatePacketResultsWith100pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_100p_loss_1,
|
||||
/*delay_based_estimate=*/DataRate::PlusInfinity(),
|
||||
/*in_alr=*/false);
|
||||
|
||||
EXPECT_EQ(
|
||||
loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
|
||||
DataRate::KilobitsPerSec(500));
|
||||
}
|
||||
|
||||
TEST_F(LossBasedBweV2Test, NotBoundEstimateByAckedRate) {
|
||||
ExplicitKeyValueConfig key_value_config(
|
||||
ShortObservationConfig("LowerBoundByAckedRateFactor:0.0"));
|
||||
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
|
||||
loss_based_bandwidth_estimator.SetMinMaxBitrate(
|
||||
/*min_bitrate=*/DataRate::KilobitsPerSec(10),
|
||||
/*max_bitrate=*/DataRate::KilobitsPerSec(1000000));
|
||||
loss_based_bandwidth_estimator.SetBandwidthEstimate(
|
||||
DataRate::KilobitsPerSec(600));
|
||||
loss_based_bandwidth_estimator.SetAcknowledgedBitrate(
|
||||
DataRate::KilobitsPerSec(500));
|
||||
|
||||
std::vector<PacketResult> enough_feedback_100p_loss_1 =
|
||||
CreatePacketResultsWith100pLossRate(
|
||||
/*first_packet_timestamp=*/Timestamp::Zero());
|
||||
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
|
||||
enough_feedback_100p_loss_1,
|
||||
/*delay_based_estimate=*/DataRate::PlusInfinity(),
|
||||
/*in_alr=*/false);
|
||||
|
||||
EXPECT_LT(
|
||||
loss_based_bandwidth_estimator.GetLossBasedResult().bandwidth_estimate,
|
||||
DataRate::KilobitsPerSec(500));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user