Support REMB in combination with send-side BWE.

BUG=webrtc:4173

Review URL: https://codereview.webrtc.org/1581113006

Cr-Commit-Position: refs/heads/master@{#11322}
diff --git a/webrtc/call/congestion_controller.cc b/webrtc/call/congestion_controller.cc
index 4030f8e..0267d79 100644
--- a/webrtc/call/congestion_controller.cc
+++ b/webrtc/call/congestion_controller.cc
@@ -237,8 +237,7 @@
 CongestionController::GetTransportFeedbackObserver() {
   if (transport_feedback_adapter_.get() == nullptr) {
     transport_feedback_adapter_.reset(new TransportFeedbackAdapter(
-        bitrate_controller_->CreateRtcpBandwidthObserver(),
-        Clock::GetRealTimeClock(), process_thread_));
+        bitrate_controller_.get(), Clock::GetRealTimeClock(), process_thread_));
     transport_feedback_adapter_->SetBitrateEstimator(
         new RemoteBitrateEstimatorAbsSendTime(
             transport_feedback_adapter_.get(), Clock::GetRealTimeClock()));
diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc b/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc
index f8fd2bb..da51c6f 100644
--- a/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc
+++ b/webrtc/modules/bitrate_controller/bitrate_controller_impl.cc
@@ -143,6 +143,15 @@
   MaybeTriggerOnNetworkChanged();
 }
 
+void BitrateControllerImpl::UpdateDelayBasedEstimate(uint32_t bitrate_bps) {
+  {
+    rtc::CritScope cs(&critsect_);
+    bandwidth_estimation_.UpdateDelayBasedEstimate(clock_->TimeInMilliseconds(),
+                                                   bitrate_bps);
+  }
+  MaybeTriggerOnNetworkChanged();
+}
+
 int64_t BitrateControllerImpl::TimeUntilNextProcess() {
   const int64_t kBitrateControllerUpdateIntervalMs = 25;
   rtc::CritScope cs(&critsect_);
diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_impl.h b/webrtc/modules/bitrate_controller/bitrate_controller_impl.h
index b601899..d7888cc 100644
--- a/webrtc/modules/bitrate_controller/bitrate_controller_impl.h
+++ b/webrtc/modules/bitrate_controller/bitrate_controller_impl.h
@@ -36,8 +36,9 @@
   RtcpBandwidthObserver* CreateRtcpBandwidthObserver() override;
 
   void SetStartBitrate(int start_bitrate_bps) override;
-  void SetMinMaxBitrate(int min_bitrate_bps,
-                                int max_bitrate_bps) override;
+  void SetMinMaxBitrate(int min_bitrate_bps, int max_bitrate_bps) override;
+
+  void UpdateDelayBasedEstimate(uint32_t bitrate_bps) override;
 
   void SetReservedBitrate(uint32_t reserved_bitrate_bps) override;
 
diff --git a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
index 2b9e589..fd9636a 100644
--- a/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
+++ b/webrtc/modules/bitrate_controller/bitrate_controller_unittest.cc
@@ -162,14 +162,18 @@
   bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, 50, time_ms);
   EXPECT_EQ(300000, bitrate_observer_.last_bitrate_);
 
-  // Test that a low REMB trigger immediately.
+  // Test that a low delay-based estimate limits the combined estimate.
+  controller_->UpdateDelayBasedEstimate(280000);
+  EXPECT_EQ(280000, bitrate_observer_.last_bitrate_);
+
+  // Test that a low REMB limits the combined estimate.
   bandwidth_observer_->OnReceivedEstimatedBitrate(250000);
   EXPECT_EQ(250000, bitrate_observer_.last_bitrate_);
   EXPECT_EQ(0, bitrate_observer_.last_fraction_loss_);
   EXPECT_EQ(50, bitrate_observer_.last_rtt_);
 
   bandwidth_observer_->OnReceivedEstimatedBitrate(1000);
-  EXPECT_EQ(100000, bitrate_observer_.last_bitrate_);  // Min cap.
+  EXPECT_EQ(100000, bitrate_observer_.last_bitrate_);
 }
 
 TEST_F(BitrateControllerTest, OneBitrateObserverTwoRtcpObservers) {
diff --git a/webrtc/modules/bitrate_controller/include/bitrate_controller.h b/webrtc/modules/bitrate_controller/include/bitrate_controller.h
index d1eca8e..a9c247a 100644
--- a/webrtc/modules/bitrate_controller/include/bitrate_controller.h
+++ b/webrtc/modules/bitrate_controller/include/bitrate_controller.h
@@ -57,6 +57,8 @@
   virtual void SetStartBitrate(int start_bitrate_bps) = 0;
   virtual void SetMinMaxBitrate(int min_bitrate_bps, int max_bitrate_bps) = 0;
 
+  virtual void UpdateDelayBasedEstimate(uint32_t bitrate_bps) = 0;
+
   virtual void SetEventLog(RtcEventLog* event_log) = 0;
 
   // Gets the available payload bandwidth in bits per second. Note that
diff --git a/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h b/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
index 7a7d2e4..8748696 100644
--- a/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
+++ b/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
@@ -24,6 +24,21 @@
                     uint8_t fraction_loss,
                     int64_t rtt_ms));
 };
+
+class MockBitrateController : public BitrateController {
+ public:
+  MOCK_METHOD0(CreateRtcpBandwidthObserver, RtcpBandwidthObserver*());
+  MOCK_METHOD1(SetStartBitrate, void(int start_bitrate_bps));
+  MOCK_METHOD2(SetMinMaxBitrate,
+               void(int min_bitrate_bps, int max_bitrate_bps));
+  MOCK_METHOD1(UpdateDelayBasedEstimate, void(uint32_t bitrate_bps));
+  MOCK_METHOD1(SetEventLog, void(RtcEventLog* event_log));
+  MOCK_CONST_METHOD1(AvailableBandwidth, bool(uint32_t* bandwidth));
+  MOCK_METHOD1(SetReservedBitrate, void(uint32_t reserved_bitrate_bps));
+
+  MOCK_METHOD0(Process, int());
+  MOCK_METHOD0(TimeUntilNextProcess, int64_t());
+};
 }  // namespace test
 }  // namespace webrtc
 
diff --git a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc
index 258c4d9..6891290 100644
--- a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc
+++ b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.cc
@@ -55,6 +55,7 @@
       last_fraction_loss_(0),
       last_round_trip_time_ms_(0),
       bwe_incoming_(0),
+      delay_based_bitrate_bps_(0),
       time_last_decrease_ms_(0),
       first_report_time_ms_(-1),
       initially_lost_packets_(0),
@@ -104,6 +105,13 @@
   bitrate_ = CapBitrateToThresholds(now_ms, bitrate_);
 }
 
+void SendSideBandwidthEstimation::UpdateDelayBasedEstimate(
+    int64_t now_ms,
+    uint32_t bitrate_bps) {
+  delay_based_bitrate_bps_ = bitrate_bps;
+  bitrate_ = CapBitrateToThresholds(now_ms, bitrate_);
+}
+
 void SendSideBandwidthEstimation::UpdateReceiverBlock(uint8_t fraction_loss,
                                                       int64_t rtt,
                                                       int number_of_packets,
@@ -268,6 +276,9 @@
   if (bwe_incoming_ > 0 && bitrate > bwe_incoming_) {
     bitrate = bwe_incoming_;
   }
+  if (delay_based_bitrate_bps_ > 0 && bitrate > delay_based_bitrate_bps_) {
+    bitrate = delay_based_bitrate_bps_;
+  }
   if (bitrate > max_bitrate_configured_) {
     bitrate = max_bitrate_configured_;
   }
diff --git a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h
index 7ffb42c..608a5e7 100644
--- a/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h
+++ b/webrtc/modules/bitrate_controller/send_side_bandwidth_estimation.h
@@ -35,6 +35,9 @@
   // Call when we receive a RTCP message with TMMBR or REMB.
   void UpdateReceiverEstimate(int64_t now_ms, uint32_t bandwidth);
 
+  // Call when a new delay-based estimate is available.
+  void UpdateDelayBasedEstimate(int64_t now_ms, uint32_t bitrate_bps);
+
   // Call when we receive a RTCP message with a ReceiveBlock.
   void UpdateReceiverBlock(uint8_t fraction_loss,
                            int64_t rtt,
@@ -80,6 +83,7 @@
   int64_t last_round_trip_time_ms_;
 
   uint32_t bwe_incoming_;
+  uint32_t delay_based_bitrate_bps_;
   int64_t time_last_decrease_ms_;
   int64_t first_report_time_ms_;
   int initially_lost_packets_;
diff --git a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc
index 5904594..7e45136 100644
--- a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc
+++ b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.cc
@@ -27,11 +27,11 @@
 const int64_t kBaseTimestampRangeSizeUs = kBaseTimestampScaleFactor * (1 << 24);
 
 TransportFeedbackAdapter::TransportFeedbackAdapter(
-    RtcpBandwidthObserver* bandwidth_observer,
+    BitrateController* bitrate_controller,
     Clock* clock,
     ProcessThread* process_thread)
     : send_time_history_(clock, kSendTimeHistoryWindowMs),
-      rtcp_bandwidth_observer_(bandwidth_observer),
+      bitrate_controller_(bitrate_controller),
       process_thread_(process_thread),
       clock_(clock),
       current_offset_ms_(kNoTimestamp),
@@ -124,7 +124,7 @@
 void TransportFeedbackAdapter::OnReceiveBitrateChanged(
     const std::vector<unsigned int>& ssrcs,
     unsigned int bitrate) {
-  rtcp_bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate);
+  bitrate_controller_->UpdateDelayBasedEstimate(bitrate);
 }
 
 void TransportFeedbackAdapter::OnRttUpdate(int64_t avg_rtt_ms,
diff --git a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h
index 93f30e6..c142eea 100644
--- a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h
+++ b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h
@@ -15,7 +15,7 @@
 
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/thread_annotations.h"
-#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
+#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
 #include "webrtc/modules/include/module_common_types.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/send_time_history.h"
@@ -28,7 +28,7 @@
                                  public CallStatsObserver,
                                  public RemoteBitrateObserver {
  public:
-  TransportFeedbackAdapter(RtcpBandwidthObserver* bandwidth_observer,
+  TransportFeedbackAdapter(BitrateController* bitrate_controller,
                            Clock* clock,
                            ProcessThread* process_thread);
   virtual ~TransportFeedbackAdapter();
@@ -54,7 +54,7 @@
 
   rtc::CriticalSection lock_;
   SendTimeHistory send_time_history_ GUARDED_BY(&lock_);
-  rtc::scoped_ptr<RtcpBandwidthObserver> rtcp_bandwidth_observer_;
+  BitrateController* bitrate_controller_;
   rtc::scoped_ptr<RemoteBitrateEstimator> bitrate_estimator_;
   ProcessThread* const process_thread_;
   Clock* const clock_;
diff --git a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc
index 64d0e55..f2ef5d9 100644
--- a/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc
+++ b/webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter_unittest.cc
@@ -16,6 +16,7 @@
 
 #include "webrtc/base/checks.h"
 #include "webrtc/base/scoped_ptr.h"
+#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
 #include "webrtc/modules/remote_bitrate_estimator/transport_feedback_adapter.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -34,13 +35,14 @@
   TransportFeedbackAdapterTest()
       : clock_(0),
         bitrate_estimator_(nullptr),
+        bitrate_controller_(this),
         receiver_estimated_bitrate_(0) {}
 
   virtual ~TransportFeedbackAdapterTest() {}
 
   virtual void SetUp() {
-    adapter_.reset(new TransportFeedbackAdapter(
-        new RtcpBandwidthObserverAdapter(this), &clock_, &process_thread_));
+    adapter_.reset(new TransportFeedbackAdapter(&bitrate_controller_, &clock_,
+                                                &process_thread_));
 
     bitrate_estimator_ = new MockRemoteBitrateEstimator();
     EXPECT_CALL(process_thread_, RegisterModule(bitrate_estimator_)).Times(1);
@@ -55,19 +57,15 @@
  protected:
   // Proxy class used since TransportFeedbackAdapter will own the instance
   // passed at construction.
-  class RtcpBandwidthObserverAdapter : public RtcpBandwidthObserver {
+  class MockBitrateControllerAdapter : public MockBitrateController {
    public:
-    explicit RtcpBandwidthObserverAdapter(TransportFeedbackAdapterTest* owner)
-        : owner_(owner) {}
+    explicit MockBitrateControllerAdapter(TransportFeedbackAdapterTest* owner)
+        : MockBitrateController(), owner_(owner) {}
 
-    void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
-      owner_->receiver_estimated_bitrate_ = bitrate;
-    }
+    ~MockBitrateControllerAdapter() override {}
 
-    void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
-                                      int64_t rtt,
-                                      int64_t now_ms) override {
-      RTC_NOTREACHED();
+    void UpdateDelayBasedEstimate(uint32_t bitrate_bps) override {
+      owner_->receiver_estimated_bitrate_ = bitrate_bps;
     }
 
     TransportFeedbackAdapterTest* const owner_;
@@ -113,6 +111,7 @@
   SimulatedClock clock_;
   MockProcessThread process_thread_;
   MockRemoteBitrateEstimator* bitrate_estimator_;
+  MockBitrateControllerAdapter bitrate_controller_;
   rtc::scoped_ptr<TransportFeedbackAdapter> adapter_;
 
   uint32_t receiver_estimated_bitrate_;
diff --git a/webrtc/video/end_to_end_tests.cc b/webrtc/video/end_to_end_tests.cc
index 48dc3e8..0bf7570 100644
--- a/webrtc/video/end_to_end_tests.cc
+++ b/webrtc/video/end_to_end_tests.cc
@@ -20,6 +20,7 @@
 #include "webrtc/call.h"
 #include "webrtc/call/transport_adapter.h"
 #include "webrtc/frame_callback.h"
+#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
@@ -1807,6 +1808,143 @@
   RunBaseTest(&test);
 }
 
+
+// Verifies that it's possible to limit the send BWE by sending a REMB.
+// This is verified by allowing the send BWE to ramp-up to >1000 kbps,
+// then have the test generate a REMB of 500 kbps and verify that the send BWE
+// is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the
+// test verifies that the send BWE ramps back up to exactly 1000 kbps.
+TEST_F(EndToEndTest, RembWithSendSideBwe) {
+  class BweObserver : public test::EndToEndTest {
+   public:
+    BweObserver()
+        : EndToEndTest(kDefaultTimeoutMs),
+          sender_call_(nullptr),
+          clock_(Clock::GetRealTimeClock()),
+          sender_ssrc_(0),
+          remb_bitrate_bps_(1000000),
+          receive_transport_(nullptr),
+          event_(false, false),
+          poller_thread_(&BitrateStatsPollingThread,
+                         this,
+                         "BitrateStatsPollingThread"),
+          state_(kWaitForFirstRampUp) {}
+
+    ~BweObserver() {}
+
+    test::PacketTransport* CreateReceiveTransport() {
+      receive_transport_ = new test::PacketTransport(
+          nullptr, this, test::PacketTransport::kReceiver,
+          FakeNetworkPipe::Config());
+      return receive_transport_;
+    }
+
+    Call::Config GetSenderCallConfig() override {
+      Call::Config config;
+      // Set a high start bitrate to reduce the test completion time.
+      config.bitrate_config.start_bitrate_bps = remb_bitrate_bps_;
+      return config;
+    }
+
+    void ModifyVideoConfigs(
+        VideoSendStream::Config* send_config,
+        std::vector<VideoReceiveStream::Config>* receive_configs,
+        VideoEncoderConfig* encoder_config) override {
+      ASSERT_EQ(1u, send_config->rtp.ssrcs.size());
+      send_config->rtp.extensions.clear();
+      send_config->rtp.extensions.push_back(
+          RtpExtension(RtpExtension::kTransportSequenceNumber,
+                       test::kTransportSequenceNumberExtensionId));
+      sender_ssrc_ = send_config->rtp.ssrcs[0];
+
+      encoder_config->streams[0].max_bitrate_bps =
+          encoder_config->streams[0].target_bitrate_bps = 2000000;
+
+      ASSERT_EQ(1u, receive_configs->size());
+      (*receive_configs)[0].rtp.remb = false;
+      (*receive_configs)[0].rtp.transport_cc = true;
+      (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
+      RtpRtcp::Configuration config;
+      config.receiver_only = true;
+      config.clock = clock_;
+      config.outgoing_transport = receive_transport_;
+      rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
+      rtp_rtcp_->SetRemoteSSRC((*receive_configs)[0].rtp.remote_ssrc);
+      rtp_rtcp_->SetSSRC((*receive_configs)[0].rtp.local_ssrc);
+      rtp_rtcp_->SetREMBStatus(true);
+      rtp_rtcp_->SetSendingStatus(true);
+      rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
+    }
+
+    void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
+      sender_call_ = sender_call;
+    }
+
+    static bool BitrateStatsPollingThread(void* obj) {
+      return static_cast<BweObserver*>(obj)->PollStats();
+    }
+
+    bool PollStats() {
+      if (sender_call_) {
+        Call::Stats stats = sender_call_->GetStats();
+        switch (state_) {
+          case kWaitForFirstRampUp:
+            if (stats.send_bandwidth_bps >= remb_bitrate_bps_) {
+              state_ = kWaitForRemb;
+              remb_bitrate_bps_ /= 2;
+              rtp_rtcp_->SetREMBData(
+                  remb_bitrate_bps_,
+                  std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
+              rtp_rtcp_->SendRTCP(kRtcpRr);
+            }
+            break;
+
+          case kWaitForRemb:
+            if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
+              state_ = kWaitForSecondRampUp;
+              remb_bitrate_bps_ *= 2;
+              rtp_rtcp_->SetREMBData(
+                  remb_bitrate_bps_,
+                  std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
+              rtp_rtcp_->SendRTCP(kRtcpRr);
+            }
+            break;
+
+          case kWaitForSecondRampUp:
+            if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
+              observation_complete_.Set();
+            }
+            break;
+        }
+      }
+
+      return !event_.Wait(1000);
+    }
+
+    void PerformTest() override {
+      poller_thread_.Start();
+      EXPECT_TRUE(Wait())
+          << "Timed out while waiting for bitrate to change according to REMB.";
+      poller_thread_.Stop();
+    }
+
+   private:
+    enum TestState { kWaitForFirstRampUp, kWaitForRemb, kWaitForSecondRampUp };
+
+    Call* sender_call_;
+    Clock* const clock_;
+    uint32_t sender_ssrc_;
+    int remb_bitrate_bps_;
+    rtc::scoped_ptr<RtpRtcp> rtp_rtcp_;
+    test::PacketTransport* receive_transport_;
+    rtc::Event event_;
+    rtc::PlatformThread poller_thread_;
+    TestState state_;
+  } test;
+
+  RunBaseTest(&test);
+}
+
 TEST_F(EndToEndTest, VerifyNackStats) {
   static const int kPacketNumberToDrop = 200;
   class NackObserver : public test::EndToEndTest {