diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index d4d339eb6e..4d44bffaea 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -129,6 +129,9 @@ struct MediaConfig { // VideoReceiveStream, where the value is passed on to the // IncomingVideoStream constructor. bool disable_prerenderer_smoothing = false; + + // Enables periodic bandwidth probing in application-limited region. + bool periodic_alr_bandwidth_probing = false; } video; }; diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 95c7c8c5f5..e947fd1254 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -1102,6 +1102,8 @@ bool WebRtcVideoChannel2::AddSendStream(const StreamParams& sp) { webrtc::VideoSendStream::Config config(this); config.suspend_below_min_bitrate = video_config_.suspend_below_min_bitrate; + config.periodic_alr_bandwidth_probing = + video_config_.periodic_alr_bandwidth_probing; WebRtcVideoSendStream* stream = new WebRtcVideoSendStream( call_, sp, std::move(config), default_send_options_, external_encoder_factory_, video_config_.enable_cpu_overuse_detection, diff --git a/webrtc/modules/congestion_controller/congestion_controller.cc b/webrtc/modules/congestion_controller/congestion_controller.cc index accc1411f9..5a11f3242f 100644 --- a/webrtc/modules/congestion_controller/congestion_controller.cc +++ b/webrtc/modules/congestion_controller/congestion_controller.cc @@ -275,6 +275,10 @@ RateLimiter* CongestionController::GetRetransmissionRateLimiter() { return retransmission_rate_limiter_.get(); } +void CongestionController::EnablePeriodicAlrProbing(bool enable) { + probe_controller_->EnablePeriodicAlrProbing(enable); +} + void CongestionController::SetAllocatedSendBitrateLimits( int min_send_bitrate_bps, int max_padding_bitrate_bps) { @@ -319,6 +323,7 @@ int64_t CongestionController::TimeUntilNextProcess() { void CongestionController::Process() { bitrate_controller_->Process(); remote_bitrate_estimator_->Process(); + probe_controller_->Process(); MaybeTriggerOnNetworkChanged(); } diff --git a/webrtc/modules/congestion_controller/include/congestion_controller.h b/webrtc/modules/congestion_controller/include/congestion_controller.h index 8663489d54..4f9ce95e2c 100644 --- a/webrtc/modules/congestion_controller/include/congestion_controller.h +++ b/webrtc/modules/congestion_controller/include/congestion_controller.h @@ -82,6 +82,7 @@ class CongestionController : public CallStatsObserver, public Module { virtual PacketRouter* packet_router() { return packet_router_.get(); } virtual TransportFeedbackObserver* GetTransportFeedbackObserver(); RateLimiter* GetRetransmissionRateLimiter(); + void EnablePeriodicAlrProbing(bool enable); // SetAllocatedSendBitrateLimits sets bitrates limits imposed by send codec // settings. diff --git a/webrtc/modules/congestion_controller/probe_controller.cc b/webrtc/modules/congestion_controller/probe_controller.cc index 1749e29ff7..5f42cf44fd 100644 --- a/webrtc/modules/congestion_controller/probe_controller.cc +++ b/webrtc/modules/congestion_controller/probe_controller.cc @@ -38,8 +38,14 @@ constexpr int kExponentialProbingDisabled = 0; constexpr int kDefaultMaxProbingBitrateBps = 100000000; // 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; +// drop detected in ALR. +constexpr int64_t kAlrProbingIntervalMinMs = 5000; + +// Interval between probes when ALR periodic probing is enabled. +constexpr int64_t kAlrPeriodicProbingIntervalMs = 5000; + +// Minimum probe bitrate percentage to probe further for repeated probes. +constexpr int kRepeatedProbeMinPercentage = 125; } // namespace @@ -53,7 +59,8 @@ ProbeController::ProbeController(PacedSender* pacer, Clock* clock) estimated_bitrate_bps_(0), start_bitrate_bps_(0), max_bitrate_bps_(0), - last_alr_probing_time_(clock_->TimeInMilliseconds()) {} + last_alr_probing_time_(clock_->TimeInMilliseconds()), + enable_periodic_alr_probing_(false) {} void ProbeController::SetBitrates(int min_bitrate_bps, int start_bitrate_bps, @@ -83,7 +90,8 @@ void ProbeController::SetBitrates(int min_bitrate_bps, if (estimated_bitrate_bps_ != 0 && estimated_bitrate_bps_ < old_max_bitrate_bps && max_bitrate_bps_ > old_max_bitrate_bps) { - InitiateProbing({max_bitrate_bps}, kExponentialProbingDisabled); + InitiateProbing(clock_->TimeInMilliseconds(), {max_bitrate_bps}, + kExponentialProbingDisabled); } break; } @@ -103,14 +111,17 @@ void ProbeController::InitiateExponentialProbing() { // When probing at 1.8 Mbps ( 6x 300), this represents a threshold of // 1.2 Mbps to continue probing. - InitiateProbing({3 * start_bitrate_bps_, 6 * start_bitrate_bps_}, + InitiateProbing(clock_->TimeInMilliseconds(), + {3 * start_bitrate_bps_, 6 * start_bitrate_bps_}, 4 * start_bitrate_bps_); } void ProbeController::SetEstimatedBitrate(int bitrate_bps) { rtc::CritScope cs(&critsect_); + int64_t now_ms = clock_->TimeInMilliseconds(); + if (state_ == State::kWaitingForProbingResult) { - if ((clock_->TimeInMilliseconds() - time_last_probing_initiated_ms_) > + if ((now_ms - time_last_probing_initiated_ms_) > kMaxWaitingTimeForProbingResultMs) { LOG(LS_INFO) << "kWaitingForProbingResult: timeout"; state_ = State::kProbingComplete; @@ -125,38 +136,73 @@ void ProbeController::SetEstimatedBitrate(int bitrate_bps) { bitrate_bps > min_bitrate_to_probe_further_bps_) { // Double the probing bitrate and expect a minimum of 25% gain to // continue probing. - 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; + InitiateProbing(now_ms, {2 * bitrate_bps}, + bitrate_bps * kRepeatedProbeMinPercentage / 100); + } else { + // Stop exponential probing. + state_ = State::kProbingComplete; + min_bitrate_to_probe_further_bps_ = kExponentialProbingDisabled; } } + } + + // Detect 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 (state_ == State::kProbingComplete && + pacer_->GetApplicationLimitedRegionStartTime() && + bitrate_bps < estimated_bitrate_bps_ / 2 && + (now_ms - last_alr_probing_time_) > kAlrProbingIntervalMinMs) { + 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(now_ms, {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; } +void ProbeController::EnablePeriodicAlrProbing(bool enable) { + rtc::CritScope cs(&critsect_); + enable_periodic_alr_probing_ = enable; +} + +void ProbeController::Process() { + rtc::CritScope cs(&critsect_); + + if (state_ != State::kProbingComplete || !enable_periodic_alr_probing_) + return; + + // Probe bandwidth periodically when in ALR state. + rtc::Optional alr_start_time = + pacer_->GetApplicationLimitedRegionStartTime(); + if (alr_start_time) { + int64_t now_ms = clock_->TimeInMilliseconds(); + int64_t next_probe_time_ms = + std::max(*alr_start_time, time_last_probing_initiated_ms_) + + kAlrPeriodicProbingIntervalMs; + if (now_ms >= next_probe_time_ms) { + InitiateProbing( + now_ms, {estimated_bitrate_bps_ * 2}, + estimated_bitrate_bps_ * kRepeatedProbeMinPercentage / 100); + } + } +} + void ProbeController::InitiateProbing( + int64_t now_ms, std::initializer_list bitrates_to_probe, int min_bitrate_to_probe_further_bps) { bool first_cluster = true; @@ -172,7 +218,7 @@ void ProbeController::InitiateProbing( } } min_bitrate_to_probe_further_bps_ = min_bitrate_to_probe_further_bps; - time_last_probing_initiated_ms_ = clock_->TimeInMilliseconds(); + time_last_probing_initiated_ms_ = now_ms; if (min_bitrate_to_probe_further_bps == kExponentialProbingDisabled) state_ = State::kProbingComplete; else diff --git a/webrtc/modules/congestion_controller/probe_controller.h b/webrtc/modules/congestion_controller/probe_controller.h index e60a007b9d..4faa8af3e3 100644 --- a/webrtc/modules/congestion_controller/probe_controller.h +++ b/webrtc/modules/congestion_controller/probe_controller.h @@ -36,6 +36,9 @@ class ProbeController { void SetEstimatedBitrate(int bitrate_bps); + void EnablePeriodicAlrProbing(bool enable); + void Process(); + private: enum class State { // Initial state where no probing has been triggered yet. @@ -47,7 +50,8 @@ class ProbeController { }; void InitiateExponentialProbing() EXCLUSIVE_LOCKS_REQUIRED(critsect_); - void InitiateProbing(std::initializer_list bitrates_to_probe, + void InitiateProbing(int64_t now_ms, + std::initializer_list bitrates_to_probe, int min_bitrate_to_probe_further_bps) EXCLUSIVE_LOCKS_REQUIRED(critsect_); @@ -62,6 +66,7 @@ class ProbeController { int start_bitrate_bps_ GUARDED_BY(critsect_); int max_bitrate_bps_ GUARDED_BY(critsect_); int64_t last_alr_probing_time_ GUARDED_BY(critsect_); + bool enable_periodic_alr_probing_ GUARDED_BY(critsect_); RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ProbeController); }; diff --git a/webrtc/modules/congestion_controller/probe_controller_unittest.cc b/webrtc/modules/congestion_controller/probe_controller_unittest.cc index 3842ded5a6..3c43cfebbb 100644 --- a/webrtc/modules/congestion_controller/probe_controller_unittest.cc +++ b/webrtc/modules/congestion_controller/probe_controller_unittest.cc @@ -19,6 +19,7 @@ using testing::_; using testing::AtLeast; using testing::NiceMock; +using testing::Return; namespace webrtc { namespace test { @@ -31,11 +32,13 @@ constexpr int kMaxBitrateBps = 10000; constexpr int kExponentialProbingTimeoutMs = 5000; +constexpr int kAlrProbeInterval = 5000; + } // namespace class ProbeControllerTest : public ::testing::Test { protected: - ProbeControllerTest() : clock_(0) { + ProbeControllerTest() : clock_(100000000L) { probe_controller_.reset(new ProbeController(&pacer_, &clock_)); } ~ProbeControllerTest() override {} @@ -79,8 +82,6 @@ TEST_F(ProbeControllerTest, TestExponentialProbing) { probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, kMaxBitrateBps); - - EXPECT_CALL(pacer_, CreateProbeCluster(2 * 1800, _)); probe_controller_->SetEstimatedBitrate(1800); } @@ -95,5 +96,59 @@ TEST_F(ProbeControllerTest, TestExponentialProbingTimeout) { probe_controller_->SetEstimatedBitrate(1800); } +TEST_F(ProbeControllerTest, ProbeAfterEstimateDropInAlr) { + EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(2); + probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps); + probe_controller_->SetEstimatedBitrate(500); + testing::Mock::VerifyAndClearExpectations(&pacer_); + + // When bandwidth estimate drops the controller should send a probe at the + // previous bitrate. + EXPECT_CALL(pacer_, CreateProbeCluster(500, _)).Times(1); + EXPECT_CALL(pacer_, GetApplicationLimitedRegionStartTime()) + .WillRepeatedly( + Return(rtc::Optional(clock_.TimeInMilliseconds()))); + clock_.AdvanceTimeMilliseconds(kAlrProbeInterval + 1); + probe_controller_->SetEstimatedBitrate(50); +} + +TEST_F(ProbeControllerTest, PeriodicProbing) { + EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(2); + probe_controller_->EnablePeriodicAlrProbing(true); + probe_controller_->SetBitrates(kMinBitrateBps, kStartBitrateBps, + kMaxBitrateBps); + probe_controller_->SetEstimatedBitrate(500); + testing::Mock::VerifyAndClearExpectations(&pacer_); + + int64_t start_time = clock_.TimeInMilliseconds(); + + // Expect the controller to send a new probe after 5s has passed. + EXPECT_CALL(pacer_, CreateProbeCluster(1000, _)).Times(1); + EXPECT_CALL(pacer_, GetApplicationLimitedRegionStartTime()) + .WillRepeatedly(Return(rtc::Optional(start_time))); + clock_.AdvanceTimeMilliseconds(5000); + probe_controller_->Process(); + probe_controller_->SetEstimatedBitrate(500); + testing::Mock::VerifyAndClearExpectations(&pacer_); + + // The following probe should be sent at 10s into ALR. + EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(0); + EXPECT_CALL(pacer_, GetApplicationLimitedRegionStartTime()) + .WillRepeatedly(Return(rtc::Optional(start_time))); + clock_.AdvanceTimeMilliseconds(4000); + probe_controller_->Process(); + probe_controller_->SetEstimatedBitrate(500); + testing::Mock::VerifyAndClearExpectations(&pacer_); + + EXPECT_CALL(pacer_, CreateProbeCluster(_, _)).Times(1); + EXPECT_CALL(pacer_, GetApplicationLimitedRegionStartTime()) + .WillRepeatedly(Return(rtc::Optional(start_time))); + clock_.AdvanceTimeMilliseconds(1000); + probe_controller_->Process(); + probe_controller_->SetEstimatedBitrate(500); + testing::Mock::VerifyAndClearExpectations(&pacer_); +} + } // namespace test } // namespace webrtc diff --git a/webrtc/modules/pacing/alr_detector.cc b/webrtc/modules/pacing/alr_detector.cc index 90afe18fef..b31d4482bb 100644 --- a/webrtc/modules/pacing/alr_detector.cc +++ b/webrtc/modules/pacing/alr_detector.cc @@ -44,10 +44,10 @@ void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t now_ms) { return; int percentage = static_cast(*rate) * 100 / estimated_bitrate_bps_; - if (percentage < kAlrStartUsagePercent && !application_limited_) { - application_limited_ = true; - } else if (percentage > kAlrEndUsagePercent && application_limited_) { - application_limited_ = false; + if (percentage < kAlrStartUsagePercent && !alr_started_time_ms_) { + alr_started_time_ms_ = rtc::Optional(now_ms); + } else if (percentage > kAlrEndUsagePercent && alr_started_time_ms_) { + alr_started_time_ms_ = rtc::Optional(); } } @@ -56,8 +56,9 @@ void AlrDetector::SetEstimatedBitrate(int bitrate_bps) { estimated_bitrate_bps_ = bitrate_bps; } -bool AlrDetector::InApplicationLimitedRegion() const { - return application_limited_; +rtc::Optional AlrDetector::GetApplicationLimitedRegionStartTime() + const { + return alr_started_time_ms_; } } // namespace webrtc diff --git a/webrtc/modules/pacing/alr_detector.h b/webrtc/modules/pacing/alr_detector.h index 31b1644d30..d8870ff04b 100644 --- a/webrtc/modules/pacing/alr_detector.h +++ b/webrtc/modules/pacing/alr_detector.h @@ -35,13 +35,16 @@ class AlrDetector { // Set current estimated bandwidth. void SetEstimatedBitrate(int bitrate_bps); - // Returns true if currently in application-limited region. - bool InApplicationLimitedRegion() const; + // Returns time in milliseconds when the current application-limited region + // started or empty result if the sender is currently not application-limited. + rtc::Optional GetApplicationLimitedRegionStartTime() const; private: RateStatistics rate_; int estimated_bitrate_bps_ = 0; - bool application_limited_ = false; + + // Non-empty in ALR state. + rtc::Optional alr_started_time_ms_; }; } // namespace webrtc diff --git a/webrtc/modules/pacing/alr_detector_unittest.cc b/webrtc/modules/pacing/alr_detector_unittest.cc index 506b55c175..c6165915d0 100644 --- a/webrtc/modules/pacing/alr_detector_unittest.cc +++ b/webrtc/modules/pacing/alr_detector_unittest.cc @@ -51,61 +51,61 @@ class AlrDetectorTest : public testing::Test { TEST_F(AlrDetectorTest, AlrDetection) { // Start in non-ALR state. - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); // Stay in non-ALR state when usage is close to 100%. SimulateOutgoingTraffic(500, 90); - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); // Verify that we ALR starts when bitrate drops below 20%. SimulateOutgoingTraffic(500, 20); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); // Verify that we remain in ALR state while usage is still below 50%. SimulateOutgoingTraffic(500, 40); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); // Verify that ALR ends when usage is above 50%. SimulateOutgoingTraffic(500, 60); - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); } TEST_F(AlrDetectorTest, ShortSpike) { // Start in non-ALR state. - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); // Verify that we ALR starts when bitrate drops below 20%. SimulateOutgoingTraffic(500, 20); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); // Verify that we stay in ALR region even after a short bitrate spike. SimulateOutgoingTraffic(100, 150); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); SimulateOutgoingTraffic(200, 20); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); // ALR ends when usage is above 50%. SimulateOutgoingTraffic(500, 60); - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); } TEST_F(AlrDetectorTest, BandwidthEstimateChanges) { // Start in non-ALR state. - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); // ALR starts when bitrate drops below 20%. SimulateOutgoingTraffic(500, 20); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); // When bandwidth estimate drops the detector should stay in ALR mode and quit // it shortly afterwards as the sender continues sending the same amount of // traffic. This is necessary to ensure that ProbeController can still react // to the BWE drop by initiating a new probe. alr_detector_.SetEstimatedBitrate(kEstimatedBitrateBps / 5); - EXPECT_TRUE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_TRUE(alr_detector_.GetApplicationLimitedRegionStartTime()); SimulateOutgoingTraffic(10, 20); - EXPECT_FALSE(alr_detector_.InApplicationLimitedRegion()); + EXPECT_FALSE(alr_detector_.GetApplicationLimitedRegionStartTime()); } } // namespace webrtc diff --git a/webrtc/modules/pacing/mock/mock_paced_sender.h b/webrtc/modules/pacing/mock/mock_paced_sender.h index b83032c24a..eacc334e0a 100644 --- a/webrtc/modules/pacing/mock/mock_paced_sender.h +++ b/webrtc/modules/pacing/mock/mock_paced_sender.h @@ -33,6 +33,8 @@ class MockPacedSender : public PacedSender { MOCK_CONST_METHOD0(QueueInMs, int64_t()); MOCK_CONST_METHOD0(QueueInPackets, int()); MOCK_CONST_METHOD0(ExpectedQueueTimeMs, int64_t()); + MOCK_CONST_METHOD0(GetApplicationLimitedRegionStartTime, + rtc::Optional()); }; } // namespace webrtc diff --git a/webrtc/modules/pacing/paced_sender.cc b/webrtc/modules/pacing/paced_sender.cc index 445d116ed7..00523e61b7 100644 --- a/webrtc/modules/pacing/paced_sender.cc +++ b/webrtc/modules/pacing/paced_sender.cc @@ -343,9 +343,10 @@ int64_t PacedSender::ExpectedQueueTimeMs() const { pacing_bitrate_kbps_); } -bool PacedSender::InApplicationLimitedRegion() const { +rtc::Optional PacedSender::GetApplicationLimitedRegionStartTime() + const { CriticalSectionScoped cs(critsect_.get()); - return alr_detector_->InApplicationLimitedRegion(); + return alr_detector_->GetApplicationLimitedRegionStartTime(); } size_t PacedSender::QueueSizePackets() const { diff --git a/webrtc/modules/pacing/paced_sender.h b/webrtc/modules/pacing/paced_sender.h index ee50f2e416..b9bb1c39a4 100644 --- a/webrtc/modules/pacing/paced_sender.h +++ b/webrtc/modules/pacing/paced_sender.h @@ -15,6 +15,7 @@ #include #include +#include "webrtc/base/optional.h" #include "webrtc/base/thread_annotations.h" #include "webrtc/modules/include/module.h" #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" @@ -120,12 +121,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 + // Returns time in milliseconds when the current application-limited region + // started or empty result if the sender is currently not application-limited. + // + // Application Limited Region (ALR) 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; + virtual rtc::Optional GetApplicationLimitedRegionStartTime() const; // Returns the average time since being enqueued, in milliseconds, for all // packets currently in the pacer queue, or 0 if queue is empty. diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc index 964475fd38..331f009287 100644 --- a/webrtc/video/video_send_stream.cc +++ b/webrtc/video/video_send_stream.cc @@ -748,6 +748,9 @@ VideoSendStreamImpl::VideoSendStreamImpl( RTC_DCHECK(congestion_controller_); RTC_DCHECK(remb_); + congestion_controller_->EnablePeriodicAlrProbing( + config_->periodic_alr_bandwidth_probing); + // RTP/RTCP initialization. for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) { congestion_controller_->packet_router()->AddRtpModule(rtp_rtcp); diff --git a/webrtc/video_send_stream.h b/webrtc/video_send_stream.h index ce16ef3b0c..fb5e9d877d 100644 --- a/webrtc/video_send_stream.h +++ b/webrtc/video_send_stream.h @@ -185,6 +185,9 @@ class VideoSendStream { // stream may send at a rate higher than the estimated available bitrate. bool suspend_below_min_bitrate = false; + // Enables periodic bandwidth probing in application-limited region. + bool periodic_alr_bandwidth_probing = false; + private: // Access to the copy constructor is private to force use of the Copy() // method for those exceptional cases where we do use it.