diff --git a/webrtc/modules/congestion_controller/probe_controller.cc b/webrtc/modules/congestion_controller/probe_controller.cc index 2e253f1a13..e7bf1fc9b3 100644 --- a/webrtc/modules/congestion_controller/probe_controller.cc +++ b/webrtc/modules/congestion_controller/probe_controller.cc @@ -14,6 +14,7 @@ #include #include "webrtc/base/logging.h" +#include "webrtc/system_wrappers/include/metrics.h" namespace webrtc { @@ -35,6 +36,10 @@ constexpr int kExponentialProbingDisabled = 0; // A limit to prevent probing at excessive bitrates. constexpr int kMaxProbingBitrateBps = 10000000; +// This is a limit on how often probing can be done when there is a BW +// drop detected in ALR region. +constexpr int kAlrProbingIntervalLimitMs = 5000; + } // namespace ProbeController::ProbeController(PacedSender* pacer, Clock* clock) @@ -44,7 +49,8 @@ ProbeController::ProbeController(PacedSender* pacer, Clock* clock) min_bitrate_to_probe_further_bps_(kExponentialProbingDisabled), time_last_probing_initiated_ms_(0), estimated_bitrate_bps_(0), - max_bitrate_bps_(0) {} + max_bitrate_bps_(0), + last_alr_probing_time_(clock_->TimeInMilliseconds()) {} void ProbeController::SetBitrates(int min_bitrate_bps, int start_bitrate_bps, @@ -92,6 +98,30 @@ void ProbeController::SetEstimatedBitrate(int bitrate_bps) { InitiateProbing({2 * bitrate_bps}, 1.25 * bitrate_bps); } } + } else { + // A drop in estimated BW when operating in ALR and not already probing. + // The current response is to initiate a single probe session at the + // previous bitrate and immediately use the reported bitrate as the new + // bitrate. + // + // If the probe session fails, the assumption is that this drop was a + // real one from a competing flow or something else on the network and + // it ramps up from bitrate_bps. + if (pacer_->InApplicationLimitedRegion() && + bitrate_bps < 0.5 * estimated_bitrate_bps_) { + int64_t now_ms = clock_->TimeInMilliseconds(); + if ((now_ms - last_alr_probing_time_) > kAlrProbingIntervalLimitMs) { + LOG(LS_INFO) << "Detected big BW drop in ALR, start probe."; + // Track how often we probe in response to BW drop in ALR. + RTC_HISTOGRAM_COUNTS_10000("WebRTC.BWE.AlrProbingIntervalInS", + (now_ms - last_alr_probing_time_) / 1000); + InitiateProbing({estimated_bitrate_bps_}, kExponentialProbingDisabled); + last_alr_probing_time_ = now_ms; + } + } + // TODO(isheriff): May want to track when we did ALR probing in order + // to reset |last_alr_probing_time_| if we validate that it was a + // drop due to exogenous event. } estimated_bitrate_bps_ = bitrate_bps; } diff --git a/webrtc/modules/congestion_controller/probe_controller.h b/webrtc/modules/congestion_controller/probe_controller.h index 4cf34c3c87..efcc2a1d4a 100644 --- a/webrtc/modules/congestion_controller/probe_controller.h +++ b/webrtc/modules/congestion_controller/probe_controller.h @@ -53,6 +53,7 @@ class ProbeController { int64_t time_last_probing_initiated_ms_ GUARDED_BY(critsect_); int estimated_bitrate_bps_ GUARDED_BY(critsect_); int max_bitrate_bps_ GUARDED_BY(critsect_); + int64_t last_alr_probing_time_ GUARDED_BY(critsect_); RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ProbeController); }; diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc index 6c5e183a78..d38154a241 100644 --- a/webrtc/modules/pacing/paced_sender.cc +++ b/webrtc/modules/pacing/paced_sender.cc @@ -343,6 +343,11 @@ int64_t PacedSender::ExpectedQueueTimeMs() const { pacing_bitrate_kbps_); } +bool PacedSender::InApplicationLimitedRegion() const { + CriticalSectionScoped cs(critsect_.get()); + return alr_detector_->InApplicationLimitedRegion(); +} + size_t PacedSender::QueueSizePackets() const { CriticalSectionScoped cs(critsect_.get()); return packets_->SizeInPackets(); diff --git a/webrtc/modules/pacing/paced_sender.h b/webrtc/modules/pacing/paced_sender.h index b11ae17fcd..ee50f2e416 100644 --- a/webrtc/modules/pacing/paced_sender.h +++ b/webrtc/modules/pacing/paced_sender.h @@ -120,6 +120,13 @@ class PacedSender : public Module, public RtpPacketSender { // packets in the queue, given the current size and bitrate, ignoring prio. virtual int64_t ExpectedQueueTimeMs() const; + // Application Limited Region refers to operating in a state where the + // traffic on network is limited due to application not having enough + // traffic to meet the current channel capacity. + // + // Returns true if network is currently application-limited. + bool InApplicationLimitedRegion() const; + // Returns the average time since being enqueued, in milliseconds, for all // packets currently in the pacer queue, or 0 if queue is empty. virtual int64_t AverageQueueTimeMs();