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}
diff --git a/modules/congestion_controller/include/send_side_congestion_controller.h b/modules/congestion_controller/include/send_side_congestion_controller.h
index 2d3e1e6..ebb2e67 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 @@
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 6014164..527dd07 100644
--- a/modules/congestion_controller/send_side_congestion_controller.cc
+++ b/modules/congestion_controller/send_side_congestion_controller.cc
@@ -32,6 +32,7 @@
namespace {
const char kCwndExperiment[] = "WebRTC-CwndExperiment";
+const char kPacerPushbackExperiment[] = "WebRTC-PacerPushbackExperiment";
const int64_t kDefaultAcceptedQueueMs = 250;
bool CwndExperimentEnabled() {
@@ -122,7 +123,9 @@
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 @@
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 @@
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 10fedfb..b2f5562 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 @@
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