Untangle ViEChannel and ViEEncoder.

Extracts shared members outside the two objects, removing PayloadRouter
from receivers and the VCM for ViEChannel from senders.

Removes Start/StopThreadsAndSetSharedMembers that was used to set the
shared state between them.

Also adding DCHECKs to document what's only used by the
sender/receiver side.

BUG=webrtc:5494
R=stefan@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#11500}
diff --git a/webrtc/modules/video_coding/include/video_coding.h b/webrtc/modules/video_coding/include/video_coding.h
index 3920c25..6433f56 100644
--- a/webrtc/modules/video_coding/include/video_coding.h
+++ b/webrtc/modules/video_coding/include/video_coding.h
@@ -75,8 +75,6 @@
 
   static VideoCodingModule* Create(Clock* clock, EventFactory* event_factory);
 
-  static void Destroy(VideoCodingModule* module);
-
   // Get supported codec settings using codec type
   //
   // Input:
diff --git a/webrtc/modules/video_coding/video_coding_impl.cc b/webrtc/modules/video_coding/video_coding_impl.cc
index a9b277f..7f74b41 100644
--- a/webrtc/modules/video_coding/video_coding_impl.cc
+++ b/webrtc/modules/video_coding/video_coding_impl.cc
@@ -310,9 +310,4 @@
                                    nullptr);
 }
 
-void VideoCodingModule::Destroy(VideoCodingModule* module) {
-  if (module != NULL) {
-    delete static_cast<VideoCodingModuleImpl*>(module);
-  }
-}
 }  // namespace webrtc
diff --git a/webrtc/modules/video_coding/video_coding_robustness_unittest.cc b/webrtc/modules/video_coding/video_coding_robustness_unittest.cc
index dd6565d..51cffcd 100644
--- a/webrtc/modules/video_coding/video_coding_robustness_unittest.cc
+++ b/webrtc/modules/video_coding/video_coding_robustness_unittest.cc
@@ -35,7 +35,7 @@
   virtual void SetUp() {
     clock_.reset(new SimulatedClock(0));
     ASSERT_TRUE(clock_.get() != NULL);
-    vcm_ = VideoCodingModule::Create(clock_.get(), &event_factory_);
+    vcm_.reset(VideoCodingModule::Create(clock_.get(), &event_factory_));
     ASSERT_TRUE(vcm_ != NULL);
     const size_t kMaxNackListSize = 250;
     const int kMaxPacketAgeToNack = 450;
@@ -47,7 +47,7 @@
     vcm_->RegisterExternalDecoder(&decoder_, video_codec_.plType);
   }
 
-  virtual void TearDown() { VideoCodingModule::Destroy(vcm_); }
+  virtual void TearDown() { vcm_.reset(); }
 
   void InsertPacket(uint32_t timestamp,
                     uint16_t seq_no,
@@ -69,7 +69,7 @@
     ASSERT_EQ(VCM_OK, vcm_->IncomingPacket(payload, kPayloadLen, rtp_info));
   }
 
-  VideoCodingModule* vcm_;
+  rtc::scoped_ptr<VideoCodingModule> vcm_;
   VideoCodec video_codec_;
   MockVCMFrameTypeCallback frame_type_callback_;
   MockPacketRequestCallback request_callback_;
diff --git a/webrtc/video/encoder_state_feedback_unittest.cc b/webrtc/video/encoder_state_feedback_unittest.cc
index 8fa1c12..de4616f 100644
--- a/webrtc/video/encoder_state_feedback_unittest.cc
+++ b/webrtc/video/encoder_state_feedback_unittest.cc
@@ -37,6 +37,7 @@
                    nullptr,
                    nullptr,
                    pacer,
+                   nullptr,
                    nullptr) {}
   ~MockVieEncoder() {}
 
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index 7779fdd..28fe7f3 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -19,6 +19,7 @@
 #include "webrtc/base/logging.h"
 #include "webrtc/call/congestion_controller.h"
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
+#include "webrtc/modules/utility/include/process_thread.h"
 #include "webrtc/system_wrappers/include/clock.h"
 #include "webrtc/video/call_stats.h"
 #include "webrtc/video/receive_statistics_proxy.h"
@@ -148,9 +149,11 @@
     : transport_adapter_(config.rtcp_send_transport),
       encoded_frame_proxy_(config.pre_decode_callback),
       config_(config),
+      process_thread_(process_thread),
       clock_(Clock::GetRealTimeClock()),
       congestion_controller_(congestion_controller),
-      call_stats_(call_stats) {
+      call_stats_(call_stats),
+      vcm_(VideoCodingModule::Create(clock_, nullptr, nullptr)) {
   LOG(LS_INFO) << "VideoReceiveStream: " << config_.ToString();
 
   bool send_side_bwe =
@@ -160,10 +163,10 @@
       congestion_controller_->GetRemoteBitrateEstimator(send_side_bwe);
 
   vie_channel_.reset(new ViEChannel(
-      num_cpu_cores, &transport_adapter_, process_thread, nullptr,
-      nullptr, nullptr, bitrate_estimator, call_stats_->rtcp_rtt_stats(),
-      congestion_controller_->pacer(), congestion_controller_->packet_router(),
-      1, false));
+      num_cpu_cores, &transport_adapter_, process_thread, nullptr, vcm_.get(),
+      nullptr, nullptr, nullptr, bitrate_estimator,
+      call_stats_->rtcp_rtt_stats(), congestion_controller_->pacer(),
+      congestion_controller_->packet_router(), 1, false));
 
   RTC_CHECK(vie_channel_->Init() == 0);
 
@@ -284,11 +287,14 @@
 
   vie_channel_->RegisterPreDecodeImageCallback(this);
   vie_channel_->RegisterPreRenderCallback(this);
+
+  process_thread_->RegisterModule(vcm_.get());
 }
 
 VideoReceiveStream::~VideoReceiveStream() {
   LOG(LS_INFO) << "~VideoReceiveStream: " << config_.ToString();
   incoming_video_stream_->Stop();
+  process_thread_->DeRegisterModule(vcm_.get());
   vie_channel_->RegisterPreRenderCallback(nullptr);
   vie_channel_->RegisterPreDecodeImageCallback(nullptr);
 
diff --git a/webrtc/video/video_receive_stream.h b/webrtc/video/video_receive_stream.h
index 0ff5269..94e858a 100644
--- a/webrtc/video/video_receive_stream.h
+++ b/webrtc/video/video_receive_stream.h
@@ -21,6 +21,7 @@
 #include "webrtc/modules/video_render/video_render_defines.h"
 #include "webrtc/system_wrappers/include/clock.h"
 #include "webrtc/video/encoded_frame_callback_adapter.h"
+#include "webrtc/video/payload_router.h"
 #include "webrtc/video/receive_statistics_proxy.h"
 #include "webrtc/video/vie_channel.h"
 #include "webrtc/video/vie_encoder.h"
@@ -80,11 +81,13 @@
   TransportAdapter transport_adapter_;
   EncodedFrameCallbackAdapter encoded_frame_proxy_;
   const VideoReceiveStream::Config config_;
+  ProcessThread* const process_thread_;
   Clock* const clock_;
 
   CongestionController* const congestion_controller_;
   CallStats* const call_stats_;
 
+  rtc::scoped_ptr<VideoCodingModule> vcm_;
   rtc::scoped_ptr<IncomingVideoStream> incoming_video_stream_;
   rtc::scoped_ptr<ReceiveStatisticsProxy> stats_proxy_;
   rtc::scoped_ptr<ViEChannel> vie_channel_;
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index 254805f..c7280ed 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -25,7 +25,6 @@
 #include "webrtc/modules/utility/include/process_thread.h"
 #include "webrtc/video/call_stats.h"
 #include "webrtc/video/encoder_state_feedback.h"
-#include "webrtc/video/payload_router.h"
 #include "webrtc/video/video_capture_input.h"
 #include "webrtc/video/vie_channel.h"
 #include "webrtc/video/vie_encoder.h"
@@ -163,28 +162,27 @@
 
   const std::vector<uint32_t>& ssrcs = config.rtp.ssrcs;
 
-  vie_encoder_.reset(
-      new ViEEncoder(num_cpu_cores, module_process_thread_, &stats_proxy_,
-                     config.pre_encode_callback, &overuse_detector_,
-                     congestion_controller_->pacer(), bitrate_allocator));
+  vie_encoder_.reset(new ViEEncoder(
+      num_cpu_cores, module_process_thread_, &stats_proxy_,
+      config.pre_encode_callback, &overuse_detector_,
+      congestion_controller_->pacer(), &payload_router_, bitrate_allocator));
+  vcm_ = vie_encoder_->vcm();
   RTC_CHECK(vie_encoder_->Init());
 
   vie_channel_.reset(new ViEChannel(
       num_cpu_cores, config.send_transport, module_process_thread_,
-      encoder_feedback_->GetRtcpIntraFrameObserver(),
-      congestion_controller_->GetBitrateController()->
-          CreateRtcpBandwidthObserver(),
+      &payload_router_, nullptr, encoder_feedback_->GetRtcpIntraFrameObserver(),
+      congestion_controller_->GetBitrateController()
+          ->CreateRtcpBandwidthObserver(),
       transport_feedback_observer,
       congestion_controller_->GetRemoteBitrateEstimator(false),
       call_stats_->rtcp_rtt_stats(), congestion_controller_->pacer(),
       congestion_controller_->packet_router(), ssrcs.size(), true));
   RTC_CHECK(vie_channel_->Init() == 0);
 
-  call_stats_->RegisterStatsObserver(vie_channel_->GetStatsObserver());
+  vcm_->RegisterProtectionCallback(vie_channel_->vcm_protection_callback());
 
-  vie_encoder_->StartThreadsAndSetSharedMembers(
-      vie_channel_->send_payload_router(),
-      vie_channel_->vcm_protection_callback());
+  call_stats_->RegisterStatsObserver(vie_channel_->GetStatsObserver());
 
   std::vector<uint32_t> first_ssrc(1, ssrcs[0]);
   vie_encoder_->SetSsrcs(first_ssrc);
@@ -266,6 +264,10 @@
 VideoSendStream::~VideoSendStream() {
   LOG(LS_INFO) << "~VideoSendStream: " << config_.ToString();
   module_process_thread_->DeRegisterModule(&overuse_detector_);
+  // Remove vcm_protection_callback (part of vie_channel_) before destroying
+  // ViEChannel. vcm_ is owned by ViEEncoder and the registered callback does
+  // not outlive it.
+  vcm_->RegisterProtectionCallback(nullptr);
   vie_channel_->RegisterSendFrameCountObserver(nullptr);
   vie_channel_->RegisterSendBitrateObserver(nullptr);
   vie_channel_->RegisterRtcpPacketTypeCounterObserver(nullptr);
@@ -287,7 +289,6 @@
   // done before deleting the channel.
   congestion_controller_->RemoveEncoder(vie_encoder_.get());
   encoder_feedback_->RemoveEncoder(vie_encoder_.get());
-  vie_encoder_->StopThreadsAndRemoveSharedMembers();
 
   uint32_t remote_ssrc = vie_channel_->GetRemoteSSRC();
   congestion_controller_->GetRemoteBitrateEstimator(false)->RemoveStream(
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index acd36ec..4a58e6f 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -19,6 +19,7 @@
 #include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
 #include "webrtc/video/encoded_frame_callback_adapter.h"
+#include "webrtc/video/payload_router.h"
 #include "webrtc/video/send_statistics_proxy.h"
 #include "webrtc/video/video_capture_input.h"
 #include "webrtc/video_receive_stream.h"
@@ -88,8 +89,12 @@
 
   OveruseFrameDetector overuse_detector_;
   rtc::scoped_ptr<VideoCaptureInput> input_;
-  rtc::scoped_ptr<ViEChannel> vie_channel_;
+  PayloadRouter payload_router_;
   rtc::scoped_ptr<ViEEncoder> vie_encoder_;
+  rtc::scoped_ptr<ViEChannel> vie_channel_;
+  // TODO(pbos): Make proper const.
+  // const after construction.
+  VideoCodingModule* vcm_;
   rtc::scoped_ptr<EncoderStateFeedback> encoder_feedback_;
 
   // Used as a workaround to indicate that we should be using the configured
diff --git a/webrtc/video/vie_channel.cc b/webrtc/video/vie_channel.cc
index 28cc1d4..8c67b50 100644
--- a/webrtc/video/vie_channel.cc
+++ b/webrtc/video/vie_channel.cc
@@ -80,6 +80,8 @@
 ViEChannel::ViEChannel(uint32_t number_of_cores,
                        Transport* transport,
                        ProcessThread* module_process_thread,
+                       PayloadRouter* send_payload_router,
+                       VideoCodingModule* vcm,
                        RtcpIntraFrameObserver* intra_frame_observer,
                        RtcpBandwidthObserver* bandwidth_observer,
                        TransportFeedbackObserver* transport_feedback_observer,
@@ -92,11 +94,9 @@
     : number_of_cores_(number_of_cores),
       sender_(sender),
       module_process_thread_(module_process_thread),
-      send_payload_router_(new PayloadRouter()),
+      send_payload_router_(send_payload_router),
       vcm_protection_callback_(new ViEChannelProtectionCallback(this)),
-      vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(),
-                                     nullptr,
-                                     nullptr)),
+      vcm_(vcm),
       vie_receiver_(vcm_, remote_bitrate_estimator, this),
       vie_sync_(vcm_),
       stats_observer_(new ChannelStatsObserver(this)),
@@ -135,7 +135,14 @@
                                max_rtp_streams)),
       num_active_rtp_rtcp_modules_(1) {
   vie_receiver_.SetRtpRtcpModule(rtp_rtcp_modules_[0]);
-  vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
+  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);
+  }
 }
 
 int32_t ViEChannel::Init() {
@@ -155,18 +162,16 @@
     std::list<RtpRtcp*> send_rtp_modules(1, rtp_rtcp_modules_[0]);
     send_payload_router_->SetSendingRtpModules(send_rtp_modules);
     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);
+    module_process_thread_->RegisterModule(&vie_sync_);
   }
-  if (vcm_->RegisterReceiveCallback(this) != 0) {
-    return -1;
-  }
-  vcm_->RegisterFrameTypeCallback(this);
-  vcm_->RegisterReceiveStatisticsCallback(this);
-  vcm_->RegisterDecoderTimingCallback(this);
-  vcm_->SetRenderDelay(kDefaultRenderDelayMs);
-
-  module_process_thread_->RegisterModule(vcm_);
-  module_process_thread_->RegisterModule(&vie_sync_);
-
   return 0;
 }
 
@@ -175,9 +180,11 @@
   // Make sure we don't get more callbacks from the RTP module.
   module_process_thread_->DeRegisterModule(
       vie_receiver_.GetReceiveStatistics());
-  module_process_thread_->DeRegisterModule(vcm_);
-  module_process_thread_->DeRegisterModule(&vie_sync_);
-  send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>());
+  if (sender_) {
+    send_payload_router_->SetSendingRtpModules(std::list<RtpRtcp*>());
+  } else {
+    module_process_thread_->DeRegisterModule(&vie_sync_);
+  }
   for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i)
     packet_router_->RemoveRtpModule(rtp_rtcp_modules_[i], sender_);
   for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) {
@@ -186,8 +193,6 @@
   }
   if (!sender_)
     StopDecodeThread();
-  // Release modules.
-  VideoCodingModule::Destroy(vcm_);
 }
 
 void ViEChannel::UpdateHistograms() {
@@ -441,15 +446,8 @@
   return 0;
 }
 
-uint32_t ViEChannel::DiscardedPackets() const {
-  return vcm_->DiscardedPackets();
-}
-
-int ViEChannel::ReceiveDelay() const {
-  return vcm_->Delay();
-}
-
 void ViEChannel::SetExpectedRenderDelay(int delay_ms) {
+  RTC_DCHECK(!sender_);
   vcm_->SetRenderDelay(delay_ms);
 }
 
@@ -483,7 +481,8 @@
     protection_method = kProtectionNone;
   }
 
-  vcm_->SetVideoProtection(protection_method, true);
+  if (!sender_)
+    vcm_->SetVideoProtection(protection_method, true);
 
   // Set NACK.
   ProcessNACKRequest(enable_nack);
@@ -506,19 +505,21 @@
     for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
       rtp_rtcp->SetStorePacketsStatus(true, nack_history_size_sender_);
 
-    vcm_->RegisterPacketRequestCallback(this);
-    // Don't introduce errors when NACK is enabled.
-    vcm_->SetDecodeErrorMode(kNoErrors);
+    if (!sender_) {
+      vcm_->RegisterPacketRequestCallback(this);
+      // Don't introduce errors when NACK is enabled.
+      vcm_->SetDecodeErrorMode(kNoErrors);
+    }
   } else {
-    vcm_->RegisterPacketRequestCallback(NULL);
-    if (paced_sender_ == nullptr) {
+    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);
     }
     vie_receiver_.SetNackStatus(false, max_nack_reordering_threshold_);
-    // 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);
   }
 }
 
@@ -880,15 +881,18 @@
 
   for (size_t i = 0; i < num_active_rtp_rtcp_modules_; ++i) {
     RtpRtcp* rtp_rtcp = rtp_rtcp_modules_[i];
-    rtp_rtcp->SetSendingMediaStatus(true);
+    // Only have senders send media.
+    rtp_rtcp->SetSendingMediaStatus(sender_);
     rtp_rtcp->SetSendingStatus(true);
   }
-  send_payload_router_->set_active(true);
+  if (sender_)
+    send_payload_router_->set_active(true);
   return 0;
 }
 
 int32_t ViEChannel::StopSend() {
-  send_payload_router_->set_active(false);
+  if (sender_)
+    send_payload_router_->set_active(false);
   for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_)
     rtp_rtcp->SetSendingMediaStatus(false);
 
@@ -940,10 +944,6 @@
   return rtp_rtcp_modules_[0];
 }
 
-rtc::scoped_refptr<PayloadRouter> ViEChannel::send_payload_router() {
-  return send_payload_router_;
-}
-
 VCMProtectionCallback* ViEChannel::vcm_protection_callback() {
   return vcm_protection_callback_.get();
 }
@@ -1038,12 +1038,14 @@
 }
 
 bool ViEChannel::ChannelDecodeProcess() {
+  RTC_DCHECK(!sender_);
   vcm_->Decode(kMaxDecodeWaitTimeMs);
   return true;
 }
 
 void ViEChannel::OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) {
-  vcm_->SetReceiveChannelParameters(max_rtt_ms);
+  if (!sender_)
+    vcm_->SetReceiveChannelParameters(max_rtt_ms);
 
   rtc::CritScope lock(&crit_);
   if (time_of_first_rtt_ms_ == -1)
@@ -1137,6 +1139,7 @@
 }
 
 void ViEChannel::StopDecodeThread() {
+  RTC_DCHECK(!sender_);
   vcm_->TriggerDecoderShutdown();
 
   decode_thread_.Stop();
@@ -1144,12 +1147,14 @@
 
 int32_t ViEChannel::SetVoiceChannel(int32_t ve_channel_id,
                                     VoEVideoSync* ve_sync_interface) {
+  RTC_DCHECK(!sender_);
   return vie_sync_.ConfigureSync(ve_channel_id, ve_sync_interface,
                                  rtp_rtcp_modules_[0],
                                  vie_receiver_.GetRtpReceiver());
 }
 
 int32_t ViEChannel::VoiceChannel() {
+  RTC_DCHECK(!sender_);
   return vie_sync_.VoiceChannel();
 }
 
@@ -1161,6 +1166,7 @@
 
 void ViEChannel::RegisterPreDecodeImageCallback(
     EncodedImageCallback* pre_decode_callback) {
+  RTC_DCHECK(!sender_);
   vcm_->RegisterPreDecodeImageCallback(pre_decode_callback);
 }
 
diff --git a/webrtc/video/vie_channel.h b/webrtc/video/vie_channel.h
index 9f5e1ff..3c00749 100644
--- a/webrtc/video/vie_channel.h
+++ b/webrtc/video/vie_channel.h
@@ -68,6 +68,8 @@
   ViEChannel(uint32_t number_of_cores,
              Transport* transport,
              ProcessThread* module_process_thread,
+             PayloadRouter* send_payload_router,
+             VideoCodingModule* vcm,
              RtcpIntraFrameObserver* intra_frame_observer,
              RtcpBandwidthObserver* bandwidth_observer,
              TransportFeedbackObserver* transport_feedback_observer,
@@ -89,11 +91,6 @@
   void RegisterExternalDecoder(const uint8_t pl_type, VideoDecoder* decoder);
   int32_t ReceiveCodecStatistics(uint32_t* num_key_frames,
                                  uint32_t* num_delta_frames);
-  uint32_t DiscardedPackets() const;
-
-  // Returns the estimated delay in milliseconds.
-  int ReceiveDelay() const;
-
   void SetExpectedRenderDelay(int delay_ms);
 
   void SetRTCPMode(const RtcpMode rtcp_mode);
@@ -214,7 +211,6 @@
 
   // Gets the modules used by the channel.
   RtpRtcp* rtp_rtcp();
-  rtc::scoped_refptr<PayloadRouter> send_payload_router();
   VCMProtectionCallback* vcm_protection_callback();
 
 
@@ -401,12 +397,12 @@
   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.
-  rtc::scoped_refptr<PayloadRouter> send_payload_router_;
   rtc::scoped_ptr<ViEChannelProtectionCallback> vcm_protection_callback_;
 
   VideoCodingModule* const vcm_;
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc
index a9b2abb..20cfaff 100644
--- a/webrtc/video/vie_encoder.cc
+++ b/webrtc/video/vie_encoder.cc
@@ -110,6 +110,7 @@
                        I420FrameCallback* pre_encode_callback,
                        OveruseFrameDetector* overuse_detector,
                        PacedSender* pacer,
+                       PayloadRouter* payload_router,
                        BitrateAllocator* bitrate_allocator)
     : number_of_cores_(number_of_cores),
       vp_(VideoProcessing::Create()),
@@ -117,11 +118,11 @@
       vcm_(VideoCodingModule::Create(Clock::GetRealTimeClock(),
                                      this,
                                      qm_callback_.get())),
-      send_payload_router_(NULL),
       stats_proxy_(stats_proxy),
       pre_encode_callback_(pre_encode_callback),
       overuse_detector_(overuse_detector),
       pacer_(pacer),
+      send_payload_router_(payload_router),
       bitrate_allocator_(bitrate_allocator),
       time_of_last_frame_activity_ms_(0),
       encoder_config_(),
@@ -138,6 +139,7 @@
       picture_id_rpsi_(0),
       video_suspended_(false) {
   bitrate_observer_.reset(new ViEBitrateObserver(this));
+  module_process_thread_->RegisterModule(vcm_.get());
 }
 
 bool ViEEncoder::Init() {
@@ -155,23 +157,14 @@
   return true;
 }
 
-void ViEEncoder::StartThreadsAndSetSharedMembers(
-    rtc::scoped_refptr<PayloadRouter> send_payload_router,
-    VCMProtectionCallback* vcm_protection_callback) {
-  RTC_DCHECK(send_payload_router_ == NULL);
-
-  send_payload_router_ = send_payload_router;
-  vcm_->RegisterProtectionCallback(vcm_protection_callback);
-  module_process_thread_->RegisterModule(vcm_.get());
-}
-
-void ViEEncoder::StopThreadsAndRemoveSharedMembers() {
-  if (bitrate_allocator_)
-    bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get());
-  module_process_thread_->DeRegisterModule(vcm_.get());
+VideoCodingModule* ViEEncoder::vcm() const {
+  return vcm_.get();
 }
 
 ViEEncoder::~ViEEncoder() {
+  module_process_thread_->DeRegisterModule(vcm_.get());
+  if (bitrate_allocator_)
+    bitrate_allocator_->RemoveBitrateObserver(bitrate_observer_.get());
 }
 
 void ViEEncoder::SetNetworkTransmissionState(bool is_transmitting) {
@@ -338,7 +331,6 @@
 }
 
 void ViEEncoder::DeliverFrame(VideoFrame video_frame) {
-  RTC_DCHECK(send_payload_router_ != NULL);
   if (!send_payload_router_->active()) {
     // We've paused or we have no channels attached, don't waste resources on
     // encoding.
diff --git a/webrtc/video/vie_encoder.h b/webrtc/video/vie_encoder.h
index b8944dc..22457ef 100644
--- a/webrtc/video/vie_encoder.h
+++ b/webrtc/video/vie_encoder.h
@@ -57,22 +57,13 @@
              I420FrameCallback* pre_encode_callback,
              OveruseFrameDetector* overuse_detector,
              PacedSender* pacer,
+             PayloadRouter* payload_router,
              BitrateAllocator* bitrate_allocator);
   ~ViEEncoder();
 
   bool Init();
 
-  // This function is assumed to be called before any frames are delivered and
-  // only once.
-  // Ideally this would be done in Init, but the dependencies between ViEEncoder
-  // and ViEChannel makes it really hard to do in a good way.
-  void StartThreadsAndSetSharedMembers(
-      rtc::scoped_refptr<PayloadRouter> send_payload_router,
-      VCMProtectionCallback* vcm_protection_callback);
-
-  // This function must be called before the corresponding ViEChannel is
-  // deleted.
-  void StopThreadsAndRemoveSharedMembers();
+  VideoCodingModule* vcm() const;
 
   void SetNetworkTransmissionState(bool is_transmitting);
 
@@ -158,7 +149,6 @@
   const rtc::scoped_ptr<VideoProcessing> vp_;
   const rtc::scoped_ptr<QMVideoSettingsCallback> qm_callback_;
   const rtc::scoped_ptr<VideoCodingModule> vcm_;
-  rtc::scoped_refptr<PayloadRouter> send_payload_router_;
 
   rtc::CriticalSection data_cs_;
   rtc::scoped_ptr<BitrateObserver> bitrate_observer_;
@@ -167,6 +157,7 @@
   I420FrameCallback* const pre_encode_callback_;
   OveruseFrameDetector* const overuse_detector_;
   PacedSender* const pacer_;
+  PayloadRouter* const send_payload_router_;
   BitrateAllocator* const bitrate_allocator_;
 
   // The time we last received an input frame or encoded frame. This is used to
diff --git a/webrtc/video/vie_receiver.cc b/webrtc/video/vie_receiver.cc
index a8719ed..d61eca4 100644
--- a/webrtc/video/vie_receiver.cc
+++ b/webrtc/video/vie_receiver.cc
@@ -232,6 +232,7 @@
 int32_t ViEReceiver::OnReceivedPayloadData(const uint8_t* payload_data,
                                            const size_t payload_size,
                                            const WebRtcRTPHeader* rtp_header) {
+  RTC_DCHECK(vcm_);
   WebRtcRTPHeader rtp_header_with_ntp = *rtp_header;
   rtp_header_with_ntp.ntp_time_ms =
       ntp_estimator_->Estimate(rtp_header->header.timestamp);