From a2219e22d27b4a64524227af31f6bcc1e7d06149 Mon Sep 17 00:00:00 2001 From: Diep Bui Date: Wed, 23 Mar 2022 12:30:36 +0000 Subject: [PATCH] Use acked bitrate only when network is overusing. Bug: webrtc:12707 Change-Id: I9a263ec60f07cfd03eed0374c730c87e20014d65 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/256113 Reviewed-by: Per Kjellander Commit-Queue: Diep Bui Cr-Commit-Position: refs/heads/main@{#36303} --- .../goog_cc/loss_based_bwe_v2.cc | 17 +++++- .../goog_cc/loss_based_bwe_v2.h | 3 + .../goog_cc/loss_based_bwe_v2_test.cc | 58 ++++++++++++++++++- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc index 03822e1710..7c72b99bda 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.cc @@ -578,7 +578,8 @@ std::vector LossBasedBweV2::GetCandidates( } if (acknowledged_bitrate_.has_value() && - config_->append_acknowledged_rate_candidate && can_decrease_bitrate) { + config_->append_acknowledged_rate_candidate && + TrendlineEsimateAllowEmergencyBackoff()) { bandwidths.push_back(*acknowledged_bitrate_ * config_->bandwidth_backoff_lower_bound_factor); } @@ -791,6 +792,20 @@ bool LossBasedBweV2::TrendlineEsimateAllowBitrateIncrease() const { return true; } +bool LossBasedBweV2::TrendlineEsimateAllowEmergencyBackoff() const { + if (!config_->trendline_integration_enabled) { + return true; + } + + for (const auto& detector_state : delay_detector_states_) { + if (detector_state == BandwidthUsage::kBwOverusing) { + return true; + } + } + + return false; +} + bool LossBasedBweV2::PushBackObservation( rtc::ArrayView packet_results, BandwidthUsage delay_detector_state) { diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h index 7e42b3e827..cc33387c9e 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2.h @@ -140,6 +140,9 @@ class LossBasedBweV2 { // Returns false if there exists an overusing state in the window. bool TrendlineEsimateAllowBitrateIncrease() const; + // Returns true if there exists an overusing state in the window. + bool TrendlineEsimateAllowEmergencyBackoff() const; + // Returns false if no observation was created. bool PushBackObservation(rtc::ArrayView packet_results, BandwidthUsage delay_detector_state); diff --git a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc index bf0a7e492e..55de52d9c9 100644 --- a/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc +++ b/modules/congestion_controller/goog_cc/loss_based_bwe_v2_test.cc @@ -437,10 +437,14 @@ TEST(LossBasedBweV2Test, BandwidthEstimateIncreasesWhenUnderusing) { DataRate::KilobitsPerSec(600)); } +// When network is underusing, estimate can increase but never be higher than +// the delay based estimate. TEST(LossBasedBweV2Test, BandwidthEstimateCappedByDelayBasedEstimateWhenUnderusing) { PacketResult enough_feedback_1[2]; PacketResult enough_feedback_2[2]; + // Create two packet results, network is in normal state, 100% packets are + // received, and no delay increase. enough_feedback_1[0].sent_packet.size = DataSize::Bytes(15'000); enough_feedback_1[1].sent_packet.size = DataSize::Bytes(15'000); enough_feedback_2[0].sent_packet.size = DataSize::Bytes(15'000); @@ -470,16 +474,69 @@ TEST(LossBasedBweV2Test, loss_based_bandwidth_estimator.UpdateBandwidthEstimate( enough_feedback_1, DataRate::PlusInfinity(), BandwidthUsage::kBwUnderusing); + // If the delay based estimate is infinity, then loss based estimate increases + // and not bounded by delay based estimate. EXPECT_GT(loss_based_bandwidth_estimator.GetBandwidthEstimate( /*delay_based_limit=*/DataRate::PlusInfinity()), DataRate::KilobitsPerSec(600)); loss_based_bandwidth_estimator.UpdateBandwidthEstimate( enough_feedback_2, DataRate::PlusInfinity(), BandwidthUsage::kBwNormal); + // If the delay based estimate is not infinity, then loss based estimate is + // bounded by delay based estimate. EXPECT_EQ(loss_based_bandwidth_estimator.GetBandwidthEstimate( /*delay_based_limit=*/DataRate::KilobitsPerSec(500)), DataRate::KilobitsPerSec(500)); } +// When loss based bwe receives a strong signal of overusing and an increase in +// loss rate, it should acked bitrate for emegency backoff. +TEST(LossBasedBweV2Test, UseAckedBitrateForEmegencyBackOff) { + PacketResult enough_feedback_1[2]; + PacketResult enough_feedback_2[2]; + // Create two packet results, first packet has 50% loss rate, second packet + // has 100% loss rate. + enough_feedback_1[0].sent_packet.size = DataSize::Bytes(15'000); + enough_feedback_1[1].sent_packet.size = DataSize::Bytes(15'000); + enough_feedback_2[0].sent_packet.size = DataSize::Bytes(15'000); + enough_feedback_2[1].sent_packet.size = DataSize::Bytes(15'000); + enough_feedback_1[0].sent_packet.send_time = Timestamp::Zero(); + enough_feedback_1[1].sent_packet.send_time = + Timestamp::Zero() + kObservationDurationLowerBound; + enough_feedback_2[0].sent_packet.send_time = + Timestamp::Zero() + 2 * kObservationDurationLowerBound; + enough_feedback_2[1].sent_packet.send_time = + Timestamp::Zero() + 3 * kObservationDurationLowerBound; + enough_feedback_1[0].receive_time = Timestamp::PlusInfinity(); + enough_feedback_1[1].receive_time = + Timestamp::Zero() + 2 * kObservationDurationLowerBound; + enough_feedback_2[0].receive_time = Timestamp::PlusInfinity(); + enough_feedback_2[1].receive_time = Timestamp::PlusInfinity(); + + ExplicitKeyValueConfig key_value_config( + Config(/*enabled=*/true, /*valid=*/true)); + LossBasedBweV2 loss_based_bandwidth_estimator(&key_value_config); + + loss_based_bandwidth_estimator.SetBandwidthEstimate( + DataRate::KilobitsPerSec(600)); + DataRate acked_bitrate = DataRate::KilobitsPerSec(300); + loss_based_bandwidth_estimator.SetAcknowledgedBitrate(acked_bitrate); + // Update estimate when network is overusing, and 50% loss rate. + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + enough_feedback_1, DataRate::PlusInfinity(), + BandwidthUsage::kBwOverusing); + // Update estimate again when network is continuously overusing, and 100% + // loss rate. + loss_based_bandwidth_estimator.UpdateBandwidthEstimate( + enough_feedback_2, DataRate::PlusInfinity(), + BandwidthUsage::kBwOverusing); + // The estimate bitrate now is backed off based on acked bitrate. + EXPECT_LE(loss_based_bandwidth_estimator.GetBandwidthEstimate( + /*delay_based_limit=*/DataRate::PlusInfinity()), + acked_bitrate); +} + +// When network is in normal state, and if the acked bitrate is small, then the +// loss based estimate is higher than the acked bitrate. TEST(LossBasedBweV2Test, NotUseAckedBitrateInNormalState) { PacketResult enough_feedback_1[2]; PacketResult enough_feedback_2[2]; @@ -525,5 +582,4 @@ TEST(LossBasedBweV2Test, NotUseAckedBitrateInNormalState) { } } // namespace - } // namespace webrtc