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