Move Ownership of RtpModules to VideoSendStream from VieChannel and remove use of vie_channel and vie_receiver from video_send_stream.

The purpose of this refactoring is a first step of separating the encoder parts from the RTP transport.

BUG=webrtc:5687
R=mflodman@webrtc.org, pbos@webrtc.org, stefan@webrtc.org

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

Cr-Original-Commit-Position: refs/heads/master@{#12377}
Cr-Mirrored-From: https://chromium.googlesource.com/external/webrtc
Cr-Mirrored-Commit: 83d09106943b3b70d9aaa92bc674fae473443f89
diff --git a/modules/rtp_rtcp/include/rtp_rtcp.h b/modules/rtp_rtcp/include/rtp_rtcp.h
index d01465b..50fb35e 100644
--- a/modules/rtp_rtcp/include/rtp_rtcp.h
+++ b/modules/rtp_rtcp/include/rtp_rtcp.h
@@ -210,10 +210,10 @@
     */
     virtual void SetSequenceNumber(uint16_t seq) = 0;
 
-    // Returns true if the ssrc matched this module, false otherwise.
-    virtual bool SetRtpStateForSsrc(uint32_t ssrc,
-                                    const RtpState& rtp_state) = 0;
-    virtual bool GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) = 0;
+    virtual void SetRtpState(const RtpState& rtp_state) = 0;
+    virtual void SetRtxState(const RtpState& rtp_state) = 0;
+    virtual RtpState GetRtpState() const = 0;
+    virtual RtpState GetRtxState() const = 0;
 
     /*
     *   Get SSRC
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index 9991aa2..4cbb042 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -85,12 +85,12 @@
   MOCK_CONST_METHOD0(StartTimestamp,
       uint32_t());
   MOCK_METHOD1(SetStartTimestamp, void(const uint32_t timestamp));
-  MOCK_CONST_METHOD0(SequenceNumber,
-      uint16_t());
+  MOCK_CONST_METHOD0(SequenceNumber, uint16_t());
   MOCK_METHOD1(SetSequenceNumber, void(const uint16_t seq));
-  MOCK_METHOD2(SetRtpStateForSsrc,
-               bool(uint32_t ssrc, const RtpState& rtp_state));
-  MOCK_METHOD2(GetRtpStateForSsrc, bool(uint32_t ssrc, RtpState* rtp_state));
+  MOCK_METHOD1(SetRtpState, void(const RtpState& rtp_state));
+  MOCK_METHOD1(SetRtxState, void(const RtpState& rtp_state));
+  MOCK_CONST_METHOD0(GetRtpState, RtpState());
+  MOCK_CONST_METHOD0(GetRtxState, RtpState());
   MOCK_CONST_METHOD0(SSRC,
       uint32_t());
   MOCK_METHOD1(SetSSRC,
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 95bfeee..7579a36 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -871,11 +871,13 @@
         random_.Rand(minIntervalMs * 1 / 2, minIntervalMs * 3 / 2);
     next_time_to_send_rtcp_ = clock_->TimeInMilliseconds() + timeToNext;
 
-    StatisticianMap statisticians =
-        receive_statistics_->GetActiveStatisticians();
-    RTC_DCHECK(report_blocks_.empty());
-    for (auto& it : statisticians) {
-      AddReportBlock(feedback_state, it.first, it.second);
+    if (receive_statistics_) {
+      StatisticianMap statisticians =
+          receive_statistics_->GetActiveStatisticians();
+      RTC_DCHECK(report_blocks_.empty());
+      for (auto& it : statisticians) {
+        AddReportBlock(feedback_state, it.first, it.second);
+      }
     }
   }
 }
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
index 64f64d8..ec767d8 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc
@@ -300,30 +300,21 @@
   rtp_sender_.SetSequenceNumber(seq_num);
 }
 
-bool ModuleRtpRtcpImpl::SetRtpStateForSsrc(uint32_t ssrc,
-                                           const RtpState& rtp_state) {
-  if (rtp_sender_.SSRC() == ssrc) {
-    SetStartTimestamp(rtp_state.start_timestamp);
-    rtp_sender_.SetRtpState(rtp_state);
-    return true;
-  }
-  if (rtp_sender_.RtxSsrc() == ssrc) {
-    rtp_sender_.SetRtxRtpState(rtp_state);
-    return true;
-  }
-  return false;
+void ModuleRtpRtcpImpl::SetRtpState(const RtpState& rtp_state) {
+  SetStartTimestamp(rtp_state.start_timestamp);
+  rtp_sender_.SetRtpState(rtp_state);
 }
 
-bool ModuleRtpRtcpImpl::GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) {
-  if (rtp_sender_.SSRC() == ssrc) {
-    *rtp_state = rtp_sender_.GetRtpState();
-    return true;
-  }
-  if (rtp_sender_.RtxSsrc() == ssrc) {
-    *rtp_state = rtp_sender_.GetRtxRtpState();
-    return true;
-  }
-  return false;
+void ModuleRtpRtcpImpl::SetRtxState(const RtpState& rtp_state) {
+  rtp_sender_.SetRtxRtpState(rtp_state);
+}
+
+RtpState ModuleRtpRtcpImpl::GetRtpState() const {
+  return rtp_sender_.GetRtpState();
+}
+
+RtpState ModuleRtpRtcpImpl::GetRtxState() const {
+  return rtp_sender_.GetRtxRtpState();
 }
 
 uint32_t ModuleRtpRtcpImpl::SSRC() const {
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index ec8e84a..997a19b 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -75,8 +75,10 @@
   // Set SequenceNumber, default is a random number.
   void SetSequenceNumber(uint16_t seq) override;
 
-  bool SetRtpStateForSsrc(uint32_t ssrc, const RtpState& rtp_state) override;
-  bool GetRtpStateForSsrc(uint32_t ssrc, RtpState* rtp_state) override;
+  void SetRtpState(const RtpState& rtp_state) override;
+  void SetRtxState(const RtpState& rtp_state) override;
+  RtpState GetRtpState() const override;
+  RtpState GetRtxState() const override;
 
   uint32_t SSRC() const override;
 
diff --git a/video/encoder_state_feedback.cc b/video/encoder_state_feedback.cc
index 0240e48..52f5111 100644
--- a/video/encoder_state_feedback.cc
+++ b/video/encoder_state_feedback.cc
@@ -25,13 +25,6 @@
   vie_encoder_ = encoder;
 }
 
-void EncoderStateFeedback::TearDown() {
-  rtc::CritScope lock(&crit_);
-  RTC_DCHECK(vie_encoder_);
-  ssrcs_.clear();
-  vie_encoder_ = nullptr;
-}
-
 bool EncoderStateFeedback::HasSsrc(uint32_t ssrc) {
   for (uint32_t registered_ssrc : ssrcs_) {
     if (registered_ssrc == ssrc)
diff --git a/video/encoder_state_feedback.h b/video/encoder_state_feedback.h
index 6326bed..57595a0 100644
--- a/video/encoder_state_feedback.h
+++ b/video/encoder_state_feedback.h
@@ -31,12 +31,6 @@
   // Adds an encoder to receive feedback for a set of SSRCs.
   void Init(const std::vector<uint32_t>& ssrc, ViEEncoder* encoder);
 
-  // Removes the registered encoder. Necessary since RTP modules outlive
-  // ViEEncoder.
-  // TODO(pbos): Make sure RTP modules are not running when tearing down
-  // ViEEncoder, then remove this function.
-  void TearDown();
-
   void OnReceivedIntraFrameRequest(uint32_t ssrc) override;
   void OnReceivedSLI(uint32_t ssrc, uint8_t picture_id) override;
   void OnReceivedRPSI(uint32_t ssrc, uint64_t picture_id) override;
diff --git a/video/payload_router.cc b/video/payload_router.cc
index 968d82d..d466e41 100644
--- a/video/payload_router.cc
+++ b/video/payload_router.cc
@@ -16,8 +16,10 @@
 
 namespace webrtc {
 
-PayloadRouter::PayloadRouter()
-    : active_(false), num_sending_modules_(0) {}
+PayloadRouter::PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules)
+    : active_(false), num_sending_modules_(1), rtp_modules_(rtp_modules) {
+  UpdateModuleSendingState();
+}
 
 PayloadRouter::~PayloadRouter() {}
 
@@ -26,12 +28,6 @@
   return IP_PACKET_SIZE - kIpUdpSrtpLength;
 }
 
-void PayloadRouter::Init(
-    const std::vector<RtpRtcp*>& rtp_modules) {
-  RTC_DCHECK(rtp_modules_.empty());
-  rtp_modules_ = rtp_modules;
-}
-
 void PayloadRouter::set_active(bool active) {
   rtc::CritScope lock(&crit_);
   if (active_ == active)
diff --git a/video/payload_router.h b/video/payload_router.h
index 9eaf716..81ec0dd 100644
--- a/video/payload_router.h
+++ b/video/payload_router.h
@@ -29,14 +29,11 @@
 // on the simulcast layer in RTPVideoHeader.
 class PayloadRouter {
  public:
-  PayloadRouter();
+  // Rtp modules are assumed to be sorted in simulcast index order.
+  explicit PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules);
   ~PayloadRouter();
 
   static size_t DefaultMaxPayloadLength();
-
-  // Rtp modules are assumed to be sorted in simulcast index order.
-  void Init(const std::vector<RtpRtcp*>& rtp_modules);
-
   void SetSendingRtpModules(size_t num_sending_modules);
 
   // PayloadRouter will only route packets if being active, all packets will be
@@ -66,13 +63,13 @@
  private:
   void UpdateModuleSendingState() EXCLUSIVE_LOCKS_REQUIRED(crit_);
 
-  // TODO(pbos): Set once and for all on construction and make const.
-  std::vector<RtpRtcp*> rtp_modules_;
-
   rtc::CriticalSection crit_;
   bool active_ GUARDED_BY(crit_);
   size_t num_sending_modules_ GUARDED_BY(crit_);
 
+  // Rtp modules are assumed to be sorted in simulcast index order. Not owned.
+  const std::vector<RtpRtcp*> rtp_modules_;
+
   RTC_DISALLOW_COPY_AND_ASSIGN(PayloadRouter);
 };
 
diff --git a/video/payload_router_unittest.cc b/video/payload_router_unittest.cc
index 5b3dc93..c5d3f38 100644
--- a/video/payload_router_unittest.cc
+++ b/video/payload_router_unittest.cc
@@ -23,20 +23,12 @@
 
 namespace webrtc {
 
-class PayloadRouterTest : public ::testing::Test {
- protected:
-  virtual void SetUp() {
-    payload_router_.reset(new PayloadRouter());
-  }
-  std::unique_ptr<PayloadRouter> payload_router_;
-};
-
-TEST_F(PayloadRouterTest, SendOnOneModule) {
+TEST(PayloadRouterTest, SendOnOneModule) {
   MockRtpRtcp rtp;
   std::vector<RtpRtcp*> modules(1, &rtp);
 
-  payload_router_->Init(modules);
-  payload_router_->SetSendingRtpModules(modules.size());
+  PayloadRouter payload_router(modules);
+  payload_router.SetSendingRtpModules(modules.size());
 
   uint8_t payload = 'a';
   FrameType frame_type = kVideoFrameKey;
@@ -45,47 +37,47 @@
   EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
                                     nullptr, nullptr))
       .Times(0);
-  EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
-                                             &payload, 1, nullptr, nullptr));
+  EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+                                           &payload, 1, nullptr, nullptr));
 
-  payload_router_->set_active(true);
+  payload_router.set_active(true);
   EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
                                     nullptr, nullptr))
       .Times(1);
-  EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
-                                            &payload, 1, nullptr, nullptr));
+  EXPECT_TRUE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+                                          &payload, 1, nullptr, nullptr));
 
-  payload_router_->set_active(false);
+  payload_router.set_active(false);
   EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
                                     nullptr, nullptr))
       .Times(0);
-  EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
-                                             &payload, 1, nullptr, nullptr));
+  EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+                                           &payload, 1, nullptr, nullptr));
 
-  payload_router_->set_active(true);
+  payload_router.set_active(true);
   EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
                                     nullptr, nullptr))
       .Times(1);
-  EXPECT_TRUE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
-                                            &payload, 1, nullptr, nullptr));
+  EXPECT_TRUE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+                                          &payload, 1, nullptr, nullptr));
 
-  payload_router_->SetSendingRtpModules(0);
+  payload_router.SetSendingRtpModules(0);
   EXPECT_CALL(rtp, SendOutgoingData(frame_type, payload_type, 0, 0, _, 1,
                                     nullptr, nullptr))
       .Times(0);
-  EXPECT_FALSE(payload_router_->RoutePayload(frame_type, payload_type, 0, 0,
-                                             &payload, 1, nullptr, nullptr));
+  EXPECT_FALSE(payload_router.RoutePayload(frame_type, payload_type, 0, 0,
+                                           &payload, 1, nullptr, nullptr));
 }
 
-TEST_F(PayloadRouterTest, SendSimulcast) {
+TEST(PayloadRouterTest, SendSimulcast) {
   MockRtpRtcp rtp_1;
   MockRtpRtcp rtp_2;
   std::vector<RtpRtcp*> modules;
   modules.push_back(&rtp_1);
   modules.push_back(&rtp_2);
 
-  payload_router_->Init(modules);
-  payload_router_->SetSendingRtpModules(modules.size());
+  PayloadRouter payload_router(modules);
+  payload_router.SetSendingRtpModules(modules.size());
 
   uint8_t payload_1 = 'a';
   FrameType frame_type_1 = kVideoFrameKey;
@@ -93,14 +85,14 @@
   RTPVideoHeader rtp_hdr_1;
   rtp_hdr_1.simulcastIdx = 0;
 
-  payload_router_->set_active(true);
+  payload_router.set_active(true);
   EXPECT_CALL(rtp_1, SendOutgoingData(frame_type_1, payload_type_1, 0, 0, _, 1,
                                       nullptr, &rtp_hdr_1))
       .Times(1);
   EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
-  EXPECT_TRUE(payload_router_->RoutePayload(
-      frame_type_1, payload_type_1, 0, 0, &payload_1, 1, nullptr, &rtp_hdr_1));
+  EXPECT_TRUE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
+                                          &payload_1, 1, nullptr, &rtp_hdr_1));
 
   uint8_t payload_2 = 'b';
   FrameType frame_type_2 = kVideoFrameDelta;
@@ -112,46 +104,45 @@
       .Times(1);
   EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
-  EXPECT_TRUE(payload_router_->RoutePayload(
-      frame_type_2, payload_type_2, 0, 0, &payload_2, 1, nullptr, &rtp_hdr_2));
+  EXPECT_TRUE(payload_router.RoutePayload(frame_type_2, payload_type_2, 0, 0,
+                                          &payload_2, 1, nullptr, &rtp_hdr_2));
 
   // Inactive.
-  payload_router_->set_active(false);
+  payload_router.set_active(false);
   EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
   EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
-  EXPECT_FALSE(payload_router_->RoutePayload(
-      frame_type_1, payload_type_1, 0, 0, &payload_1, 1, nullptr, &rtp_hdr_1));
-  EXPECT_FALSE(payload_router_->RoutePayload(
-      frame_type_2, payload_type_2, 0, 0, &payload_2, 1, nullptr, &rtp_hdr_2));
+  EXPECT_FALSE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
+                                           &payload_1, 1, nullptr, &rtp_hdr_1));
+  EXPECT_FALSE(payload_router.RoutePayload(frame_type_2, payload_type_2, 0, 0,
+                                           &payload_2, 1, nullptr, &rtp_hdr_2));
 
   // Invalid simulcast index.
-  payload_router_->SetSendingRtpModules(1);
-  payload_router_->set_active(true);
+  payload_router.SetSendingRtpModules(1);
+  payload_router.set_active(true);
   EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
   EXPECT_CALL(rtp_2, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
   rtp_hdr_1.simulcastIdx = 1;
-  EXPECT_FALSE(payload_router_->RoutePayload(
-      frame_type_1, payload_type_1, 0, 0, &payload_1, 1, nullptr, &rtp_hdr_1));
+  EXPECT_FALSE(payload_router.RoutePayload(frame_type_1, payload_type_1, 0, 0,
+                                           &payload_1, 1, nullptr, &rtp_hdr_1));
 }
 
-TEST_F(PayloadRouterTest, MaxPayloadLength) {
+TEST(PayloadRouterTest, MaxPayloadLength) {
   // Without any limitations from the modules, verify we get the max payload
   // length for IP/UDP/SRTP with a MTU of 150 bytes.
   const size_t kDefaultMaxLength = 1500 - 20 - 8 - 12 - 4;
-  EXPECT_EQ(kDefaultMaxLength, payload_router_->DefaultMaxPayloadLength());
-  EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());
-
   MockRtpRtcp rtp_1;
   MockRtpRtcp rtp_2;
   std::vector<RtpRtcp*> modules;
   modules.push_back(&rtp_1);
   modules.push_back(&rtp_2);
-  payload_router_->Init(modules);
-  payload_router_->SetSendingRtpModules(modules.size());
+  PayloadRouter payload_router(modules);
+
+  EXPECT_EQ(kDefaultMaxLength, PayloadRouter::DefaultMaxPayloadLength());
+  payload_router.SetSendingRtpModules(modules.size());
 
   // Modules return a higher length than the default value.
   EXPECT_CALL(rtp_1, MaxDataPayloadLength())
@@ -160,7 +151,7 @@
   EXPECT_CALL(rtp_2, MaxDataPayloadLength())
       .Times(1)
       .WillOnce(Return(kDefaultMaxLength + 10));
-  EXPECT_EQ(kDefaultMaxLength, payload_router_->MaxPayloadLength());
+  EXPECT_EQ(kDefaultMaxLength, payload_router.MaxPayloadLength());
 
   // The modules return a value lower than default.
   const size_t kTestMinPayloadLength = 1001;
@@ -170,17 +161,17 @@
   EXPECT_CALL(rtp_2, MaxDataPayloadLength())
       .Times(1)
       .WillOnce(Return(kTestMinPayloadLength));
-  EXPECT_EQ(kTestMinPayloadLength, payload_router_->MaxPayloadLength());
+  EXPECT_EQ(kTestMinPayloadLength, payload_router.MaxPayloadLength());
 }
 
-TEST_F(PayloadRouterTest, SetTargetSendBitrates) {
+TEST(PayloadRouterTest, SetTargetSendBitrates) {
   MockRtpRtcp rtp_1;
   MockRtpRtcp rtp_2;
   std::vector<RtpRtcp*> modules;
   modules.push_back(&rtp_1);
   modules.push_back(&rtp_2);
-  payload_router_->Init(modules);
-  payload_router_->SetSendingRtpModules(modules.size());
+  PayloadRouter payload_router(modules);
+  payload_router.SetSendingRtpModules(modules.size());
 
   const uint32_t bitrate_1 = 10000;
   const uint32_t bitrate_2 = 76543;
@@ -190,13 +181,13 @@
       .Times(1);
   EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
       .Times(1);
-  payload_router_->SetTargetSendBitrates(bitrates);
+  payload_router.SetTargetSendBitrates(bitrates);
 
   bitrates.resize(1);
   EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
       .Times(1);
   EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
       .Times(0);
-  payload_router_->SetTargetSendBitrates(bitrates);
+  payload_router.SetTargetSendBitrates(bitrates);
 }
 }  // namespace webrtc
diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc
index a34544d..131469f 100644
--- a/video/video_receive_stream.cc
+++ b/video/video_receive_stream.cc
@@ -172,21 +172,15 @@
       stats_proxy_(config_, clock_),
       vie_channel_(&transport_adapter_,
                    process_thread,
-                   nullptr,
                    vcm_.get(),
-                   nullptr,
-                   nullptr,
-                   nullptr,
                    congestion_controller_->GetRemoteBitrateEstimator(
                        UseSendSideBwe(config_)),
                    call_stats_->rtcp_rtt_stats(),
                    congestion_controller_->pacer(),
-                   congestion_controller_->packet_router(),
-                   1,
-                   false),
+                   congestion_controller_->packet_router()),
       vie_receiver_(vie_channel_.vie_receiver()),
       vie_sync_(vcm_.get()),
-      rtp_rtcp_(vie_channel_.rtp_rtcp().front()) {
+      rtp_rtcp_(vie_channel_.rtp_rtcp()) {
   LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
 
   RTC_DCHECK(process_thread_);
diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc
index 1c6638e..baec5a2 100644
--- a/video/video_send_stream.cc
+++ b/video/video_send_stream.cc
@@ -34,6 +34,52 @@
 class RtcpIntraFrameObserver;
 class TransportFeedbackObserver;
 
+static const int kMinSendSidePacketHistorySize = 600;
+
+namespace {
+
+std::vector<RtpRtcp*> CreateRtpRtcpModules(
+    Transport* outgoing_transport,
+    RtcpIntraFrameObserver* intra_frame_callback,
+    RtcpBandwidthObserver* bandwidth_callback,
+    TransportFeedbackObserver* transport_feedback_callback,
+    RtcpRttStats* rtt_stats,
+    RtpPacketSender* paced_sender,
+    TransportSequenceNumberAllocator* transport_sequence_number_allocator,
+    SendStatisticsProxy* stats_proxy,
+    size_t num_modules) {
+  RTC_DCHECK_GT(num_modules, 0u);
+  RtpRtcp::Configuration configuration;
+  ReceiveStatistics* null_receive_statistics = configuration.receive_statistics;
+  configuration.audio = false;
+  configuration.receiver_only = false;
+  configuration.receive_statistics = null_receive_statistics;
+  configuration.outgoing_transport = outgoing_transport;
+  configuration.intra_frame_callback = intra_frame_callback;
+  configuration.rtt_stats = rtt_stats;
+  configuration.rtcp_packet_type_counter_observer = stats_proxy;
+  configuration.paced_sender = paced_sender;
+  configuration.transport_sequence_number_allocator =
+      transport_sequence_number_allocator;
+  configuration.send_bitrate_observer = stats_proxy;
+  configuration.send_frame_count_observer = stats_proxy;
+  configuration.send_side_delay_observer = stats_proxy;
+  configuration.bandwidth_callback = bandwidth_callback;
+  configuration.transport_feedback_callback = transport_feedback_callback;
+
+  std::vector<RtpRtcp*> modules;
+  for (size_t i = 0; i < num_modules; ++i) {
+    RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
+    rtp_rtcp->SetSendingStatus(false);
+    rtp_rtcp->SetSendingMediaStatus(false);
+    rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
+    modules.push_back(rtp_rtcp);
+  }
+  return modules;
+}
+
+}  // namespace
+
 std::string
 VideoSendStream::Config::EncoderSettings::ToString() const {
   std::stringstream ss;
@@ -183,21 +229,6 @@
           this,
           config.post_encode_callback,
           &stats_proxy_),
-      vie_channel_(config.send_transport,
-                   module_process_thread_,
-                   &payload_router_,
-                   nullptr,
-                   &encoder_feedback_,
-                   congestion_controller_->GetBitrateController()
-                       ->CreateRtcpBandwidthObserver(),
-                   congestion_controller_->GetTransportFeedbackObserver(),
-                   nullptr,
-                   call_stats_->rtcp_rtt_stats(),
-                   congestion_controller_->pacer(),
-                   congestion_controller_->packet_router(),
-                   config_.rtp.ssrcs.size(),
-                   true),
-      vie_receiver_(vie_channel_.vie_receiver()),
       vie_encoder_(num_cpu_cores,
                    config_.rtp.ssrcs,
                    module_process_thread_,
@@ -207,7 +238,19 @@
                    congestion_controller_->pacer(),
                    &payload_router_),
       vcm_(vie_encoder_.vcm()),
-      rtp_rtcp_modules_(vie_channel_.rtp_rtcp()),
+      bandwidth_observer_(congestion_controller_->GetBitrateController()
+                              ->CreateRtcpBandwidthObserver()),
+      rtp_rtcp_modules_(CreateRtpRtcpModules(
+          config.send_transport,
+          &encoder_feedback_,
+          bandwidth_observer_.get(),
+          congestion_controller_->GetTransportFeedbackObserver(),
+          call_stats_->rtcp_rtt_stats(),
+          congestion_controller_->pacer(),
+          congestion_controller_->packet_router(),
+          &stats_proxy_,
+          config_.rtp.ssrcs.size())),
+      payload_router_(rtp_rtcp_modules_),
       input_(&encoder_wakeup_event_,
              config_.local_renderer,
              &stats_proxy_,
@@ -220,14 +263,16 @@
   RTC_DCHECK(congestion_controller_);
   RTC_DCHECK(remb_);
 
-  payload_router_.Init(rtp_rtcp_modules_);
   RTC_CHECK(vie_encoder_.Init());
   encoder_feedback_.Init(config_.rtp.ssrcs, &vie_encoder_);
-  RTC_CHECK(vie_channel_.Init() == 0);
 
-  vcm_->RegisterProtectionCallback(vie_channel_.vcm_protection_callback());
+  // RTP/RTCP initialization.
+  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+    module_process_thread_->RegisterModule(rtp_rtcp);
+    congestion_controller_->packet_router()->AddRtpModule(rtp_rtcp);
+  }
 
-  call_stats_->RegisterStatsObserver(vie_channel_.GetStatsObserver());
+  vcm_->RegisterProtectionCallback(this);
 
   for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
     const std::string& extension = config_.rtp.extensions[i].name;
@@ -245,28 +290,7 @@
   remb_->AddRembSender(rtp_rtcp_modules_[0]);
   rtp_rtcp_modules_[0]->SetREMBStatus(true);
 
-  // Enable NACK, FEC or both.
-  const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
-  bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
-  // Payload types without picture ID cannot determine that a stream is complete
-  // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
-  // a waste of bandwidth since FEC packets still have to be transmitted. Note
-  // that this is not the case with FLEXFEC.
-  if (enable_protection_nack &&
-      !PayloadTypeSupportsSkippingFecPackets(
-          config_.encoder_settings.payload_name)) {
-    LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
-                       "NACK+FEC is a waste of bandwidth since FEC packets "
-                       "also have to be retransmitted. Disabling FEC.";
-    enable_protection_fec = false;
-  }
-  // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
-  vie_channel_.SetProtectionMode(enable_protection_nack, enable_protection_fec,
-                                 config_.rtp.fec.red_payload_type,
-                                 config_.rtp.fec.ulpfec_payload_type);
-  vie_encoder_.SetProtectionMethod(enable_protection_nack,
-                                   enable_protection_fec);
-
+  ConfigureProtection();
   ConfigureSsrcs();
 
   // TODO(pbos): Should we set CNAME on all RTP modules?
@@ -295,8 +319,6 @@
 
   ReconfigureVideoEncoder(encoder_config);
 
-  vie_channel_.RegisterSendSideDelayObserver(&stats_proxy_);
-
   if (config_.post_encode_callback)
     vie_encoder_.RegisterPostEncodeImageCallback(&encoded_frame_proxy_);
 
@@ -305,10 +327,6 @@
     bitrate_allocator_->EnforceMinBitrate(false);
   }
 
-  vie_channel_.RegisterRtcpPacketTypeCounterObserver(&stats_proxy_);
-  vie_channel_.RegisterSendBitrateObserver(&stats_proxy_);
-  vie_channel_.RegisterSendFrameCountObserver(&stats_proxy_);
-
   module_process_thread_->RegisterModule(&overuse_detector_);
 
   encoder_thread_.Start();
@@ -330,22 +348,17 @@
   bitrate_allocator_->RemoveObserver(this);
 
   module_process_thread_->DeRegisterModule(&overuse_detector_);
-  vie_channel_.RegisterSendFrameCountObserver(nullptr);
-  vie_channel_.RegisterSendBitrateObserver(nullptr);
-  vie_channel_.RegisterRtcpPacketTypeCounterObserver(nullptr);
 
   vie_encoder_.DeRegisterExternalEncoder(config_.encoder_settings.payload_type);
 
-  call_stats_->DeregisterStatsObserver(vie_channel_.GetStatsObserver());
   rtp_rtcp_modules_[0]->SetREMBStatus(false);
   remb_->RemoveRembSender(rtp_rtcp_modules_[0]);
 
-  // ViEChannel outlives ViEEncoder so remove encoder from feedback before
-  // destruction.
-  encoder_feedback_.TearDown();
-
-  congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream(
-      vie_receiver_->GetRemoteSsrc());
+  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+    congestion_controller_->packet_router()->RemoveRtpModule(rtp_rtcp);
+    module_process_thread_->DeRegisterModule(rtp_rtcp);
+    delete rtp_rtcp;
+  }
 }
 
 VideoCaptureInput* VideoSendStream::Input() {
@@ -361,7 +374,6 @@
   // Was not already started, trigger a keyframe.
   vie_encoder_.SendKeyFrame();
   vie_encoder_.Restart();
-  vie_receiver_->StartReceive();
 }
 
 void VideoSendStream::Stop() {
@@ -370,7 +382,6 @@
   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
   // TODO(pbos): Make sure the encoder stops here.
   payload_router_.set_active(false);
-  vie_receiver_->StopReceive();
 }
 
 bool VideoSendStream::EncoderThreadFunction(void* obj) {
@@ -535,7 +546,9 @@
 }
 
 bool VideoSendStream::DeliverRtcp(const uint8_t* packet, size_t length) {
-  return vie_receiver_->DeliverRtcp(packet, length);
+  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
+    rtp_rtcp->IncomingRtcpPacket(packet, length);
+  return true;
 }
 
 VideoSendStream::Stats VideoSendStream::GetStats() {
@@ -552,6 +565,60 @@
     config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
 }
 
+void VideoSendStream::ConfigureProtection() {
+  // Enable NACK, FEC or both.
+  const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
+  bool enable_protection_fec = config_.rtp.fec.red_payload_type != -1;
+  // Payload types without picture ID cannot determine that a stream is complete
+  // without retransmitting FEC, so using FEC + NACK for H.264 (for instance) is
+  // a waste of bandwidth since FEC packets still have to be transmitted. Note
+  // that this is not the case with FLEXFEC.
+  if (enable_protection_nack &&
+      !PayloadTypeSupportsSkippingFecPackets(
+          config_.encoder_settings.payload_name)) {
+    LOG(LS_WARNING) << "Transmitting payload type without picture ID using"
+                       "NACK+FEC is a waste of bandwidth since FEC packets "
+                       "also have to be retransmitted. Disabling FEC.";
+    enable_protection_fec = false;
+  }
+
+  // Set to valid uint8_ts to be castable later without signed overflows.
+  uint8_t payload_type_red = 0;
+  uint8_t payload_type_fec = 0;
+  // TODO(changbin): Should set RTX for RED mapping in RTP sender in future.
+  // Validate payload types. If either RED or FEC payload types are set then
+  // both should be. If FEC is enabled then they both have to be set.
+  if (enable_protection_fec || config_.rtp.fec.red_payload_type != -1 ||
+      config_.rtp.fec.ulpfec_payload_type != -1) {
+    RTC_DCHECK_GE(config_.rtp.fec.red_payload_type, 0);
+    RTC_DCHECK_GE(config_.rtp.fec.ulpfec_payload_type, 0);
+    RTC_DCHECK_LE(config_.rtp.fec.red_payload_type, 127);
+    RTC_DCHECK_LE(config_.rtp.fec.ulpfec_payload_type, 127);
+    payload_type_red = static_cast<uint8_t>(config_.rtp.fec.red_payload_type);
+    payload_type_fec =
+        static_cast<uint8_t>(config_.rtp.fec.ulpfec_payload_type);
+  } else {
+    // Payload types unset.
+    RTC_DCHECK_EQ(config_.rtp.fec.red_payload_type, -1);
+    RTC_DCHECK_EQ(config_.rtp.fec.ulpfec_payload_type, -1);
+  }
+
+  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+    // Set NACK.
+    rtp_rtcp->SetStorePacketsStatus(
+        enable_protection_nack || congestion_controller_->pacer(),
+        kMinSendSidePacketHistorySize);
+    // Set FEC.
+    for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+      rtp_rtcp->SetGenericFECStatus(enable_protection_fec, payload_type_red,
+                                    payload_type_fec);
+    }
+  }
+
+  vie_encoder_.SetProtectionMethod(enable_protection_nack,
+                                   enable_protection_fec);
+}
+
 void VideoSendStream::ConfigureSsrcs() {
   // Configure regular SSRCs.
   for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
@@ -562,7 +629,7 @@
     // Restore RTP state if previous existed.
     RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
     if (it != suspended_ssrcs_.end())
-      rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second);
+      rtp_rtcp->SetRtpState(it->second);
   }
 
   // Set up RTX if available.
@@ -577,7 +644,7 @@
     rtp_rtcp->SetRtxSsrc(ssrc);
     RtpStateMap::iterator it = suspended_ssrcs_.find(ssrc);
     if (it != suspended_ssrcs_.end())
-      rtp_rtcp->SetRtpStateForSsrc(ssrc, it->second);
+      rtp_rtcp->SetRtxState(it->second);
   }
 
   // Configure RTX payload types.
@@ -600,12 +667,13 @@
   std::map<uint32_t, RtpState> rtp_states;
   for (size_t i = 0; i < config_.rtp.ssrcs.size(); ++i) {
     uint32_t ssrc = config_.rtp.ssrcs[i];
-    rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc);
+    RTC_DCHECK_EQ(ssrc, rtp_rtcp_modules_[i]->SSRC());
+    rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtpState();
   }
 
   for (size_t i = 0; i < config_.rtp.rtx.ssrcs.size(); ++i) {
     uint32_t ssrc = config_.rtp.rtx.ssrcs[i];
-    rtp_states[ssrc] = vie_channel_.GetRtpStateForSsrc(ssrc);
+    rtp_states[ssrc] = rtp_rtcp_modules_[i]->GetRtxState();
   }
 
   return rtp_states;
@@ -636,5 +704,28 @@
   vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
 }
 
+int VideoSendStream::ProtectionRequest(const FecProtectionParams* delta_params,
+                                       const FecProtectionParams* key_params,
+                                       uint32_t* sent_video_rate_bps,
+                                       uint32_t* sent_nack_rate_bps,
+                                       uint32_t* sent_fec_rate_bps) {
+  *sent_video_rate_bps = 0;
+  *sent_nack_rate_bps = 0;
+  *sent_fec_rate_bps = 0;
+  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
+    uint32_t not_used = 0;
+    uint32_t module_video_rate = 0;
+    uint32_t module_fec_rate = 0;
+    uint32_t module_nack_rate = 0;
+    rtp_rtcp->SetFecParameters(delta_params, key_params);
+    rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
+                          &module_nack_rate);
+    *sent_video_rate_bps += module_video_rate;
+    *sent_nack_rate_bps += module_nack_rate;
+    *sent_fec_rate_bps += module_fec_rate;
+  }
+  return 0;
+}
+
 }  // namespace internal
 }  // namespace webrtc
diff --git a/video/video_send_stream.h b/video/video_send_stream.h
index 8b3d064..688e8fc 100644
--- a/video/video_send_stream.h
+++ b/video/video_send_stream.h
@@ -42,7 +42,8 @@
 
 class VideoSendStream : public webrtc::VideoSendStream,
                         public webrtc::CpuOveruseObserver,
-                        public webrtc::BitrateAllocatorObserver {
+                        public webrtc::BitrateAllocatorObserver,
+                        public webrtc::VCMProtectionCallback {
  public:
   VideoSendStream(int num_cpu_cores,
                   ProcessThread* module_process_thread,
@@ -81,10 +82,18 @@
                         uint8_t fraction_loss,
                         int64_t rtt) override;
 
+  // Implements webrtc::VCMProtectionCallback.
+  int ProtectionRequest(const FecProtectionParams* delta_params,
+                        const FecProtectionParams* key_params,
+                        uint32_t* sent_video_rate_bps,
+                        uint32_t* sent_nack_rate_bps,
+                        uint32_t* sent_fec_rate_bps) override;
+
  private:
   static bool EncoderThreadFunction(void* obj);
   void EncoderProcess();
 
+  void ConfigureProtection();
   void ConfigureSsrcs();
 
   SendStatisticsProxy stats_proxy_;
@@ -103,16 +112,14 @@
   volatile int stop_encoder_thread_;
 
   OveruseFrameDetector overuse_detector_;
-  PayloadRouter payload_router_;
   EncoderStateFeedback encoder_feedback_;
-  ViEChannel vie_channel_;
-  ViEReceiver* const vie_receiver_;
   ViEEncoder vie_encoder_;
   VideoCodingModule* const vcm_;
-  // TODO(pbos): Move RtpRtcp ownership to VideoSendStream.
-  // RtpRtcp modules, currently owned by ViEChannel but ownership should
-  // eventually move here.
+
+  const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
+  // RtpRtcp modules, declared here as they use other members on construction.
   const std::vector<RtpRtcp*> rtp_rtcp_modules_;
+  PayloadRouter payload_router_;
   VideoCaptureInput input_;
 };
 }  // namespace internal
diff --git a/video/vie_channel.cc b/video/vie_channel.cc
index c0676bc..842558b 100644
--- a/video/vie_channel.cc
+++ b/video/vie_channel.cc
@@ -35,10 +35,47 @@
 
 namespace webrtc {
 
-static const int kMinSendSidePacketHistorySize = 600;
 static const int kMaxPacketAgeToNack = 450;
 static const int kMaxNackListSize = 250;
 
+namespace {
+
+std::unique_ptr<RtpRtcp> CreateRtpRtcpModule(
+    ReceiveStatistics* receive_statistics,
+    Transport* outgoing_transport,
+    RtcpRttStats* rtt_stats,
+    RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
+    RemoteBitrateEstimator* remote_bitrate_estimator,
+    RtpPacketSender* paced_sender,
+    TransportSequenceNumberAllocator* transport_sequence_number_allocator) {
+  RtpRtcp::Configuration configuration;
+  configuration.audio = false;
+  configuration.receiver_only = true;
+  configuration.receive_statistics = receive_statistics;
+  configuration.outgoing_transport = outgoing_transport;
+  configuration.intra_frame_callback = nullptr;
+  configuration.rtt_stats = rtt_stats;
+  configuration.rtcp_packet_type_counter_observer =
+      rtcp_packet_type_counter_observer;
+  configuration.paced_sender = paced_sender;
+  configuration.transport_sequence_number_allocator =
+      transport_sequence_number_allocator;
+  configuration.send_bitrate_observer = nullptr;
+  configuration.send_frame_count_observer = nullptr;
+  configuration.send_side_delay_observer = nullptr;
+  configuration.bandwidth_callback = nullptr;
+  configuration.transport_feedback_callback = nullptr;
+
+  std::unique_ptr<RtpRtcp> rtp_rtcp(RtpRtcp::CreateRtpRtcp(configuration));
+  rtp_rtcp->SetSendingStatus(false);
+  rtp_rtcp->SetSendingMediaStatus(false);
+  rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
+
+  return rtp_rtcp;
+}
+
+}  // namespace
+
 // Helper class receiving statistics callbacks.
 class ChannelStatsObserver : public CallStatsObserver {
  public:
@@ -54,82 +91,35 @@
   ViEChannel* const owner_;
 };
 
-class ViEChannelProtectionCallback : public VCMProtectionCallback {
- public:
-  explicit ViEChannelProtectionCallback(ViEChannel* owner) : owner_(owner) {}
-  ~ViEChannelProtectionCallback() {}
-
-
-  int ProtectionRequest(
-      const FecProtectionParams* delta_fec_params,
-      const FecProtectionParams* key_fec_params,
-      uint32_t* sent_video_rate_bps,
-      uint32_t* sent_nack_rate_bps,
-      uint32_t* sent_fec_rate_bps) override {
-    return owner_->ProtectionRequest(delta_fec_params, key_fec_params,
-                                     sent_video_rate_bps, sent_nack_rate_bps,
-                                     sent_fec_rate_bps);
-  }
- private:
-  ViEChannel* owner_;
-};
-
 ViEChannel::ViEChannel(Transport* transport,
                        ProcessThread* module_process_thread,
-                       PayloadRouter* send_payload_router,
                        VideoCodingModule* vcm,
-                       RtcpIntraFrameObserver* intra_frame_observer,
-                       RtcpBandwidthObserver* bandwidth_observer,
-                       TransportFeedbackObserver* transport_feedback_observer,
                        RemoteBitrateEstimator* remote_bitrate_estimator,
                        RtcpRttStats* rtt_stats,
                        PacedSender* paced_sender,
-                       PacketRouter* packet_router,
-                       size_t max_rtp_streams,
-                       bool sender)
-    : sender_(sender),
-      module_process_thread_(module_process_thread),
-      send_payload_router_(send_payload_router),
-      vcm_protection_callback_(new ViEChannelProtectionCallback(this)),
+                       PacketRouter* packet_router)
+    : module_process_thread_(module_process_thread),
       vcm_(vcm),
       vie_receiver_(vcm_, remote_bitrate_estimator, this),
       stats_observer_(new ChannelStatsObserver(this)),
       receive_stats_callback_(nullptr),
       incoming_video_stream_(nullptr),
-      intra_frame_observer_(intra_frame_observer),
       rtt_stats_(rtt_stats),
       paced_sender_(paced_sender),
       packet_router_(packet_router),
-      bandwidth_observer_(bandwidth_observer),
-      transport_feedback_observer_(transport_feedback_observer),
       max_nack_reordering_threshold_(kMaxPacketAgeToNack),
       pre_render_callback_(nullptr),
       last_rtt_ms_(0),
-      rtp_rtcp_modules_(
-          CreateRtpRtcpModules(!sender,
-                               vie_receiver_.GetReceiveStatistics(),
-                               transport,
-                               intra_frame_observer_,
-                               bandwidth_observer_.get(),
-                               transport_feedback_observer_,
-                               rtt_stats_,
-                               &rtcp_packet_type_counter_observer_,
-                               remote_bitrate_estimator,
-                               paced_sender_,
-                               packet_router_,
-                               &send_bitrate_observer_,
-                               &send_frame_count_observer_,
-                               &send_side_delay_observer_,
-                               max_rtp_streams)) {
-  vie_receiver_.Init(rtp_rtcp_modules_);
-  if (sender_) {
-    RTC_DCHECK(send_payload_router_);
-    RTC_DCHECK(!vcm_);
-  } else {
-    RTC_DCHECK(!send_payload_router_);
-    RTC_DCHECK(vcm_);
-    vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
-  }
+      rtp_rtcp_(CreateRtpRtcpModule(vie_receiver_.GetReceiveStatistics(),
+                                    transport,
+                                    rtt_stats_,
+                                    &rtcp_packet_type_counter_observer_,
+                                    remote_bitrate_estimator,
+                                    paced_sender_,
+                                    packet_router_)) {
+  vie_receiver_.Init(rtp_rtcp_.get());
+  RTC_DCHECK(vcm_);
+  vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
 }
 
 int32_t ViEChannel::Init() {
@@ -137,28 +127,18 @@
   module_process_thread_->RegisterModule(vie_receiver_.GetReceiveStatistics());
 
   // RTP/RTCP initialization.
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    module_process_thread_->RegisterModule(rtp_rtcp);
-    packet_router_->AddRtpModule(rtp_rtcp);
-  }
+  module_process_thread_->RegisterModule(rtp_rtcp_.get());
+  packet_router_->AddRtpModule(rtp_rtcp_.get());
 
-  rtp_rtcp_modules_[0]->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
-  if (paced_sender_) {
-    for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
-      rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
+  rtp_rtcp_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
+  if (vcm_->RegisterReceiveCallback(this) != 0) {
+    return -1;
   }
-  if (sender_) {
-    send_payload_router_->SetSendingRtpModules(1);
-    RTC_DCHECK(!send_payload_router_->active());
-  } else {
-    if (vcm_->RegisterReceiveCallback(this) != 0) {
-      return -1;
-    }
-    vcm_->RegisterFrameTypeCallback(this);
-    vcm_->RegisterReceiveStatisticsCallback(this);
-    vcm_->RegisterDecoderTimingCallback(this);
-    vcm_->SetRenderDelay(kDefaultRenderDelayMs);
-  }
+  vcm_->RegisterFrameTypeCallback(this);
+  vcm_->RegisterReceiveStatisticsCallback(this);
+  vcm_->RegisterDecoderTimingCallback(this);
+  vcm_->SetRenderDelay(kDefaultRenderDelayMs);
+
   return 0;
 }
 
@@ -166,14 +146,9 @@
   // Make sure we don't get more callbacks from the RTP module.
   module_process_thread_->DeRegisterModule(
       vie_receiver_.GetReceiveStatistics());
-  if (sender_) {
-    send_payload_router_->SetSendingRtpModules(0);
-  }
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    packet_router_->RemoveRtpModule(rtp_rtcp);
-    module_process_thread_->DeRegisterModule(rtp_rtcp);
-    delete rtp_rtcp;
-  }
+
+  packet_router_->RemoveRtpModule(rtp_rtcp_.get());
+  module_process_thread_->DeRegisterModule(rtp_rtcp_.get());
 }
 
 void ViEChannel::SetProtectionMode(bool enable_nack,
@@ -203,44 +178,32 @@
     protection_method = kProtectionNone;
   }
 
-  if (!sender_)
-    vcm_->SetVideoProtection(protection_method, true);
+  vcm_->SetVideoProtection(protection_method, true);
 
   // Set NACK.
   ProcessNACKRequest(enable_nack);
 
   // Set FEC.
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    rtp_rtcp->SetGenericFECStatus(enable_fec,
-                                  static_cast<uint8_t>(payload_type_red),
-                                  static_cast<uint8_t>(payload_type_fec));
-  }
+  rtp_rtcp_->SetGenericFECStatus(enable_fec,
+                                 static_cast<uint8_t>(payload_type_red),
+                                 static_cast<uint8_t>(payload_type_fec));
 }
 
 void ViEChannel::ProcessNACKRequest(const bool enable) {
   if (enable) {
     // Turn on NACK.
-    if (rtp_rtcp_modules_[0]->RTCP() == RtcpMode::kOff)
+    if (rtp_rtcp_->RTCP() == RtcpMode::kOff)
       return;
     vie_receiver_.SetNackStatus(true, max_nack_reordering_threshold_);
+    vcm_->RegisterPacketRequestCallback(this);
+    // Don't introduce errors when NACK is enabled.
+    vcm_->SetDecodeErrorMode(kNoErrors);
 
-    for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
-      rtp_rtcp->SetStorePacketsStatus(true, kMinSendSidePacketHistorySize);
-
-    if (!sender_) {
-      vcm_->RegisterPacketRequestCallback(this);
-      // Don't introduce errors when NACK is enabled.
-      vcm_->SetDecodeErrorMode(kNoErrors);
-    }
   } else {
-    if (!sender_) {
-      vcm_->RegisterPacketRequestCallback(nullptr);
-      for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
-        rtp_rtcp->SetStorePacketsStatus(false, 0);
-      // When NACK is off, allow decoding with errors. Otherwise, the video
-      // will freeze, and will only recover with a complete key frame.
-      vcm_->SetDecodeErrorMode(kWithErrors);
-    }
+    vcm_->RegisterPacketRequestCallback(nullptr);
+    // When NACK is off, allow decoding with errors. Otherwise, the video
+    // will freeze, and will only recover with a complete key frame.
+    vcm_->SetDecodeErrorMode(kWithErrors);
     vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
   }
 }
@@ -253,14 +216,9 @@
 }
 
 RtpState ViEChannel::GetRtpStateForSsrc(uint32_t ssrc) const {
-  RTC_DCHECK(!rtp_rtcp_modules_[0]->Sending());
-  RtpState rtp_state;
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    if (rtp_rtcp->GetRtpStateForSsrc(ssrc, &rtp_state))
-      return rtp_state;
-  }
-  LOG(LS_ERROR) << "Couldn't get RTP state for ssrc: " << ssrc;
-  return rtp_state;
+  RTC_DCHECK(!rtp_rtcp_->Sending());
+  RTC_DCHECK_EQ(ssrc, rtp_rtcp_->SSRC());
+  return rtp_rtcp_->GetRtpState();
 }
 
 void ViEChannel::RegisterRtcpPacketTypeCounterObserver(
@@ -268,42 +226,14 @@
   rtcp_packet_type_counter_observer_.Set(observer);
 }
 
-void ViEChannel::GetSendStreamDataCounters(
-    StreamDataCounters* rtp_counters,
-    StreamDataCounters* rtx_counters) const {
-  *rtp_counters = StreamDataCounters();
-  *rtx_counters = StreamDataCounters();
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    StreamDataCounters rtp_data;
-    StreamDataCounters rtx_data;
-    rtp_rtcp->GetSendStreamDataCounters(&rtp_data, &rtx_data);
-    rtp_counters->Add(rtp_data);
-    rtx_counters->Add(rtx_data);
-  }
-}
-
-void ViEChannel::RegisterSendSideDelayObserver(
-    SendSideDelayObserver* observer) {
-  send_side_delay_observer_.Set(observer);
-}
-
-void ViEChannel::RegisterSendBitrateObserver(
-    BitrateStatisticsObserver* observer) {
-  send_bitrate_observer_.Set(observer);
-}
-
-const std::vector<RtpRtcp*>& ViEChannel::rtp_rtcp() const {
-  return rtp_rtcp_modules_;
+RtpRtcp* ViEChannel::rtp_rtcp() const {
+  return rtp_rtcp_.get();
 }
 
 ViEReceiver* ViEChannel::vie_receiver() {
   return &vie_receiver_;
 }
 
-VCMProtectionCallback* ViEChannel::vcm_protection_callback() {
-  return vcm_protection_callback_.get();
-}
-
 CallStatsObserver* ViEChannel::GetStatsObserver() {
   return stats_observer_.get();
 }
@@ -325,7 +255,7 @@
 
 int32_t ViEChannel::ReceivedDecodedReferenceFrame(
   const uint64_t picture_id) {
-  return rtp_rtcp_modules_[0]->SendRTCPReferencePictureSelection(picture_id);
+  return rtp_rtcp_->SendRTCPReferencePictureSelection(picture_id);
 }
 
 void ViEChannel::OnIncomingPayloadType(int payload_type) {
@@ -375,105 +305,29 @@
 }
 
 int32_t ViEChannel::RequestKeyFrame() {
-  return rtp_rtcp_modules_[0]->RequestKeyFrame();
+  return rtp_rtcp_->RequestKeyFrame();
 }
 
 int32_t ViEChannel::SliceLossIndicationRequest(
   const uint64_t picture_id) {
-  return rtp_rtcp_modules_[0]->SendRTCPSliceLossIndication(
+  return rtp_rtcp_->SendRTCPSliceLossIndication(
       static_cast<uint8_t>(picture_id));
 }
 
 int32_t ViEChannel::ResendPackets(const uint16_t* sequence_numbers,
                                   uint16_t length) {
-  return rtp_rtcp_modules_[0]->SendNACK(sequence_numbers, length);
+  return rtp_rtcp_->SendNACK(sequence_numbers, length);
 }
 
 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
-  if (!sender_)
-    vcm_->SetReceiveChannelParameters(max_rtt_ms);
+  vcm_->SetReceiveChannelParameters(max_rtt_ms);
 
   rtc::CritScope lock(&crit_);
   last_rtt_ms_ = avg_rtt_ms;
 }
 
-int ViEChannel::ProtectionRequest(const FecProtectionParams* delta_fec_params,
-                                  const FecProtectionParams* key_fec_params,
-                                  uint32_t* video_rate_bps,
-                                  uint32_t* nack_rate_bps,
-                                  uint32_t* fec_rate_bps) {
-  *video_rate_bps = 0;
-  *nack_rate_bps = 0;
-  *fec_rate_bps = 0;
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
-    uint32_t not_used = 0;
-    uint32_t module_video_rate = 0;
-    uint32_t module_fec_rate = 0;
-    uint32_t module_nack_rate = 0;
-    rtp_rtcp->SetFecParameters(delta_fec_params, key_fec_params);
-    rtp_rtcp->BitrateSent(&not_used, &module_video_rate, &module_fec_rate,
-                          &module_nack_rate);
-    *video_rate_bps += module_video_rate;
-    *nack_rate_bps += module_nack_rate;
-    *fec_rate_bps += module_fec_rate;
-  }
-  return 0;
-}
-
-std::vector<RtpRtcp*> ViEChannel::CreateRtpRtcpModules(
-    bool receiver_only,
-    ReceiveStatistics* receive_statistics,
-    Transport* outgoing_transport,
-    RtcpIntraFrameObserver* intra_frame_callback,
-    RtcpBandwidthObserver* bandwidth_callback,
-    TransportFeedbackObserver* transport_feedback_callback,
-    RtcpRttStats* rtt_stats,
-    RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
-    RemoteBitrateEstimator* remote_bitrate_estimator,
-    RtpPacketSender* paced_sender,
-    TransportSequenceNumberAllocator* transport_sequence_number_allocator,
-    BitrateStatisticsObserver* send_bitrate_observer,
-    FrameCountObserver* send_frame_count_observer,
-    SendSideDelayObserver* send_side_delay_observer,
-    size_t num_modules) {
-  RTC_DCHECK_GT(num_modules, 0u);
-  RtpRtcp::Configuration configuration;
-  ReceiveStatistics* null_receive_statistics = configuration.receive_statistics;
-  configuration.audio = false;
-  configuration.receiver_only = receiver_only;
-  configuration.receive_statistics = receive_statistics;
-  configuration.outgoing_transport = outgoing_transport;
-  configuration.intra_frame_callback = intra_frame_callback;
-  configuration.rtt_stats = rtt_stats;
-  configuration.rtcp_packet_type_counter_observer =
-      rtcp_packet_type_counter_observer;
-  configuration.paced_sender = paced_sender;
-  configuration.transport_sequence_number_allocator =
-      transport_sequence_number_allocator;
-  configuration.send_bitrate_observer = send_bitrate_observer;
-  configuration.send_frame_count_observer = send_frame_count_observer;
-  configuration.send_side_delay_observer = send_side_delay_observer;
-  configuration.bandwidth_callback = bandwidth_callback;
-  configuration.transport_feedback_callback = transport_feedback_callback;
-
-  std::vector<RtpRtcp*> modules;
-  for (size_t i = 0; i < num_modules; ++i) {
-    RtpRtcp* rtp_rtcp = RtpRtcp::CreateRtpRtcp(configuration);
-    rtp_rtcp->SetSendingStatus(false);
-    rtp_rtcp->SetSendingMediaStatus(false);
-    rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
-    modules.push_back(rtp_rtcp);
-    // Receive statistics and remote bitrate estimator should only be set for
-    // the primary (first) module.
-    configuration.receive_statistics = null_receive_statistics;
-    configuration.remote_bitrate_estimator = nullptr;
-  }
-  return modules;
-}
-
 void ViEChannel::RegisterPreRenderCallback(
     I420FrameCallback* pre_render_callback) {
-  RTC_DCHECK(!sender_);
   rtc::CritScope lock(&crit_);
   pre_render_callback_ = pre_render_callback;
 }
@@ -491,16 +345,11 @@
 }
 
 void ViEChannel::OnIncomingSSRCChanged(const uint32_t ssrc) {
-  rtp_rtcp_modules_[0]->SetRemoteSSRC(ssrc);
+  rtp_rtcp_->SetRemoteSSRC(ssrc);
 }
 
 void ViEChannel::OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) {}
 
-void ViEChannel::RegisterSendFrameCountObserver(
-    FrameCountObserver* observer) {
-  send_frame_count_observer_.Set(observer);
-}
-
 void ViEChannel::RegisterReceiveStatisticsProxy(
     ReceiveStatisticsProxy* receive_statistics_proxy) {
   rtc::CritScope lock(&crit_);
diff --git a/video/vie_channel.h b/video/vie_channel.h
index 8a9d70e..1bcae19 100644
--- a/video/vie_channel.h
+++ b/video/vie_channel.h
@@ -42,7 +42,6 @@
 class ProcessThread;
 class ReceiveStatisticsProxy;
 class RtcpRttStats;
-class ViEChannelProtectionCallback;
 class ViERTPObserver;
 class VideoCodingModule;
 class VideoRenderCallback;
@@ -61,21 +60,14 @@
                    public RtpFeedback {
  public:
   friend class ChannelStatsObserver;
-  friend class ViEChannelProtectionCallback;
 
   ViEChannel(Transport* transport,
              ProcessThread* module_process_thread,
-             PayloadRouter* send_payload_router,
              VideoCodingModule* vcm,
-             RtcpIntraFrameObserver* intra_frame_observer,
-             RtcpBandwidthObserver* bandwidth_observer,
-             TransportFeedbackObserver* transport_feedback_observer,
              RemoteBitrateEstimator* remote_bitrate_estimator,
              RtcpRttStats* rtt_stats,
              PacedSender* paced_sender,
-             PacketRouter* packet_router,
-             size_t max_rtp_streams,
-             bool sender);
+             PacketRouter* packet_router);
   ~ViEChannel();
 
   int32_t Init();
@@ -87,15 +79,6 @@
 
   RtpState GetRtpStateForSsrc(uint32_t ssrc) const;
 
-  // Gets send statistics for the rtp and rtx stream.
-  void GetSendStreamDataCounters(StreamDataCounters* rtp_counters,
-                                 StreamDataCounters* rtx_counters) const;
-
-  void RegisterSendSideDelayObserver(SendSideDelayObserver* observer);
-
-  // Called on any new send bitrate estimate.
-  void RegisterSendBitrateObserver(BitrateStatisticsObserver* observer);
-
   // Implements RtpFeedback.
   int32_t OnInitializeDecoder(const int8_t payload_type,
                               const char payload_name[RTP_PAYLOAD_NAME_SIZE],
@@ -105,11 +88,9 @@
   void OnIncomingSSRCChanged(const uint32_t ssrc) override;
   void OnIncomingCSRCChanged(const uint32_t CSRC, const bool added) override;
 
-  // Gets the modules used by the channel.
-  const std::vector<RtpRtcp*>& rtp_rtcp() const;
+  // Gets the module used by the channel.
+  RtpRtcp* rtp_rtcp() const;
   ViEReceiver* vie_receiver();
-  VCMProtectionCallback* vcm_protection_callback();
-
 
   CallStatsObserver* GetStatsObserver();
 
@@ -151,7 +132,6 @@
 
   void RegisterPreRenderCallback(I420FrameCallback* pre_render_callback);
 
-  void RegisterSendFrameCountObserver(FrameCountObserver* observer);
   void RegisterRtcpPacketTypeCounterObserver(
       RtcpPacketTypeCounterObserver* observer);
   void RegisterReceiveStatisticsProxy(
@@ -161,30 +141,7 @@
  protected:
   void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms);
 
-  int ProtectionRequest(const FecProtectionParams* delta_fec_params,
-                        const FecProtectionParams* key_fec_params,
-                        uint32_t* sent_video_rate_bps,
-                        uint32_t* sent_nack_rate_bps,
-                        uint32_t* sent_fec_rate_bps);
-
  private:
-  static std::vector<RtpRtcp*> CreateRtpRtcpModules(
-      bool receiver_only,
-      ReceiveStatistics* receive_statistics,
-      Transport* outgoing_transport,
-      RtcpIntraFrameObserver* intra_frame_callback,
-      RtcpBandwidthObserver* bandwidth_callback,
-      TransportFeedbackObserver* transport_feedback_callback,
-      RtcpRttStats* rtt_stats,
-      RtcpPacketTypeCounterObserver* rtcp_packet_type_counter_observer,
-      RemoteBitrateEstimator* remote_bitrate_estimator,
-      RtpPacketSender* paced_sender,
-      TransportSequenceNumberAllocator* transport_sequence_number_allocator,
-      BitrateStatisticsObserver* send_bitrate_observer,
-      FrameCountObserver* send_frame_count_observer,
-      SendSideDelayObserver* send_side_delay_observer,
-      size_t num_modules);
-
   // Assumed to be protected.
   void StartDecodeThread();
   void StopDecodeThread();
@@ -219,41 +176,6 @@
     RTC_DISALLOW_COPY_AND_ASSIGN(RegisterableCallback);
   };
 
-  class RegisterableBitrateStatisticsObserver:
-    public RegisterableCallback<BitrateStatisticsObserver> {
-    virtual void Notify(const BitrateStatistics& total_stats,
-                        const BitrateStatistics& retransmit_stats,
-                        uint32_t ssrc) {
-      rtc::CritScope lock(&critsect_);
-      if (callback_)
-        callback_->Notify(total_stats, retransmit_stats, ssrc);
-    }
-  } send_bitrate_observer_;
-
-  class RegisterableFrameCountObserver
-      : public RegisterableCallback<FrameCountObserver> {
-   public:
-    virtual void FrameCountUpdated(const FrameCounts& frame_counts,
-                                   uint32_t ssrc) {
-      rtc::CritScope lock(&critsect_);
-      if (callback_)
-        callback_->FrameCountUpdated(frame_counts, ssrc);
-    }
-
-   private:
-  } send_frame_count_observer_;
-
-  class RegisterableSendSideDelayObserver :
-      public RegisterableCallback<SendSideDelayObserver> {
-    void SendSideDelayUpdated(int avg_delay_ms,
-                              int max_delay_ms,
-                              uint32_t ssrc) override {
-      rtc::CritScope lock(&critsect_);
-      if (callback_)
-        callback_->SendSideDelayUpdated(avg_delay_ms, max_delay_ms, ssrc);
-    }
-  } send_side_delay_observer_;
-
   class RegisterableRtcpPacketTypeCounterObserver
       : public RegisterableCallback<RtcpPacketTypeCounterObserver> {
    public:
@@ -268,17 +190,12 @@
    private:
   } rtcp_packet_type_counter_observer_;
 
-  const bool sender_;
 
   ProcessThread* const module_process_thread_;
-  PayloadRouter* const send_payload_router_;
 
   // Used for all registered callbacks except rendering.
   rtc::CriticalSection crit_;
 
-  // Owned modules/classes.
-  std::unique_ptr<ViEChannelProtectionCallback> vcm_protection_callback_;
-
   VideoCodingModule* const vcm_;
   ViEReceiver vie_receiver_;
 
@@ -289,21 +206,17 @@
   ReceiveStatisticsProxy* receive_stats_callback_ GUARDED_BY(crit_);
   FrameCounts receive_frame_counts_ GUARDED_BY(crit_);
   IncomingVideoStream* incoming_video_stream_ GUARDED_BY(crit_);
-  RtcpIntraFrameObserver* const intra_frame_observer_;
   RtcpRttStats* const rtt_stats_;
   PacedSender* const paced_sender_;
   PacketRouter* const packet_router_;
 
-  const std::unique_ptr<RtcpBandwidthObserver> bandwidth_observer_;
-  TransportFeedbackObserver* const transport_feedback_observer_;
-
   int max_nack_reordering_threshold_;
   I420FrameCallback* pre_render_callback_ GUARDED_BY(crit_);
 
   int64_t last_rtt_ms_ GUARDED_BY(crit_);
 
-  // RtpRtcp modules, declared last as they use other members on construction.
-  const std::vector<RtpRtcp*> rtp_rtcp_modules_;
+  // RtpRtcp module, declared last as it use other members on construction.
+  const std::unique_ptr<RtpRtcp> rtp_rtcp_;
 };
 
 }  // namespace webrtc
diff --git a/video/vie_receiver.cc b/video/vie_receiver.cc
index e5ec167..9ead910 100644
--- a/video/vie_receiver.cc
+++ b/video/vie_receiver.cc
@@ -124,8 +124,8 @@
   return rtp_receiver_->CSRCs(csrcs);
 }
 
-void ViEReceiver::Init(const std::vector<RtpRtcp*>& modules) {
-  rtp_rtcp_ = modules;
+void ViEReceiver::Init(RtpRtcp* rtp_rtcp) {
+  rtp_rtcp_ = rtp_rtcp;
 }
 
 RtpReceiver* ViEReceiver::GetRtpReceiver() const {
@@ -318,8 +318,6 @@
 
 bool ViEReceiver::DeliverRtcp(const uint8_t* rtcp_packet,
                               size_t rtcp_packet_length) {
-  // Should be set by owner at construction time.
-  RTC_DCHECK(!rtp_rtcp_.empty());
   {
     rtc::CritScope lock(&receive_cs_);
     if (!receiving_) {
@@ -327,11 +325,10 @@
     }
   }
 
-  for (RtpRtcp* rtp_rtcp : rtp_rtcp_)
-    rtp_rtcp->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
+  rtp_rtcp_->IncomingRtcpPacket(rtcp_packet, rtcp_packet_length);
 
   int64_t rtt = 0;
-  rtp_rtcp_[0]->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr);
+  rtp_rtcp_->RTT(rtp_receiver_->SSRC(), &rtt, nullptr, nullptr, nullptr);
   if (rtt == 0) {
     // Waiting for valid rtt.
     return true;
@@ -339,8 +336,8 @@
   uint32_t ntp_secs = 0;
   uint32_t ntp_frac = 0;
   uint32_t rtp_timestamp = 0;
-  if (rtp_rtcp_[0]->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
-                              &rtp_timestamp) != 0) {
+  if (rtp_rtcp_->RemoteNTP(&ntp_secs, &ntp_frac, nullptr, nullptr,
+                           &rtp_timestamp) != 0) {
     // Waiting for RTCP.
     return true;
   }
@@ -382,7 +379,7 @@
     return false;
   // Check if this is a retransmission.
   int64_t min_rtt = 0;
-  rtp_rtcp_[0]->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr);
+  rtp_rtcp_->RTT(rtp_receiver_->SSRC(), nullptr, nullptr, &min_rtt, nullptr);
   return !in_order &&
       statistician->IsRetransmitOfOldPacket(header, min_rtt);
 }
diff --git a/video/vie_receiver.h b/video/vie_receiver.h
index 999e66d..c96bf5e 100644
--- a/video/vie_receiver.h
+++ b/video/vie_receiver.h
@@ -60,7 +60,7 @@
   uint32_t GetRemoteSsrc() const;
   int GetCsrcs(uint32_t* csrcs) const;
 
-  void Init(const std::vector<RtpRtcp*>& modules);
+  void Init(RtpRtcp* rtp_rtcp);
 
   RtpReceiver* GetRtpReceiver() const;
 
@@ -102,7 +102,7 @@
   RemoteBitrateEstimator* const remote_bitrate_estimator_;
 
   // TODO(pbos): Make const and set on construction.
-  std::vector<RtpRtcp*> rtp_rtcp_;
+  RtpRtcp* rtp_rtcp_;  // Owned by ViEChannel
 
   RemoteNtpTimeEstimator ntp_estimator_;
   RTPPayloadRegistry rtp_payload_registry_;