Add an option to allow pacing at loss based estimate when network bandwidth is loss limited.

Add a small clean up in LossBasedBandwidthEstimatorV2ReadyForUse since IsReady() includes IsEnabled().

Bug: webrtc:12707
Change-Id: I20dfeb2ab31e7724041f89af9f312211a3ae3d23
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/339521
Commit-Queue: Diep Bui <diepbp@webrtc.org>
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41727}
This commit is contained in:
Diep Bui 2024-02-13 11:05:24 +00:00 committed by WebRTC LUCI CQ
parent e5cd905b9e
commit 14d7d2d845
6 changed files with 57 additions and 4 deletions

View File

@ -720,7 +720,8 @@ PacerConfig GoogCcNetworkController::GetPacingRates(Timestamp at_time) const {
// Pacing rate is based on target rate before congestion window pushback,
// because we don't want to build queues in the pacer when pushback occurs.
DataRate pacing_rate = DataRate::Zero();
if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_) {
if (pace_at_max_of_bwe_and_lower_link_capacity_ && estimate_ &&
!bandwidth_estimation_->PaceAtLossBasedEstimate()) {
pacing_rate =
std::max({min_total_allocated_bitrate_, estimate_->link_capacity_lower,
last_loss_based_target_rate_}) *

View File

@ -499,6 +499,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
FieldTrialParameter<TimeDelta> padding_duration("PaddingDuration",
TimeDelta::Zero());
FieldTrialParameter<bool> bound_best_candidate("BoundBestCandidate", false);
FieldTrialParameter<bool> pace_at_loss_based_estimate(
"PaceAtLossBasedEstimate", false);
if (key_value_config) {
ParseFieldTrial({&enabled,
&bandwidth_rampup_upper_bound_factor,
@ -538,7 +540,8 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
&hold_duration_factor,
&use_byte_loss_rate,
&padding_duration,
&bound_best_candidate},
&bound_best_candidate,
&pace_at_loss_based_estimate},
key_value_config->Lookup("WebRTC-Bwe-LossBasedBweV2"));
}
@ -604,6 +607,7 @@ absl::optional<LossBasedBweV2::Config> LossBasedBweV2::CreateConfig(
config->use_byte_loss_rate = use_byte_loss_rate.Get();
config->padding_duration = padding_duration.Get();
config->bound_best_candidate = bound_best_candidate.Get();
config->pace_at_loss_based_estimate = pace_at_loss_based_estimate.Get();
return config;
}
@ -1199,4 +1203,9 @@ bool LossBasedBweV2::CanKeepIncreasingState(DataRate estimate) const {
last_padding_info_.padding_rate < estimate;
}
bool LossBasedBweV2::PaceAtLossBasedEstimate() const {
return config_->pace_at_loss_based_estimate &&
loss_based_result_.state != LossBasedState::kDelayBasedEstimate;
}
} // namespace webrtc

View File

@ -74,6 +74,7 @@ class LossBasedBweV2 {
rtc::ArrayView<const PacketResult> packet_results,
DataRate delay_based_estimate,
bool in_alr);
bool PaceAtLossBasedEstimate() const;
// For unit testing only.
void SetBandwidthEstimate(DataRate bandwidth_estimate);
@ -124,6 +125,7 @@ class LossBasedBweV2 {
bool use_byte_loss_rate = false;
TimeDelta padding_duration = TimeDelta::Zero();
bool bound_best_candidate = false;
bool pace_at_loss_based_estimate = false;
};
struct Derivatives {

View File

@ -1776,5 +1776,41 @@ TEST_F(LossBasedBweV2Test, UseByteLossRate) {
DataRate::KilobitsPerSec(150));
}
TEST_F(LossBasedBweV2Test, PaceAtLossBasedEstimate) {
ExplicitKeyValueConfig key_value_config(ShortObservationConfig(
"PaceAtLossBasedEstimate:true,PaddingDuration:1000ms"));
LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config);
loss_based_bandwidth_estimator.SetBandwidthEstimate(
DataRate::KilobitsPerSec(1000));
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
CreatePacketResultsWithReceivedPackets(
/*first_packet_timestamp=*/Timestamp::Zero()),
/*delay_based_estimate=*/DataRate::KilobitsPerSec(1000),
/*in_alr=*/false);
EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
LossBasedState::kDelayBasedEstimate);
EXPECT_FALSE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate());
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
CreatePacketResultsWith100pLossRate(
/*first_packet_timestamp=*/Timestamp::Zero() +
kObservationDurationLowerBound),
/*delay_based_estimate=*/DataRate::KilobitsPerSec(1000),
/*in_alr=*/false);
EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
LossBasedState::kDecreasing);
EXPECT_TRUE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate());
loss_based_bandwidth_estimator.UpdateBandwidthEstimate(
CreatePacketResultsWithReceivedPackets(
/*first_packet_timestamp=*/Timestamp::Zero() +
kObservationDurationLowerBound * 2),
/*delay_based_estimate=*/DataRate::KilobitsPerSec(1000),
/*in_alr=*/false);
EXPECT_EQ(loss_based_bandwidth_estimator.GetLossBasedResult().state,
LossBasedState::kIncreaseUsingPadding);
EXPECT_TRUE(loss_based_bandwidth_estimator.PaceAtLossBasedEstimate());
}
} // namespace
} // namespace webrtc

View File

@ -700,8 +700,12 @@ bool SendSideBandwidthEstimation::LossBasedBandwidthEstimatorV2Enabled() const {
bool SendSideBandwidthEstimation::LossBasedBandwidthEstimatorV2ReadyForUse()
const {
return LossBasedBandwidthEstimatorV2Enabled() &&
loss_based_bandwidth_estimator_v2_->IsReady();
return loss_based_bandwidth_estimator_v2_->IsReady();
}
bool SendSideBandwidthEstimation::PaceAtLossBasedEstimate() const {
return LossBasedBandwidthEstimatorV2ReadyForUse() &&
loss_based_bandwidth_estimator_v2_->PaceAtLossBasedEstimate();
}
} // namespace webrtc

View File

@ -129,6 +129,7 @@ class SendSideBandwidthEstimation {
BandwidthUsage delay_detector_state,
absl::optional<DataRate> probe_bitrate,
bool in_alr);
bool PaceAtLossBasedEstimate() const;
private:
friend class GoogCcStatePrinter;