diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.cc b/modules/congestion_controller/goog_cc/delay_based_bwe.cc index a76adb01c6..3c780dddd2 100644 --- a/modules/congestion_controller/goog_cc/delay_based_bwe.cc +++ b/modules/congestion_controller/goog_cc/delay_based_bwe.cc @@ -70,13 +70,15 @@ DelayBasedBwe::Result::Result() : updated(false), probe(false), target_bitrate(DataRate::Zero()), - recovered_from_overuse(false) {} + recovered_from_overuse(false), + backoff_in_alr(false) {} DelayBasedBwe::Result::Result(bool probe, DataRate target_bitrate) : updated(true), probe(probe), target_bitrate(target_bitrate), - recovered_from_overuse(false) {} + recovered_from_overuse(false), + backoff_in_alr(false) {} DelayBasedBwe::Result::~Result() {} @@ -93,7 +95,9 @@ DelayBasedBwe::DelayBasedBwe(RtcEventLog* event_log) trendline_smoothing_coeff_(kDefaultTrendlineSmoothingCoeff), trendline_threshold_gain_(kDefaultTrendlineThresholdGain), prev_bitrate_(DataRate::Zero()), - prev_state_(BandwidthUsage::kBwNormal) { + prev_state_(BandwidthUsage::kBwNormal), + alr_limited_backoff_enabled_( + field_trial::IsEnabled("WebRTC-Bwe-AlrLimitedBackoff")) { RTC_LOG(LS_INFO) << "Using Trendline filter for delay change estimation with window size " << trendline_window_size_; @@ -108,6 +112,7 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( const std::vector& packet_feedback_vector, absl::optional acked_bitrate, absl::optional probe_bitrate, + bool in_alr, Timestamp at_time) { RTC_DCHECK(std::is_sorted(packet_feedback_vector.begin(), packet_feedback_vector.end(), @@ -149,7 +154,7 @@ DelayBasedBwe::Result DelayBasedBwe::IncomingPacketFeedbackVector( return Result(); } return MaybeUpdateEstimate(acked_bitrate, probe_bitrate, - recovered_from_overuse, at_time); + recovered_from_overuse, in_alr, at_time); } void DelayBasedBwe::IncomingPacketFeedback( @@ -194,13 +199,19 @@ DelayBasedBwe::Result DelayBasedBwe::MaybeUpdateEstimate( absl::optional acked_bitrate, absl::optional probe_bitrate, bool recovered_from_overuse, + bool in_alr, Timestamp at_time) { Result result; // Currently overusing the bandwidth. if (delay_detector_->State() == BandwidthUsage::kBwOverusing) { - if (acked_bitrate && - rate_control_.TimeToReduceFurther(at_time, *acked_bitrate)) { + if (in_alr && alr_limited_backoff_enabled_ && + rate_control_.TimeToReduceFurther(at_time, prev_bitrate_)) { + result.updated = + UpdateEstimate(at_time, prev_bitrate_, &result.target_bitrate); + result.backoff_in_alr = true; + } else if (acked_bitrate && + rate_control_.TimeToReduceFurther(at_time, *acked_bitrate)) { result.updated = UpdateEstimate(at_time, acked_bitrate, &result.target_bitrate); } else if (!acked_bitrate && rate_control_.ValidEstimate() && @@ -287,4 +298,9 @@ void DelayBasedBwe::SetMinBitrate(DataRate min_bitrate) { TimeDelta DelayBasedBwe::GetExpectedBwePeriod() const { return rate_control_.GetExpectedBandwidthPeriod(); } + +void DelayBasedBwe::SetAlrLimitedBackoffExperiment(bool enabled) { + alr_limited_backoff_enabled_ = enabled; +} + } // namespace webrtc diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe.h b/modules/congestion_controller/goog_cc/delay_based_bwe.h index ead60f3012..f276dfeabf 100644 --- a/modules/congestion_controller/goog_cc/delay_based_bwe.h +++ b/modules/congestion_controller/goog_cc/delay_based_bwe.h @@ -39,6 +39,7 @@ class DelayBasedBwe { bool probe; DataRate target_bitrate = DataRate::Zero(); bool recovered_from_overuse; + bool backoff_in_alr; }; explicit DelayBasedBwe(RtcEventLog* event_log); @@ -48,12 +49,14 @@ class DelayBasedBwe { const std::vector& packet_feedback_vector, absl::optional acked_bitrate, absl::optional probe_bitrate, + bool in_alr, Timestamp at_time); void OnRttUpdate(TimeDelta avg_rtt); bool LatestEstimate(std::vector* ssrcs, DataRate* bitrate) const; void SetStartBitrate(DataRate start_bitrate); void SetMinBitrate(DataRate min_bitrate); TimeDelta GetExpectedBwePeriod() const; + void SetAlrLimitedBackoffExperiment(bool enabled); private: friend class GoogCcStatePrinter; @@ -61,7 +64,8 @@ class DelayBasedBwe { Timestamp at_time); Result MaybeUpdateEstimate(absl::optional acked_bitrate, absl::optional probe_bitrate, - bool request_probe, + bool recovered_from_overuse, + bool in_alr, Timestamp at_time); // Updates the current remote rate estimate and returns true if a valid // estimate exists. @@ -81,6 +85,7 @@ class DelayBasedBwe { double trendline_threshold_gain_; DataRate prev_bitrate_; BandwidthUsage prev_state_; + bool alr_limited_backoff_enabled_; RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DelayBasedBwe); }; diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc index fbea95accc..3798e96282 100644 --- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc +++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest.cc @@ -29,8 +29,9 @@ constexpr Timestamp kDummyTimestamp = Timestamp::Seconds<1000>(); TEST_F(DelayBasedBweTest, NoCrashEmptyFeedback) { std::vector packet_feedback_vector; - bitrate_estimator_->IncomingPacketFeedbackVector( - packet_feedback_vector, absl::nullopt, absl::nullopt, kDummyTimestamp); + bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector, + absl::nullopt, absl::nullopt, + false, kDummyTimestamp); } TEST_F(DelayBasedBweTest, NoCrashOnlyLostFeedback) { @@ -41,8 +42,9 @@ TEST_F(DelayBasedBweTest, NoCrashOnlyLostFeedback) { packet_feedback_vector.push_back(PacketFeedback(PacketFeedback::kNotReceived, PacketFeedback::kNoSendTime, 1, 1500, PacedPacketInfo())); - bitrate_estimator_->IncomingPacketFeedbackVector( - packet_feedback_vector, absl::nullopt, absl::nullopt, kDummyTimestamp); + bitrate_estimator_->IncomingPacketFeedbackVector(packet_feedback_vector, + absl::nullopt, absl::nullopt, + false, kDummyTimestamp); } TEST_F(DelayBasedBweTest, ProbeDetection) { diff --git a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc index b6e2e57d10..006acf736d 100644 --- a/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc +++ b/modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.cc @@ -207,7 +207,7 @@ void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms, DelayBasedBwe::Result result = bitrate_estimator_->IncomingPacketFeedbackVector( packets, acknowledged_bitrate_estimator_->bitrate(), - probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), + probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), false, Timestamp::ms(clock_.TimeInMilliseconds())); const uint32_t kDummySsrc = 0; if (result.updated) { @@ -248,7 +248,7 @@ bool DelayBasedBweTest::GenerateAndProcessFrame(uint32_t ssrc, DelayBasedBwe::Result result = bitrate_estimator_->IncomingPacketFeedbackVector( packets, acknowledged_bitrate_estimator_->bitrate(), - probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), + probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), false, Timestamp::ms(clock_.TimeInMilliseconds())); const uint32_t kDummySsrc = 0; if (result.updated) { diff --git a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc index aa0b78969f..8240acc4f5 100644 --- a/modules/congestion_controller/goog_cc/goog_cc_network_control.cc +++ b/modules/congestion_controller/goog_cc/goog_cc_network_control.cc @@ -498,7 +498,7 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( DelayBasedBwe::Result result; result = delay_based_bwe_->IncomingPacketFeedbackVector( received_feedback_vector, acknowledged_bitrate, probe_bitrate, - report.feedback_time); + alr_start_time.has_value(), report.feedback_time); NetworkControlUpdate update; if (result.updated) { @@ -518,6 +518,11 @@ NetworkControlUpdate GoogCcNetworkController::OnTransportPacketsFeedback( auto probes = probe_controller_->RequestProbe(report.feedback_time.ms()); update.probe_cluster_configs.insert(update.probe_cluster_configs.end(), probes.begin(), probes.end()); + } else if (result.backoff_in_alr) { + // If we just backed off during ALR, request a new probe. + auto probes = probe_controller_->RequestProbe(report.feedback_time.ms()); + update.probe_cluster_configs.insert(update.probe_cluster_configs.end(), + probes.begin(), probes.end()); } // No valid RTT could be because send-side BWE isn't used, in which case diff --git a/modules/congestion_controller/include/send_side_congestion_controller.h b/modules/congestion_controller/include/send_side_congestion_controller.h index 39ee4cc6d6..41c10173c2 100644 --- a/modules/congestion_controller/include/send_side_congestion_controller.h +++ b/modules/congestion_controller/include/send_side_congestion_controller.h @@ -119,6 +119,8 @@ class DEPRECATED_SendSideCongestionController void EnableCongestionWindowPushback(int64_t accepted_queue_ms, uint32_t min_pushback_target_bitrate_bps); + void SetAlrLimitedBackoffExperiment(bool enable); + private: void MaybeTriggerOnNetworkChanged(); diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc index 3bff09c1fa..cf2bba4273 100644 --- a/modules/congestion_controller/send_side_congestion_controller.cc +++ b/modules/congestion_controller/send_side_congestion_controller.cc @@ -186,6 +186,12 @@ void DEPRECATED_SendSideCongestionController::EnableCongestionWindowPushback( min_pushback_target_bitrate_bps); } +void DEPRECATED_SendSideCongestionController::SetAlrLimitedBackoffExperiment( + bool enable) { + rtc::CritScope cs(&bwe_lock_); + delay_based_bwe_->SetAlrLimitedBackoffExperiment(enable); +} + void DEPRECATED_SendSideCongestionController::RegisterPacketFeedbackObserver( PacketFeedbackObserver* observer) { transport_feedback_adapter_.RegisterPacketFeedbackObserver(observer); @@ -437,7 +443,7 @@ void DEPRECATED_SendSideCongestionController::OnTransportFeedback( result = delay_based_bwe_->IncomingPacketFeedbackVector( feedback_vector, acknowledged_bitrate_estimator_->bitrate(), probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), - Timestamp::ms(clock_->TimeInMilliseconds())); + currently_in_alr, Timestamp::ms(clock_->TimeInMilliseconds())); } if (result.updated) { bitrate_controller_->OnDelayBasedBweResult(result); @@ -449,6 +455,9 @@ void DEPRECATED_SendSideCongestionController::OnTransportFeedback( probe_controller_->SetAlrStartTimeMs( pacer_->GetApplicationLimitedRegionStartTime()); SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds())); + } else if (result.backoff_in_alr) { + rtc::CritScope cs(&probe_lock_); + SendProbes(probe_controller_->RequestProbe(clock_->TimeInMilliseconds())); } if (in_cwnd_experiment_) { LimitOutstandingBytes(transport_feedback_adapter_.GetOutstandingBytes()); diff --git a/modules/remote_bitrate_estimator/test/estimators/send_side.cc b/modules/remote_bitrate_estimator/test/estimators/send_side.cc index 7c1d8c4a78..0221edf08d 100644 --- a/modules/remote_bitrate_estimator/test/estimators/send_side.cc +++ b/modules/remote_bitrate_estimator/test/estimators/send_side.cc @@ -91,7 +91,7 @@ void SendSideBweSender::GiveFeedback(const FeedbackPacket& feedback) { } DelayBasedBwe::Result result = bwe_->IncomingPacketFeedbackVector( packet_feedback_vector, acknowledged_bitrate_estimator_->bitrate(), - probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), + probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(), false, Timestamp::ms(clock_->TimeInMilliseconds())); if (result.updated) bitrate_controller_->OnDelayBasedBweResult(result);