Implement periodic bandwidth probing in application-limited region.
Now ProbeController can send periodic bandwidth probes when in application-limited region. This will allow to maintain correct bottleneck bandwidth estimate, even not all bandwidth is being used. The feature is not enabled by default, but can be enabled with a flag. Interval between probes is currently set to 5 seconds. BUG=webrtc:6332 Review-Url: https://codereview.webrtc.org/2504023002 Cr-Commit-Position: refs/heads/master@{#15279}
This commit is contained in:
parent
bf22be902e
commit
80ed35e21c
@ -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;
|
||||
};
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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<int64_t> 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<int> 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
|
||||
|
||||
@ -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<int> bitrates_to_probe,
|
||||
void InitiateProbing(int64_t now_ms,
|
||||
std::initializer_list<int> 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);
|
||||
};
|
||||
|
||||
@ -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<int64_t>(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<int64_t>(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<int64_t>(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<int64_t>(start_time)));
|
||||
clock_.AdvanceTimeMilliseconds(1000);
|
||||
probe_controller_->Process();
|
||||
probe_controller_->SetEstimatedBitrate(500);
|
||||
testing::Mock::VerifyAndClearExpectations(&pacer_);
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace webrtc
|
||||
|
||||
@ -44,10 +44,10 @@ void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t now_ms) {
|
||||
return;
|
||||
|
||||
int percentage = static_cast<int>(*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<int64_t>(now_ms);
|
||||
} else if (percentage > kAlrEndUsagePercent && alr_started_time_ms_) {
|
||||
alr_started_time_ms_ = rtc::Optional<int64_t>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,8 +56,9 @@ void AlrDetector::SetEstimatedBitrate(int bitrate_bps) {
|
||||
estimated_bitrate_bps_ = bitrate_bps;
|
||||
}
|
||||
|
||||
bool AlrDetector::InApplicationLimitedRegion() const {
|
||||
return application_limited_;
|
||||
rtc::Optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime()
|
||||
const {
|
||||
return alr_started_time_ms_;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -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<int64_t> GetApplicationLimitedRegionStartTime() const;
|
||||
|
||||
private:
|
||||
RateStatistics rate_;
|
||||
int estimated_bitrate_bps_ = 0;
|
||||
bool application_limited_ = false;
|
||||
|
||||
// Non-empty in ALR state.
|
||||
rtc::Optional<int64_t> alr_started_time_ms_;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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<int64_t>());
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -343,9 +343,10 @@ int64_t PacedSender::ExpectedQueueTimeMs() const {
|
||||
pacing_bitrate_kbps_);
|
||||
}
|
||||
|
||||
bool PacedSender::InApplicationLimitedRegion() const {
|
||||
rtc::Optional<int64_t> PacedSender::GetApplicationLimitedRegionStartTime()
|
||||
const {
|
||||
CriticalSectionScoped cs(critsect_.get());
|
||||
return alr_detector_->InApplicationLimitedRegion();
|
||||
return alr_detector_->GetApplicationLimitedRegionStartTime();
|
||||
}
|
||||
|
||||
size_t PacedSender::QueueSizePackets() const {
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#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<int64_t> 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.
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user