Wire-up BWE feedback for audio receive streams.

Also wires up receiving transport sequence numbers.

BUG=webrtc:5263
R=mflodman@webrtc.org, pbos@webrtc.org, solenberg@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#11220}
diff --git a/webrtc/audio/audio_receive_stream.cc b/webrtc/audio/audio_receive_stream.cc
index dfad79f..64d0083 100644
--- a/webrtc/audio/audio_receive_stream.cc
+++ b/webrtc/audio/audio_receive_stream.cc
@@ -18,6 +18,7 @@
 #include "webrtc/audio/conversion.h"
 #include "webrtc/base/checks.h"
 #include "webrtc/base/logging.h"
+#include "webrtc/call/congestion_controller.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "webrtc/system_wrappers/include/tick_util.h"
 #include "webrtc/voice_engine/channel_proxy.h"
@@ -30,6 +31,21 @@
 #include "webrtc/voice_engine/voice_engine_impl.h"
 
 namespace webrtc {
+namespace {
+
+bool UseSendSideBwe(const webrtc::AudioReceiveStream::Config& config) {
+  if (!config.rtp.transport_cc) {
+    return false;
+  }
+  for (const auto& extension : config.rtp.extensions) {
+    if (extension.name == RtpExtension::kTransportSequenceNumber) {
+      return true;
+    }
+  }
+  return false;
+}
+}  // namespace
+
 std::string AudioReceiveStream::Config::Rtp::ToString() const {
   std::stringstream ss;
   ss << "{remote_ssrc: " << remote_ssrc;
@@ -65,17 +81,16 @@
 
 namespace internal {
 AudioReceiveStream::AudioReceiveStream(
-    RemoteBitrateEstimator* remote_bitrate_estimator,
+    CongestionController* congestion_controller,
     const webrtc::AudioReceiveStream::Config& config,
     const rtc::scoped_refptr<webrtc::AudioState>& audio_state)
-    : remote_bitrate_estimator_(remote_bitrate_estimator),
-      config_(config),
+    : config_(config),
       audio_state_(audio_state),
       rtp_header_parser_(RtpHeaderParser::Create()) {
   LOG(LS_INFO) << "AudioReceiveStream: " << config_.ToString();
   RTC_DCHECK_NE(config_.voe_channel_id, -1);
-  RTC_DCHECK(remote_bitrate_estimator_);
   RTC_DCHECK(audio_state_.get());
+  RTC_DCHECK(congestion_controller);
   RTC_DCHECK(rtp_header_parser_);
 
   VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine());
@@ -93,8 +108,6 @@
           kRtpExtensionAbsoluteSendTime, extension.id);
       RTC_DCHECK(registered);
     } else if (extension.name == RtpExtension::kTransportSequenceNumber) {
-      // TODO(holmer): Need to do something here or in  DeliverRtp() to actually
-      //               handle audio packets with this header extension.
       bool registered = rtp_header_parser_->RegisterRtpHeaderExtension(
           kRtpExtensionTransportSequenceNumber, extension.id);
       RTC_DCHECK(registered);
@@ -102,11 +115,28 @@
       RTC_NOTREACHED() << "Unsupported RTP extension.";
     }
   }
+  // Configure bandwidth estimation.
+  channel_proxy_->SetCongestionControlObjects(
+      nullptr, nullptr, congestion_controller->packet_router());
+  if (config.combined_audio_video_bwe) {
+    if (UseSendSideBwe(config)) {
+      remote_bitrate_estimator_ =
+          congestion_controller->GetRemoteBitrateEstimator(true);
+    } else {
+      remote_bitrate_estimator_ =
+          congestion_controller->GetRemoteBitrateEstimator(false);
+    }
+    RTC_DCHECK(remote_bitrate_estimator_);
+  }
 }
 
 AudioReceiveStream::~AudioReceiveStream() {
   RTC_DCHECK(thread_checker_.CalledOnValidThread());
   LOG(LS_INFO) << "~AudioReceiveStream: " << config_.ToString();
+  channel_proxy_->SetCongestionControlObjects(nullptr, nullptr, nullptr);
+  if (remote_bitrate_estimator_) {
+    remote_bitrate_estimator_->RemoveStream(config_.rtp.remote_ssrc);
+  }
 }
 
 void AudioReceiveStream::Start() {
@@ -141,10 +171,12 @@
     return false;
   }
 
-  // Only forward if the parsed header has absolute sender time. RTP timestamps
-  // may have different rates for audio and video and shouldn't be mixed.
-  if (config_.combined_audio_video_bwe &&
-      header.extension.hasAbsoluteSendTime) {
+  // Only forward if the parsed header has one of the headers necessary for
+  // bandwidth estimation. RTP timestamps has different rates for audio and
+  // video and shouldn't be mixed.
+  if (remote_bitrate_estimator_ &&
+      (header.extension.hasAbsoluteSendTime ||
+       header.extension.hasTransportSequenceNumber)) {
     int64_t arrival_time_ms = TickTime::MillisecondTimestamp();
     if (packet_time.timestamp >= 0)
       arrival_time_ms = (packet_time.timestamp + 500) / 1000;
diff --git a/webrtc/audio/audio_receive_stream.h b/webrtc/audio/audio_receive_stream.h
index 42286af..4940c6a 100644
--- a/webrtc/audio/audio_receive_stream.h
+++ b/webrtc/audio/audio_receive_stream.h
@@ -17,6 +17,7 @@
 #include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
 
 namespace webrtc {
+class CongestionController;
 class RemoteBitrateEstimator;
 
 namespace voe {
@@ -27,7 +28,7 @@
 
 class AudioReceiveStream final : public webrtc::AudioReceiveStream {
  public:
-  AudioReceiveStream(RemoteBitrateEstimator* remote_bitrate_estimator,
+  AudioReceiveStream(CongestionController* congestion_controller,
                      const webrtc::AudioReceiveStream::Config& config,
                      const rtc::scoped_refptr<webrtc::AudioState>& audio_state);
   ~AudioReceiveStream() override;
@@ -52,7 +53,7 @@
   VoiceEngine* voice_engine() const;
 
   rtc::ThreadChecker thread_checker_;
-  RemoteBitrateEstimator* const remote_bitrate_estimator_;
+  RemoteBitrateEstimator* remote_bitrate_estimator_ = nullptr;
   const webrtc::AudioReceiveStream::Config config_;
   rtc::scoped_refptr<webrtc::AudioState> audio_state_;
   rtc::scoped_ptr<RtpHeaderParser> rtp_header_parser_;
diff --git a/webrtc/audio/audio_receive_stream_unittest.cc b/webrtc/audio/audio_receive_stream_unittest.cc
index 01e8a2b..eb008b3 100644
--- a/webrtc/audio/audio_receive_stream_unittest.cc
+++ b/webrtc/audio/audio_receive_stream_unittest.cc
@@ -14,10 +14,16 @@
 
 #include "webrtc/audio/audio_receive_stream.h"
 #include "webrtc/audio/conversion.h"
+#include "webrtc/call/mock/mock_congestion_controller.h"
+#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
+#include "webrtc/modules/pacing/packet_router.h"
 #include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_estimator.h"
 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
+#include "webrtc/modules/utility/include/mock/mock_process_thread.h"
+#include "webrtc/system_wrappers/include/clock.h"
 #include "webrtc/test/mock_voe_channel_proxy.h"
 #include "webrtc/test/mock_voice_engine.h"
+#include "webrtc/video/call_stats.h"
 
 namespace webrtc {
 namespace test {
@@ -40,9 +46,11 @@
 const int kChannelId = 2;
 const uint32_t kRemoteSsrc = 1234;
 const uint32_t kLocalSsrc = 5678;
-const size_t kAbsoluteSendTimeLength = 4;
+const size_t kOneByteExtensionHeaderLength = 4;
+const size_t kOneByteExtensionLength = 4;
 const int kAbsSendTimeId = 2;
 const int kAudioLevelId = 3;
+const int kTransportSequenceNumberId = 4;
 const int kJitterBufferDelay = -7;
 const int kPlayoutBufferDelay = 302;
 const unsigned int kSpeechOutputLevel = 99;
@@ -55,7 +63,12 @@
 const AudioDecodingCallStats kAudioDecodeStats = MakeAudioDecodeStatsForTest();
 
 struct ConfigHelper {
-  ConfigHelper() {
+  ConfigHelper()
+      : simulated_clock_(123456),
+        call_stats_(&simulated_clock_),
+        congestion_controller_(&process_thread_,
+                               &call_stats_,
+                               &bitrate_observer_) {
     using testing::Invoke;
 
     EXPECT_CALL(voice_engine_,
@@ -77,6 +90,14 @@
           EXPECT_CALL(*channel_proxy_,
               SetReceiveAudioLevelIndicationStatus(true, kAudioLevelId))
                   .Times(1);
+          EXPECT_CALL(*channel_proxy_, SetCongestionControlObjects(
+                                           nullptr, nullptr, &packet_router_))
+              .Times(1);
+          EXPECT_CALL(congestion_controller_, packet_router())
+              .WillOnce(Return(&packet_router_));
+          EXPECT_CALL(*channel_proxy_,
+                      SetCongestionControlObjects(nullptr, nullptr, nullptr))
+              .Times(1);
           return channel_proxy_;
         }));
     stream_config_.voe_channel_id = kChannelId;
@@ -88,6 +109,9 @@
         RtpExtension(RtpExtension::kAudioLevel, kAudioLevelId));
   }
 
+  MockCongestionController* congestion_controller() {
+    return &congestion_controller_;
+  }
   MockRemoteBitrateEstimator* remote_bitrate_estimator() {
     return &remote_bitrate_estimator_;
   }
@@ -95,11 +119,19 @@
   rtc::scoped_refptr<AudioState> audio_state() { return audio_state_; }
   MockVoiceEngine& voice_engine() { return voice_engine_; }
 
+  void SetupMockForBweFeedback(bool send_side_bwe) {
+    EXPECT_CALL(congestion_controller_,
+                GetRemoteBitrateEstimator(send_side_bwe))
+        .WillOnce(Return(&remote_bitrate_estimator_));
+    EXPECT_CALL(remote_bitrate_estimator_,
+                RemoveStream(stream_config_.rtp.remote_ssrc));
+  }
+
   void SetupMockForGetStats() {
     using testing::DoAll;
     using testing::SetArgReferee;
 
-    EXPECT_TRUE(channel_proxy_);
+    ASSERT_TRUE(channel_proxy_);
     EXPECT_CALL(*channel_proxy_, GetRTCPStatistics())
         .WillOnce(Return(kCallStats));
     EXPECT_CALL(*channel_proxy_, GetDelayEstimate())
@@ -116,6 +148,12 @@
   }
 
  private:
+  SimulatedClock simulated_clock_;
+  CallStats call_stats_;
+  PacketRouter packet_router_;
+  testing::NiceMock<MockBitrateObserver> bitrate_observer_;
+  testing::NiceMock<MockProcessThread> process_thread_;
+  MockCongestionController congestion_controller_;
   MockRemoteBitrateEstimator remote_bitrate_estimator_;
   testing::StrictMock<MockVoiceEngine> voice_engine_;
   rtc::scoped_refptr<AudioState> audio_state_;
@@ -123,39 +161,43 @@
   testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
 };
 
-void BuildAbsoluteSendTimeExtension(uint8_t* buffer,
-                                    int id,
-                                    uint32_t abs_send_time) {
-  const size_t kRtpOneByteHeaderLength = 4;
+void BuildOneByteExtension(std::vector<uint8_t>::iterator it,
+                           int id,
+                           uint32_t extension_value,
+                           size_t value_length) {
   const uint16_t kRtpOneByteHeaderExtensionId = 0xBEDE;
-  ByteWriter<uint16_t>::WriteBigEndian(buffer, kRtpOneByteHeaderExtensionId);
+  ByteWriter<uint16_t>::WriteBigEndian(&(*it), kRtpOneByteHeaderExtensionId);
+  it += 2;
 
-  const uint32_t kPosLength = 2;
-  ByteWriter<uint16_t>::WriteBigEndian(buffer + kPosLength,
-                                       kAbsoluteSendTimeLength / 4);
-
-  const uint8_t kLengthOfData = 3;
-  buffer[kRtpOneByteHeaderLength] = (id << 4) + (kLengthOfData - 1);
-  ByteWriter<uint32_t, kLengthOfData>::WriteBigEndian(
-      buffer + kRtpOneByteHeaderLength + 1, abs_send_time);
+  ByteWriter<uint16_t>::WriteBigEndian(&(*it), kOneByteExtensionLength / 4);
+  it += 2;
+  const size_t kExtensionDataLength = kOneByteExtensionLength - 1;
+  uint32_t shifted_value = extension_value
+                           << (8 * (kExtensionDataLength - value_length));
+  *it = (id << 4) + (value_length - 1);
+  ++it;
+  ByteWriter<uint32_t, kExtensionDataLength>::WriteBigEndian(&(*it),
+                                                             shifted_value);
 }
 
-size_t CreateRtpHeaderWithAbsSendTime(uint8_t* header,
-                                      int extension_id,
-                                      uint32_t abs_send_time) {
+std::vector<uint8_t> CreateRtpHeaderWithOneByteExtension(
+    int extension_id,
+    uint32_t extension_value,
+    size_t value_length) {
+  std::vector<uint8_t> header;
+  header.resize(webrtc::kRtpHeaderSize + kOneByteExtensionHeaderLength +
+                kOneByteExtensionLength);
   header[0] = 0x80;   // Version 2.
   header[0] |= 0x10;  // Set extension bit.
   header[1] = 100;    // Payload type.
   header[1] |= 0x80;  // Marker bit is set.
-  ByteWriter<uint16_t>::WriteBigEndian(header + 2, 0x1234);  // Sequence number.
-  ByteWriter<uint32_t>::WriteBigEndian(header + 4, 0x5678);  // Timestamp.
-  ByteWriter<uint32_t>::WriteBigEndian(header + 8, 0x4321);  // SSRC.
-  int32_t rtp_header_length = webrtc::kRtpHeaderSize;
+  ByteWriter<uint16_t>::WriteBigEndian(&header[2], 0x1234);  // Sequence number.
+  ByteWriter<uint32_t>::WriteBigEndian(&header[4], 0x5678);  // Timestamp.
+  ByteWriter<uint32_t>::WriteBigEndian(&header[8], 0x4321);  // SSRC.
 
-  BuildAbsoluteSendTimeExtension(header + rtp_header_length, extension_id,
-                                 abs_send_time);
-  rtp_header_length += kAbsoluteSendTimeLength;
-  return rtp_header_length;
+  BuildOneByteExtension(header.begin() + webrtc::kRtpHeaderSize, extension_id,
+                        extension_value, value_length);
+  return header;
 }
 }  // namespace
 
@@ -178,32 +220,73 @@
 TEST(AudioReceiveStreamTest, ConstructDestruct) {
   ConfigHelper helper;
   internal::AudioReceiveStream recv_stream(
-      helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
+      helper.congestion_controller(), helper.config(), helper.audio_state());
+}
+
+MATCHER_P(VerifyHeaderExtension, expected_extension, "") {
+  return arg.extension.hasAbsoluteSendTime ==
+             expected_extension.hasAbsoluteSendTime &&
+         arg.extension.absoluteSendTime ==
+             expected_extension.absoluteSendTime &&
+         arg.extension.hasTransportSequenceNumber ==
+             expected_extension.hasTransportSequenceNumber &&
+         arg.extension.transportSequenceNumber ==
+             expected_extension.transportSequenceNumber;
 }
 
 TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweWithTimestamp) {
   ConfigHelper helper;
   helper.config().combined_audio_video_bwe = true;
+  helper.SetupMockForBweFeedback(false);
   internal::AudioReceiveStream recv_stream(
-      helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
-  uint8_t rtp_packet[30];
+      helper.congestion_controller(), helper.config(), helper.audio_state());
   const int kAbsSendTimeValue = 1234;
-  CreateRtpHeaderWithAbsSendTime(rtp_packet, kAbsSendTimeId, kAbsSendTimeValue);
+  std::vector<uint8_t> rtp_packet =
+      CreateRtpHeaderWithOneByteExtension(kAbsSendTimeId, kAbsSendTimeValue, 3);
   PacketTime packet_time(5678000, 0);
   const size_t kExpectedHeaderLength = 20;
+  RTPHeaderExtension expected_extension;
+  expected_extension.hasAbsoluteSendTime = true;
+  expected_extension.absoluteSendTime = kAbsSendTimeValue;
   EXPECT_CALL(*helper.remote_bitrate_estimator(),
               IncomingPacket(packet_time.timestamp / 1000,
-                             sizeof(rtp_packet) - kExpectedHeaderLength,
-                             testing::_, false))
+                             rtp_packet.size() - kExpectedHeaderLength,
+                             VerifyHeaderExtension(expected_extension), false))
       .Times(1);
   EXPECT_TRUE(
-      recv_stream.DeliverRtp(rtp_packet, sizeof(rtp_packet), packet_time));
+      recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time));
+}
+
+TEST(AudioReceiveStreamTest, AudioPacketUpdatesBweFeedback) {
+  ConfigHelper helper;
+  helper.config().combined_audio_video_bwe = true;
+  helper.config().rtp.transport_cc = true;
+  helper.config().rtp.extensions.push_back(RtpExtension(
+      RtpExtension::kTransportSequenceNumber, kTransportSequenceNumberId));
+  helper.SetupMockForBweFeedback(true);
+  internal::AudioReceiveStream recv_stream(
+      helper.congestion_controller(), helper.config(), helper.audio_state());
+  const int kTransportSequenceNumberValue = 1234;
+  std::vector<uint8_t> rtp_packet = CreateRtpHeaderWithOneByteExtension(
+      kTransportSequenceNumberId, kTransportSequenceNumberValue, 2);
+  PacketTime packet_time(5678000, 0);
+  const size_t kExpectedHeaderLength = 20;
+  RTPHeaderExtension expected_extension;
+  expected_extension.hasTransportSequenceNumber = true;
+  expected_extension.transportSequenceNumber = kTransportSequenceNumberValue;
+  EXPECT_CALL(*helper.remote_bitrate_estimator(),
+              IncomingPacket(packet_time.timestamp / 1000,
+                             rtp_packet.size() - kExpectedHeaderLength,
+                             VerifyHeaderExtension(expected_extension), false))
+      .Times(1);
+  EXPECT_TRUE(
+      recv_stream.DeliverRtp(&rtp_packet[0], rtp_packet.size(), packet_time));
 }
 
 TEST(AudioReceiveStreamTest, GetStats) {
   ConfigHelper helper;
   internal::AudioReceiveStream recv_stream(
-      helper.remote_bitrate_estimator(), helper.config(), helper.audio_state());
+      helper.congestion_controller(), helper.config(), helper.audio_state());
   helper.SetupMockForGetStats();
   AudioReceiveStream::Stats stats = recv_stream.GetStats();
   EXPECT_EQ(kRemoteSsrc, stats.remote_ssrc);
diff --git a/webrtc/audio/audio_send_stream_unittest.cc b/webrtc/audio/audio_send_stream_unittest.cc
index 08ff9a6..466c157 100644
--- a/webrtc/audio/audio_send_stream_unittest.cc
+++ b/webrtc/audio/audio_send_stream_unittest.cc
@@ -17,7 +17,7 @@
 #include "webrtc/audio/audio_state.h"
 #include "webrtc/audio/conversion.h"
 #include "webrtc/call/congestion_controller.h"
-#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
+#include "webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h"
 #include "webrtc/modules/pacing/paced_sender.h"
 #include "webrtc/test/mock_voe_channel_proxy.h"
 #include "webrtc/test/mock_voice_engine.h"
@@ -154,19 +154,12 @@
   }
 
  private:
-  class NullBitrateObserver : public BitrateObserver {
-   public:
-    virtual void OnNetworkChanged(uint32_t bitrate_bps,
-                                  uint8_t fraction_loss,
-                                  int64_t rtt_ms) {}
-  };
-
   testing::StrictMock<MockVoiceEngine> voice_engine_;
   rtc::scoped_refptr<AudioState> audio_state_;
   AudioSendStream::Config stream_config_;
   testing::StrictMock<MockVoEChannelProxy>* channel_proxy_ = nullptr;
   CallStats call_stats_;
-  NullBitrateObserver bitrate_observer_;
+  testing::NiceMock<MockBitrateObserver> bitrate_observer_;
   rtc::scoped_ptr<ProcessThread> process_thread_;
   CongestionController congestion_controller_;
 };
diff --git a/webrtc/audio_receive_stream.h b/webrtc/audio_receive_stream.h
index daf4598..8cab094 100644
--- a/webrtc/audio_receive_stream.h
+++ b/webrtc/audio_receive_stream.h
@@ -73,6 +73,12 @@
       // Sender SSRC used for sending RTCP (such as receiver reports).
       uint32_t local_ssrc = 0;
 
+      // Enable feedback for send side bandwidth estimation.
+      // See
+      // https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions
+      // for details.
+      bool transport_cc = false;
+
       // RTP header extensions used for the received stream.
       std::vector<RtpExtension> extensions;
     } rtp;
diff --git a/webrtc/call/call.cc b/webrtc/call/call.cc
index f861139..5c46a48 100644
--- a/webrtc/call/call.cc
+++ b/webrtc/call/call.cc
@@ -336,8 +336,7 @@
   TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream");
   RTC_DCHECK(configuration_thread_checker_.CalledOnValidThread());
   AudioReceiveStream* receive_stream = new AudioReceiveStream(
-      congestion_controller_->GetRemoteBitrateEstimator(false), config,
-      config_.audio_state);
+      congestion_controller_.get(), config, config_.audio_state);
   {
     WriteLockScoped write_lock(*receive_crit_);
     RTC_DCHECK(audio_receive_ssrcs_.find(config.rtp.remote_ssrc) ==
diff --git a/webrtc/call/congestion_controller.h b/webrtc/call/congestion_controller.h
index 98d8e43..b77c46f 100644
--- a/webrtc/call/congestion_controller.h
+++ b/webrtc/call/congestion_controller.h
@@ -40,28 +40,32 @@
  public:
   CongestionController(ProcessThread* process_thread, CallStats* call_stats,
                        BitrateObserver* bitrate_observer);
-  ~CongestionController();
-  void AddEncoder(ViEEncoder* encoder);
-  void RemoveEncoder(ViEEncoder* encoder);
-  void SetBweBitrates(int min_bitrate_bps,
-                      int start_bitrate_bps,
-                      int max_bitrate_bps);
+  virtual ~CongestionController();
+  virtual void AddEncoder(ViEEncoder* encoder);
+  virtual void RemoveEncoder(ViEEncoder* encoder);
+  virtual void SetBweBitrates(int min_bitrate_bps,
+                              int start_bitrate_bps,
+                              int max_bitrate_bps);
 
-  void SetChannelRembStatus(bool sender, bool receiver, RtpRtcp* rtp_module);
+  virtual void SetChannelRembStatus(bool sender,
+                                    bool receiver,
+                                    RtpRtcp* rtp_module);
 
-  void SignalNetworkState(NetworkState state);
+  virtual void SignalNetworkState(NetworkState state);
 
-  BitrateController* GetBitrateController() const;
-  RemoteBitrateEstimator* GetRemoteBitrateEstimator(bool send_side_bwe) const;
-  int64_t GetPacerQueuingDelayMs() const;
-  PacedSender* pacer() const { return pacer_.get(); }
-  PacketRouter* packet_router() const { return packet_router_.get(); }
-  TransportFeedbackObserver* GetTransportFeedbackObserver();
+  virtual BitrateController* GetBitrateController() const;
+  virtual RemoteBitrateEstimator* GetRemoteBitrateEstimator(
+      bool send_side_bwe) const;
+  virtual int64_t GetPacerQueuingDelayMs() const;
+  virtual PacedSender* pacer() const { return pacer_.get(); }
+  virtual PacketRouter* packet_router() const { return packet_router_.get(); }
+  virtual TransportFeedbackObserver* GetTransportFeedbackObserver();
 
-  void UpdatePacerBitrate(int bitrate_kbps, int max_bitrate_kbps,
-                          int min_bitrate_kbps);
+  virtual void UpdatePacerBitrate(int bitrate_kbps,
+                                  int max_bitrate_kbps,
+                                  int min_bitrate_kbps);
 
-  void OnSentPacket(const rtc::SentPacket& sent_packet);
+  virtual void OnSentPacket(const rtc::SentPacket& sent_packet);
 
  private:
   rtc::scoped_ptr<VieRemb> remb_;
@@ -82,6 +86,8 @@
   rtc::scoped_ptr<BitrateController> bitrate_controller_;
   rtc::scoped_ptr<TransportFeedbackAdapter> transport_feedback_adapter_;
   int min_bitrate_bps_;
+
+  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(CongestionController);
 };
 
 }  // namespace webrtc
diff --git a/webrtc/call/mock/mock_congestion_controller.h b/webrtc/call/mock/mock_congestion_controller.h
new file mode 100644
index 0000000..54014da
--- /dev/null
+++ b/webrtc/call/mock/mock_congestion_controller.h
@@ -0,0 +1,52 @@
+/*
+ *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_CALL_MOCK_MOCK_CONGESTION_CONTROLLER_H_
+#define WEBRTC_CALL_MOCK_MOCK_CONGESTION_CONTROLLER_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webrtc/call/congestion_controller.h"
+
+namespace webrtc {
+namespace test {
+
+class MockCongestionController : public CongestionController {
+ public:
+  MockCongestionController(ProcessThread* process_thread,
+                           CallStats* call_stats,
+                           BitrateObserver* bitrate_observer)
+      : CongestionController(process_thread, call_stats, bitrate_observer) {}
+  MOCK_METHOD1(AddEncoder, void(ViEEncoder* encoder));
+  MOCK_METHOD1(RemoveEncoder, void(ViEEncoder* encoder));
+  MOCK_METHOD3(SetBweBitrates,
+               void(int min_bitrate_bps,
+                    int start_bitrate_bps,
+                    int max_bitrate_bps));
+  MOCK_METHOD3(SetChannelRembStatus,
+               void(bool sender, bool receiver, RtpRtcp* rtp_module));
+  MOCK_METHOD1(SignalNetworkState, void(NetworkState state));
+  MOCK_CONST_METHOD0(GetBitrateController, BitrateController*());
+  MOCK_CONST_METHOD1(GetRemoteBitrateEstimator,
+                     RemoteBitrateEstimator*(bool send_side_bwe));
+  MOCK_CONST_METHOD0(GetPacerQueuingDelayMs, int64_t());
+  MOCK_CONST_METHOD0(pacer, PacedSender*());
+  MOCK_CONST_METHOD0(packet_router, PacketRouter*());
+  MOCK_METHOD0(GetTransportFeedbackObserver, TransportFeedbackObserver*());
+  MOCK_METHOD3(UpdatePacerBitrate,
+               void(int bitrate_kbps,
+                    int max_bitrate_kbps,
+                    int min_bitrate_kbps));
+  MOCK_METHOD1(OnSentPacket, void(const rtc::SentPacket& sent_packet));
+
+  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MockCongestionController);
+};
+}  // namespace test
+}  // namespace webrtc
+#endif  // WEBRTC_CALL_MOCK_MOCK_CONGESTION_CONTROLLER_H_
diff --git a/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h b/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
new file mode 100644
index 0000000..7a7d2e4
--- /dev/null
+++ b/webrtc/modules/bitrate_controller/include/mock/mock_bitrate_controller.h
@@ -0,0 +1,30 @@
+/*
+ *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_MOCK_MOCK_BITRATE_CONTROLLER_H_
+#define WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_MOCK_MOCK_BITRATE_CONTROLLER_H_
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
+
+namespace webrtc {
+namespace test {
+
+class MockBitrateObserver : public BitrateObserver {
+ public:
+  MOCK_METHOD3(OnNetworkChanged,
+               void(uint32_t bitrate_bps,
+                    uint8_t fraction_loss,
+                    int64_t rtt_ms));
+};
+}  // namespace test
+}  // namespace webrtc
+
+#endif  // WEBRTC_MODULES_BITRATE_CONTROLLER_INCLUDE_MOCK_MOCK_BITRATE_CONTROLLER_H_
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
index 43433b9..0f0ad83 100644
--- a/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
+++ b/webrtc/modules/rtp_rtcp/source/rtp_utility.cc
@@ -314,8 +314,8 @@
 
     // Note that 'len' is the header extension element length, which is the
     // number of bytes - 1.
-    const uint8_t id = (*ptr & 0xf0) >> 4;
-    const uint8_t len = (*ptr & 0x0f);
+    const int id = (*ptr & 0xf0) >> 4;
+    const int len = (*ptr & 0x0f);
     ptr++;
 
     if (id == 15) {
@@ -327,8 +327,7 @@
     RTPExtensionType type;
     if (ptrExtensionMap->GetType(id, &type) != 0) {
       // If we encounter an unknown extension, just skip over it.
-      LOG(LS_WARNING) << "Failed to find extension id: "
-                      << static_cast<int>(id);
+      LOG(LS_WARNING) << "Failed to find extension id: " << id;
     } else {
       switch (type) {
         case kRtpExtensionTransmissionTimeOffset: {
@@ -397,8 +396,8 @@
         }
         case kRtpExtensionTransportSequenceNumber: {
           if (len != 1) {
-            LOG(LS_WARNING)
-                << "Incorrect peer connection sequence number len: " << len;
+            LOG(LS_WARNING) << "Incorrect transport sequence number len: "
+                            << len;
             return;
           }
           //   0                   1                   2
diff --git a/webrtc/voice_engine/channel.cc b/webrtc/voice_engine/channel.cc
index 48111db..64b40a8 100644
--- a/webrtc/voice_engine/channel.cc
+++ b/webrtc/voice_engine/channel.cc
@@ -2927,14 +2927,19 @@
     RtpPacketSender* rtp_packet_sender,
     TransportFeedbackObserver* transport_feedback_observer,
     PacketRouter* packet_router) {
-  RTC_DCHECK(feedback_observer_proxy_.get());
-  RTC_DCHECK(seq_num_allocator_proxy_.get());
-  RTC_DCHECK(rtp_packet_sender_proxy_.get());
   RTC_DCHECK(packet_router != nullptr || packet_router_ != nullptr);
-  feedback_observer_proxy_->SetTransportFeedbackObserver(
-      transport_feedback_observer);
-  seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
-  rtp_packet_sender_proxy_->SetPacketSender(rtp_packet_sender);
+  if (transport_feedback_observer) {
+    RTC_DCHECK(feedback_observer_proxy_.get());
+    feedback_observer_proxy_->SetTransportFeedbackObserver(
+        transport_feedback_observer);
+  }
+  if (rtp_packet_sender) {
+    RTC_DCHECK(rtp_packet_sender_proxy_.get());
+    rtp_packet_sender_proxy_->SetPacketSender(rtp_packet_sender);
+  }
+  if (seq_num_allocator_proxy_.get()) {
+    seq_num_allocator_proxy_->SetSequenceNumberAllocator(packet_router);
+  }
   _rtpRtcpModule->SetStorePacketsStatus(rtp_packet_sender != nullptr, 600);
   if (packet_router != nullptr) {
     packet_router->AddRtpModule(_rtpRtcpModule.get());