From a42055116d3f0c20f7ddcb011926e97e2a6bcc08 Mon Sep 17 00:00:00 2001 From: philipel Date: Tue, 26 Sep 2017 05:36:58 -0700 Subject: [PATCH] Push back on the video encoder to avoid building queues in the pacer. Implemented behind the field trial "WebRTC-PacerPushbackExperiment/Enabled/" BUG=webrtc:8171, webrtc:8287 Review-Url: https://codereview.webrtc.org/3004783002 Cr-Commit-Position: refs/heads/master@{#19969} --- .../include/send_side_congestion_controller.h | 3 ++ .../send_side_congestion_controller.cc | 30 +++++++++++-- ...end_side_congestion_controller_unittest.cc | 43 ++++++++++++++++++- 3 files changed, 72 insertions(+), 4 deletions(-) diff --git a/modules/congestion_controller/include/send_side_congestion_controller.h b/modules/congestion_controller/include/send_side_congestion_controller.h index 2d3e1e6a12..ebb2e67644 100644 --- a/modules/congestion_controller/include/send_side_congestion_controller.h +++ b/modules/congestion_controller/include/send_side_congestion_controller.h @@ -154,6 +154,9 @@ class SendSideCongestionController : public CallStatsObserver, rtc::RaceChecker worker_race_; + bool pacer_pushback_experiment_ = false; + float encoding_rate_ = 1.0; + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(SendSideCongestionController); }; diff --git a/modules/congestion_controller/send_side_congestion_controller.cc b/modules/congestion_controller/send_side_congestion_controller.cc index 6014164edc..527dd07ba3 100644 --- a/modules/congestion_controller/send_side_congestion_controller.cc +++ b/modules/congestion_controller/send_side_congestion_controller.cc @@ -32,6 +32,7 @@ namespace webrtc { namespace { const char kCwndExperiment[] = "WebRTC-CwndExperiment"; +const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment"; const int64_t kDefaultAcceptedQueueMs = 250; bool CwndExperimentEnabled() { @@ -122,7 +123,9 @@ SendSideCongestionController::SendSideCongestionController( delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), in_cwnd_experiment_(CwndExperimentEnabled()), accepted_queue_ms_(kDefaultAcceptedQueueMs), - was_in_alr_(0) { + was_in_alr_(false), + pacer_pushback_experiment_( + webrtc::field_trial::IsEnabled(kPacerPushbackExperiment)) { delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); if (in_cwnd_experiment_ && !ReadCwndExperimentParameter(&accepted_queue_ms_)) { @@ -159,7 +162,9 @@ SendSideCongestionController::SendSideCongestionController( delay_based_bwe_(new DelayBasedBwe(event_log_, clock_)), in_cwnd_experiment_(CwndExperimentEnabled()), accepted_queue_ms_(kDefaultAcceptedQueueMs), - was_in_alr_(0) { + was_in_alr_(false), + pacer_pushback_experiment_( + webrtc::field_trial::IsEnabled(kPacerPushbackExperiment)) { delay_based_bwe_->SetMinBitrate(min_bitrate_bps_); if (in_cwnd_experiment_ && !ReadCwndExperimentParameter(&accepted_queue_ms_)) { @@ -416,7 +421,26 @@ void SendSideCongestionController::MaybeTriggerOnNetworkChanged() { retransmission_rate_limiter_->SetMaxRate(bitrate_bps); } - bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps; + if (!pacer_pushback_experiment_) { + bitrate_bps = IsNetworkDown() || IsSendQueueFull() ? 0 : bitrate_bps; + } else { + if (IsNetworkDown()) { + bitrate_bps = 0; + } else { + int64_t queue_length_ms = pacer_->ExpectedQueueTimeMs(); + + if (queue_length_ms == 0) { + encoding_rate_ = 1.0; + } else if (queue_length_ms > 50) { + float encoding_rate = 1.0 - queue_length_ms / 1000.0; + encoding_rate_ = std::min(encoding_rate_, encoding_rate); + encoding_rate_ = std::max(encoding_rate_, 0.0f); + } + + bitrate_bps *= encoding_rate_; + bitrate_bps = bitrate_bps < 50000 ? 0 : bitrate_bps; + } + } if (HasNetworkParametersToReportChanged(bitrate_bps, fraction_loss, rtt)) { int64_t probing_interval_ms; diff --git a/modules/congestion_controller/send_side_congestion_controller_unittest.cc b/modules/congestion_controller/send_side_congestion_controller_unittest.cc index 10fedfb2c0..b2f5562d50 100644 --- a/modules/congestion_controller/send_side_congestion_controller_unittest.cc +++ b/modules/congestion_controller/send_side_congestion_controller_unittest.cc @@ -8,22 +8,24 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include "modules/congestion_controller/include/send_side_congestion_controller.h" #include "logging/rtc_event_log/mock/mock_rtc_event_log.h" #include "modules/bitrate_controller/include/bitrate_controller.h" #include "modules/congestion_controller/congestion_controller_unittests_helper.h" #include "modules/congestion_controller/include/mock/mock_congestion_observer.h" +#include "modules/congestion_controller/include/send_side_congestion_controller.h" #include "modules/pacing/mock/mock_paced_sender.h" #include "modules/remote_bitrate_estimator/include/bwe_defines.h" #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" #include "rtc_base/socket.h" #include "system_wrappers/include/clock.h" +#include "test/field_trial.h" #include "test/gmock.h" #include "test/gtest.h" using testing::_; using testing::AtLeast; +using testing::Ge; using testing::NiceMock; using testing::Return; using testing::SaveArg; @@ -455,5 +457,44 @@ TEST_F(SendSideCongestionControllerTest, UpdatesDelayBasedEstimate) { PacketTransmissionAndFeedbackBlock(&seq_num, kRunTimeMs, 50); EXPECT_LT(*target_bitrate_bps_, bitrate_before_delay); } + +TEST_F(SendSideCongestionControllerTest, PacerQueueEncodeRatePushback) { + ScopedFieldTrials pushback_field_trial( + "WebRTC-PacerPushbackExperiment/Enabled/"); + SetUp(); + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0)); + controller_->Process(); + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(100)); + EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps * 0.9, _, _, _)); + controller_->Process(); + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(50)); + controller_->Process(); + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0)); + EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _)); + controller_->Process(); + + const uint32_t kMinAdjustedBps = 50000; + int expected_queue_threshold = + 1000 - kMinAdjustedBps * 1000.0 / kInitialBitrateBps; + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()) + .WillOnce(Return(expected_queue_threshold)); + EXPECT_CALL(observer_, OnNetworkChanged(Ge(kMinAdjustedBps), _, _, _)); + controller_->Process(); + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()) + .WillOnce(Return(expected_queue_threshold + 1)); + EXPECT_CALL(observer_, OnNetworkChanged(0, _, _, _)); + controller_->Process(); + + EXPECT_CALL(*pacer_, ExpectedQueueTimeMs()).WillOnce(Return(0)); + EXPECT_CALL(observer_, OnNetworkChanged(kInitialBitrateBps, _, _, _)); + controller_->Process(); +} + } // namespace test } // namespace webrtc