Remove PayloadRouter dependency from ViEEncoder.

BUG=webrtc:5687

Review-Url: https://codereview.webrtc.org/1912653002
Cr-Commit-Position: refs/heads/master@{#12593}
diff --git a/webrtc/video/encoded_frame_callback_adapter.cc b/webrtc/video/encoded_frame_callback_adapter.cc
index 8428360..9741491 100644
--- a/webrtc/video/encoded_frame_callback_adapter.cc
+++ b/webrtc/video/encoded_frame_callback_adapter.cc
@@ -26,9 +26,11 @@
     const EncodedImage& encodedImage,
     const CodecSpecificInfo* codecSpecificInfo,
     const RTPFragmentationHeader* fragmentation) {
-  RTC_DCHECK(observer_);
+  if (!observer_)
+    return 0;
   const EncodedFrame frame(encodedImage._buffer, encodedImage._length,
                            encodedImage._frameType);
+
   observer_->EncodedFrameCallback(frame);
   return 0;
 }
diff --git a/webrtc/video/encoded_frame_callback_adapter.h b/webrtc/video/encoded_frame_callback_adapter.h
index fa82495..83fe4bd 100644
--- a/webrtc/video/encoded_frame_callback_adapter.h
+++ b/webrtc/video/encoded_frame_callback_adapter.h
@@ -27,7 +27,7 @@
                           const RTPFragmentationHeader* fragmentation);
 
  private:
-  EncodedFrameObserver* observer_;
+  EncodedFrameObserver* const observer_;
 };
 
 }  // namespace internal
diff --git a/webrtc/video/encoder_state_feedback_unittest.cc b/webrtc/video/encoder_state_feedback_unittest.cc
index 3b7ef29..fff5ca8 100644
--- a/webrtc/video/encoder_state_feedback_unittest.cc
+++ b/webrtc/video/encoder_state_feedback_unittest.cc
@@ -32,9 +32,7 @@
                    nullptr,
                    nullptr,
                    nullptr,
-                   pacer,
-                   nullptr,
-                   nullptr) {}
+                   pacer) {}
   ~MockVieEncoder() {}
 
   MOCK_METHOD1(OnReceivedIntraFrameRequest,
diff --git a/webrtc/video/payload_router.cc b/webrtc/video/payload_router.cc
index abe476f..3be5882 100644
--- a/webrtc/video/payload_router.cc
+++ b/webrtc/video/payload_router.cc
@@ -84,6 +84,7 @@
       return;
   }
 }
+
 }  // namespace
 
 PayloadRouter::PayloadRouter(const std::vector<RtpRtcp*>& rtp_modules,
@@ -115,10 +116,12 @@
   return active_ && !rtp_modules_.empty();
 }
 
-void PayloadRouter::SetSendingRtpModules(size_t num_sending_modules) {
-  RTC_DCHECK_LE(num_sending_modules, rtp_modules_.size());
+void PayloadRouter::SetSendStreams(const std::vector<VideoStream>& streams) {
+  RTC_DCHECK_LE(streams.size(), rtp_modules_.size());
   rtc::CritScope lock(&crit_);
-  num_sending_modules_ = num_sending_modules;
+  num_sending_modules_ = streams.size();
+  streams_ = streams;
+  // TODO(perkj): Should SetSendStreams also call SetTargetSendBitrate?
   UpdateModuleSendingState();
 }
 
@@ -163,12 +166,22 @@
       encoded_image._length, fragmentation, &rtp_video_header);
 }
 
-void PayloadRouter::SetTargetSendBitrates(
-    const std::vector<uint32_t>& stream_bitrates) {
+void PayloadRouter::SetTargetSendBitrate(uint32_t bitrate_bps) {
   rtc::CritScope lock(&crit_);
-  RTC_DCHECK_LE(stream_bitrates.size(), rtp_modules_.size());
-  for (size_t i = 0; i < stream_bitrates.size(); ++i) {
-    rtp_modules_[i]->SetTargetSendBitrate(stream_bitrates[i]);
+  RTC_DCHECK_LE(streams_.size(), rtp_modules_.size());
+
+  // TODO(sprang): Rebase https://codereview.webrtc.org/1913073002/ on top of
+  // this.
+  int bitrate_remainder = bitrate_bps;
+  for (size_t i = 0; i < streams_.size() && bitrate_remainder > 0; ++i) {
+    int stream_bitrate = 0;
+    if (streams_[i].max_bitrate_bps > bitrate_remainder) {
+      stream_bitrate = bitrate_remainder;
+    } else {
+      stream_bitrate = streams_[i].max_bitrate_bps;
+    }
+    bitrate_remainder -= stream_bitrate;
+    rtp_modules_[i]->SetTargetSendBitrate(stream_bitrate);
   }
 }
 
diff --git a/webrtc/video/payload_router.h b/webrtc/video/payload_router.h
index c2f4b04..ce65bae 100644
--- a/webrtc/video/payload_router.h
+++ b/webrtc/video/payload_router.h
@@ -17,6 +17,7 @@
 #include "webrtc/base/criticalsection.h"
 #include "webrtc/base/thread_annotations.h"
 #include "webrtc/common_types.h"
+#include "webrtc/config.h"
 #include "webrtc/video_encoder.h"
 #include "webrtc/system_wrappers/include/atomic32.h"
 
@@ -36,7 +37,7 @@
   ~PayloadRouter();
 
   static size_t DefaultMaxPayloadLength();
-  void SetSendingRtpModules(size_t num_sending_modules);
+  void SetSendStreams(const std::vector<VideoStream>& streams);
 
   // PayloadRouter will only route packets if being active, all packets will be
   // dropped otherwise.
@@ -49,9 +50,8 @@
                   const CodecSpecificInfo* codec_specific_info,
                   const RTPFragmentationHeader* fragmentation) override;
 
-  // Configures current target bitrate per module. 'stream_bitrates' is assumed
-  // to be in the same order as 'SetSendingRtpModules'.
-  void SetTargetSendBitrates(const std::vector<uint32_t>& stream_bitrates);
+  // Configures current target bitrate.
+  void SetTargetSendBitrate(uint32_t bitrate_bps);
 
   // Returns the maximum allowed data payload length, given the configured MTU
   // and RTP headers.
@@ -62,6 +62,7 @@
 
   rtc::CriticalSection crit_;
   bool active_ GUARDED_BY(crit_);
+  std::vector<VideoStream> streams_ GUARDED_BY(crit_);
   size_t num_sending_modules_ GUARDED_BY(crit_);
 
   // Rtp modules are assumed to be sorted in simulcast index order. Not owned.
diff --git a/webrtc/video/payload_router_unittest.cc b/webrtc/video/payload_router_unittest.cc
index 41e173b..5b66121 100644
--- a/webrtc/video/payload_router_unittest.cc
+++ b/webrtc/video/payload_router_unittest.cc
@@ -25,8 +25,9 @@
 namespace webrtc {
 
 TEST(PayloadRouterTest, SendOnOneModule) {
-  MockRtpRtcp rtp;
+  NiceMock<MockRtpRtcp> rtp;
   std::vector<RtpRtcp*> modules(1, &rtp);
+  std::vector<VideoStream> streams(1);
 
   uint8_t payload = 'a';
   int8_t payload_type = 96;
@@ -38,7 +39,7 @@
   encoded_image._length = 1;
 
   PayloadRouter payload_router(modules, payload_type);
-  payload_router.SetSendingRtpModules(modules.size());
+  payload_router.SetSendStreams(streams);
 
   EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
                                     encoded_image._timeStamp,
@@ -71,7 +72,8 @@
       .Times(1);
   EXPECT_EQ(0, payload_router.Encoded(encoded_image, nullptr, nullptr));
 
-  payload_router.SetSendingRtpModules(0);
+  streams.clear();
+  payload_router.SetSendStreams(streams);
   EXPECT_CALL(rtp, SendOutgoingData(encoded_image._frameType, payload_type,
                                     encoded_image._timeStamp,
                                     encoded_image.capture_time_ms_, &payload,
@@ -81,11 +83,12 @@
 }
 
 TEST(PayloadRouterTest, SendSimulcast) {
-  MockRtpRtcp rtp_1;
-  MockRtpRtcp rtp_2;
+  NiceMock<MockRtpRtcp> rtp_1;
+  NiceMock<MockRtpRtcp> rtp_2;
   std::vector<RtpRtcp*> modules;
   modules.push_back(&rtp_1);
   modules.push_back(&rtp_2);
+  std::vector<VideoStream> streams(2);
 
   int8_t payload_type = 96;
   uint8_t payload = 'a';
@@ -97,7 +100,7 @@
   encoded_image._length = 1;
 
   PayloadRouter payload_router(modules, payload_type);
-  payload_router.SetSendingRtpModules(modules.size());
+  payload_router.SetSendStreams(streams);
 
   CodecSpecificInfo codec_info_1;
   memset(&codec_info_1, 0, sizeof(CodecSpecificInfo));
@@ -138,7 +141,8 @@
   EXPECT_EQ(-1, payload_router.Encoded(encoded_image, &codec_info_2, nullptr));
 
   // Invalid simulcast index.
-  payload_router.SetSendingRtpModules(1);
+  streams.pop_back();  // Remove a stream.
+  payload_router.SetSendStreams(streams);
   payload_router.set_active(true);
   EXPECT_CALL(rtp_1, SendOutgoingData(_, _, _, _, _, _, _, _))
       .Times(0);
@@ -152,15 +156,16 @@
   // 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;
-  MockRtpRtcp rtp_1;
-  MockRtpRtcp rtp_2;
+  NiceMock<MockRtpRtcp> rtp_1;
+  NiceMock<MockRtpRtcp> rtp_2;
   std::vector<RtpRtcp*> modules;
   modules.push_back(&rtp_1);
   modules.push_back(&rtp_2);
   PayloadRouter payload_router(modules, 42);
 
   EXPECT_EQ(kDefaultMaxLength, PayloadRouter::DefaultMaxPayloadLength());
-  payload_router.SetSendingRtpModules(modules.size());
+  std::vector<VideoStream> streams(2);
+  payload_router.SetSendStreams(streams);
 
   // Modules return a higher length than the default value.
   EXPECT_CALL(rtp_1, MaxDataPayloadLength())
@@ -183,29 +188,23 @@
 }
 
 TEST(PayloadRouterTest, SetTargetSendBitrates) {
-  MockRtpRtcp rtp_1;
-  MockRtpRtcp rtp_2;
+  NiceMock<MockRtpRtcp> rtp_1;
+  NiceMock<MockRtpRtcp> rtp_2;
   std::vector<RtpRtcp*> modules;
   modules.push_back(&rtp_1);
   modules.push_back(&rtp_2);
   PayloadRouter payload_router(modules, 42);
-  payload_router.SetSendingRtpModules(modules.size());
+  std::vector<VideoStream> streams(2);
+  streams[0].max_bitrate_bps = 10000;
+  streams[1].max_bitrate_bps = 100000;
+  payload_router.SetSendStreams(streams);
 
   const uint32_t bitrate_1 = 10000;
   const uint32_t bitrate_2 = 76543;
-  std::vector<uint32_t> bitrates(2, bitrate_1);
-  bitrates[1] = bitrate_2;
   EXPECT_CALL(rtp_1, SetTargetSendBitrate(bitrate_1))
       .Times(1);
   EXPECT_CALL(rtp_2, SetTargetSendBitrate(bitrate_2))
       .Times(1);
-  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.SetTargetSendBitrate(bitrate_1 + bitrate_2);
 }
 }  // namespace webrtc
diff --git a/webrtc/video/video_send_stream.cc b/webrtc/video/video_send_stream.cc
index cecc7e9..9e38384 100644
--- a/webrtc/video/video_send_stream.cc
+++ b/webrtc/video/video_send_stream.cc
@@ -372,16 +372,13 @@
           this,
           config.post_encode_callback,
           &stats_proxy_),
-      vie_encoder_(
-          num_cpu_cores,
-          config_.rtp.ssrcs,
-          module_process_thread_,
-          &stats_proxy_,
-          config.pre_encode_callback,
-          &overuse_detector_,
-          congestion_controller_->pacer(),
-          &payload_router_,
-          config.post_encode_callback ? &encoded_frame_proxy_ : nullptr),
+      vie_encoder_(num_cpu_cores,
+                   config_.rtp.ssrcs,
+                   module_process_thread_,
+                   &stats_proxy_,
+                   config.pre_encode_callback,
+                   &overuse_detector_,
+                   congestion_controller_->pacer()),
       video_sender_(vie_encoder_.video_sender()),
       bandwidth_observer_(congestion_controller_->GetBitrateController()
                               ->CreateRtcpBandwidthObserver()),
@@ -516,18 +513,17 @@
   if (payload_router_.active())
     return;
   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Start");
-  vie_encoder_.Pause();
   payload_router_.set_active(true);
   // Was not already started, trigger a keyframe.
   vie_encoder_.SendKeyFrame();
-  vie_encoder_.Restart();
+  vie_encoder_.Start();
 }
 
 void VideoSendStream::Stop() {
   if (!payload_router_.active())
     return;
   TRACE_EVENT_INSTANT0("webrtc", "VideoSendStream::Stop");
-  // TODO(pbos): Make sure the encoder stops here.
+  vie_encoder_.Pause();
   payload_router_.set_active(false);
 }
 
@@ -565,8 +561,11 @@
               this, encoder_settings->video_codec.minBitrate * 1000,
               encoder_settings->video_codec.maxBitrate * 1000) /
           1000;
+
+      payload_router_.SetSendStreams(encoder_settings->streams);
       vie_encoder_.SetEncoder(encoder_settings->video_codec,
-                              encoder_settings->min_transmit_bitrate_bps);
+                              encoder_settings->min_transmit_bitrate_bps,
+                              payload_router_.MaxPayloadLength(), this);
       if (config_.suspend_below_min_bitrate) {
         video_sender_->SuspendBelowMinBitrate();
         bitrate_allocator_->EnforceMinBitrate(false);
@@ -596,7 +595,7 @@
   {
     rtc::CritScope lock(&encoder_settings_crit_);
     pending_encoder_settings_ = rtc::Optional<EncoderSettings>(
-        {video_codec, config.min_transmit_bitrate_bps});
+        {video_codec, config.min_transmit_bitrate_bps, config.streams});
   }
   encoder_wakeup_event_.Set();
 }
@@ -615,6 +614,16 @@
     config_.overuse_callback->OnLoadUpdate(LoadObserver::kUnderuse);
 }
 
+int32_t VideoSendStream::Encoded(const EncodedImage& encoded_image,
+                                 const CodecSpecificInfo* codec_specific_info,
+                                 const RTPFragmentationHeader* fragmentation) {
+  // |encoded_frame_proxy_| forwards frames to |config_.post_encode_callback|;
+  encoded_frame_proxy_.Encoded(encoded_image, codec_specific_info,
+                               fragmentation);
+  return payload_router_.Encoded(encoded_image, codec_specific_info,
+                                 fragmentation);
+}
+
 void VideoSendStream::ConfigureProtection() {
   // Enable NACK, FEC or both.
   const bool enable_protection_nack = config_.rtp.nack.rtp_history_ms > 0;
@@ -736,6 +745,7 @@
 void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
                                        uint8_t fraction_loss,
                                        int64_t rtt) {
+  payload_router_.SetTargetSendBitrate(bitrate_bps);
   vie_encoder_.OnBitrateUpdated(bitrate_bps, fraction_loss, rtt);
 }
 
diff --git a/webrtc/video/video_send_stream.h b/webrtc/video/video_send_stream.h
index fb16b67..ead1abf 100644
--- a/webrtc/video/video_send_stream.h
+++ b/webrtc/video/video_send_stream.h
@@ -49,7 +49,8 @@
 class VideoSendStream : public webrtc::VideoSendStream,
                         public webrtc::CpuOveruseObserver,
                         public webrtc::BitrateAllocatorObserver,
-                        public webrtc::VCMProtectionCallback {
+                        public webrtc::VCMProtectionCallback,
+                        protected webrtc::EncodedImageCallback {
  public:
   VideoSendStream(int num_cpu_cores,
                   ProcessThread* module_process_thread,
@@ -98,7 +99,16 @@
   struct EncoderSettings {
     VideoCodec video_codec;
     int min_transmit_bitrate_bps;
+    std::vector<VideoStream> streams;
   };
+
+  // Implements EncodedImageCallback. The implementation routes encoded frames
+  // to the |payload_router_| and |config.pre_encode_callback| if set.
+  // Called on an arbitrary encoder callback thread.
+  int32_t Encoded(const EncodedImage& encoded_image,
+                  const CodecSpecificInfo* codec_specific_info,
+                  const RTPFragmentationHeader* fragmentation) override;
+
   static bool EncoderThreadFunction(void* obj);
   void EncoderProcess();
 
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc
index b0f6272..89cbb52 100644
--- a/webrtc/video/vie_encoder.cc
+++ b/webrtc/video/vie_encoder.cc
@@ -38,28 +38,6 @@
 static const float kStopPaddingThresholdMs = 2000;
 static const int kMinKeyFrameRequestIntervalMs = 300;
 
-std::vector<uint32_t> AllocateStreamBitrates(
-    uint32_t total_bitrate,
-    const SimulcastStream* stream_configs,
-    size_t number_of_streams) {
-  if (number_of_streams == 0) {
-    std::vector<uint32_t> stream_bitrates(1, 0);
-    stream_bitrates[0] = total_bitrate;
-    return stream_bitrates;
-  }
-  std::vector<uint32_t> stream_bitrates(number_of_streams, 0);
-  uint32_t bitrate_remainder = total_bitrate;
-  for (size_t i = 0; i < stream_bitrates.size() && bitrate_remainder > 0; ++i) {
-    if (stream_configs[i].maxBitrate * 1000 > bitrate_remainder) {
-      stream_bitrates[i] = bitrate_remainder;
-    } else {
-      stream_bitrates[i] = stream_configs[i].maxBitrate * 1000;
-    }
-    bitrate_remainder -= stream_bitrates[i];
-  }
-  return stream_bitrates;
-}
-
 class QMVideoSettingsCallback : public VCMQMSettingsCallback {
  public:
   explicit QMVideoSettingsCallback(VideoProcessing* vpm);
@@ -81,9 +59,7 @@
                        SendStatisticsProxy* stats_proxy,
                        rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
                        OveruseFrameDetector* overuse_detector,
-                       PacedSender* pacer,
-                       PayloadRouter* payload_router,
-                       EncodedImageCallback* post_encode_callback)
+                       PacedSender* pacer)
     : number_of_cores_(number_of_cores),
       ssrcs_(ssrcs),
       vp_(VideoProcessing::Create()),
@@ -93,14 +69,12 @@
       pre_encode_callback_(pre_encode_callback),
       overuse_detector_(overuse_detector),
       pacer_(pacer),
-      send_payload_router_(payload_router),
-      post_encode_callback_(post_encode_callback),
       time_of_last_frame_activity_ms_(0),
       encoder_config_(),
       min_transmit_bitrate_bps_(0),
       last_observed_bitrate_bps_(0),
       network_is_transmitting_(true),
-      encoder_paused_(false),
+      encoder_paused_(true),
       encoder_paused_and_dropped_frame_(false),
       time_last_intra_request_ms_(ssrcs.size(), -1),
       module_process_thread_(module_process_thread),
@@ -149,7 +123,7 @@
   encoder_paused_ = true;
 }
 
-void ViEEncoder::Restart() {
+void ViEEncoder::Start() {
   rtc::CritScope lock(&data_cs_);
   encoder_paused_ = false;
 }
@@ -166,8 +140,9 @@
   return 0;
 }
 void ViEEncoder::SetEncoder(const webrtc::VideoCodec& video_codec,
-                            int min_transmit_bitrate_bps) {
-  RTC_DCHECK(send_payload_router_);
+                            int min_transmit_bitrate_bps,
+                            size_t max_data_payload_length,
+                            EncodedImageCallback* sink) {
   // Setting target width and height for VPM.
   RTC_CHECK_EQ(VPM_OK,
                vp_->SetTargetResolution(video_codec.width, video_codec.height,
@@ -178,11 +153,13 @@
   {
     rtc::CritScope lock(&data_cs_);
     encoder_config_ = video_codec;
-    encoder_paused_ = true;
     min_transmit_bitrate_bps_ = min_transmit_bitrate_bps;
   }
+  {
+    rtc::CritScope lock(&sink_cs_);
+    sink_ = sink;
+  }
 
-  size_t max_data_payload_length = send_payload_router_->MaxPayloadLength();
   bool success = video_sender_.RegisterSendCodec(
                      &video_codec, number_of_cores_,
                      static_cast<uint32_t>(max_data_payload_length)) == VCM_OK;
@@ -191,11 +168,6 @@
     RTC_DCHECK(success);
   }
 
-  send_payload_router_->SetSendingRtpModules(
-      video_codec.numberOfSimulcastStreams);
-
-  // Restart the media flow
-  Restart();
   if (stats_proxy_) {
     // Clear stats for disabled layers.
     for (size_t i = video_codec.numberOfSimulcastStreams; i < ssrcs_.size();
@@ -307,11 +279,6 @@
 }
 
 void ViEEncoder::EncodeVideoFrame(const VideoFrame& video_frame) {
-  if (!send_payload_router_->active()) {
-    // We've paused or we have no channels attached, don't waste resources on
-    // encoding.
-    return;
-  }
   VideoCodecType codec_type;
   {
     rtc::CritScope lock(&data_cs_);
@@ -394,25 +361,21 @@
 int32_t ViEEncoder::Encoded(const EncodedImage& encoded_image,
                             const CodecSpecificInfo* codec_specific_info,
                             const RTPFragmentationHeader* fragmentation) {
-  RTC_DCHECK(send_payload_router_);
-
   {
     rtc::CritScope lock(&data_cs_);
     time_of_last_frame_activity_ms_ = TickTime::MillisecondTimestamp();
   }
-
-  if (post_encode_callback_) {
-    post_encode_callback_->Encoded(encoded_image, codec_specific_info,
-                                   fragmentation);
-  }
-
   if (stats_proxy_) {
     stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info);
   }
-  int success = send_payload_router_->Encoded(
-      encoded_image, codec_specific_info, fragmentation);
-  overuse_detector_->FrameSent(encoded_image._timeStamp);
 
+  int success = 0;
+  {
+    rtc::CritScope lock(&sink_cs_);
+    success = sink_->Encoded(encoded_image, codec_specific_info, fragmentation);
+  }
+
+  overuse_detector_->FrameSent(encoded_image._timeStamp);
   if (kEnableFrameRecording) {
     int layer = codec_specific_info->codecType == kVideoCodecVP8
                     ? codec_specific_info->codecSpecific.VP8.simulcastIdx
@@ -489,26 +452,17 @@
   LOG(LS_VERBOSE) << "OnBitrateUpdated, bitrate" << bitrate_bps
                   << " packet loss " << static_cast<int>(fraction_lost)
                   << " rtt " << round_trip_time_ms;
-  RTC_DCHECK(send_payload_router_);
   video_sender_.SetChannelParameters(bitrate_bps, fraction_lost,
                                      round_trip_time_ms);
   bool video_is_suspended = video_sender_.VideoSuspended();
   bool video_suspension_changed;
-  VideoCodec send_codec;
   {
     rtc::CritScope lock(&data_cs_);
     last_observed_bitrate_bps_ = bitrate_bps;
     video_suspension_changed = video_suspended_ != video_is_suspended;
     video_suspended_ = video_is_suspended;
-    send_codec = encoder_config_;
   }
 
-  SimulcastStream* stream_configs = send_codec.simulcastStream;
-  // Allocate the bandwidth between the streams.
-  std::vector<uint32_t> stream_bitrates = AllocateStreamBitrates(
-      bitrate_bps, stream_configs, send_codec.numberOfSimulcastStreams);
-  send_payload_router_->SetTargetSendBitrates(stream_bitrates);
-
   if (!video_suspension_changed)
     return;
   // Video suspend-state changed, inform codec observer.
diff --git a/webrtc/video/vie_encoder.h b/webrtc/video/vie_encoder.h
index d3ac0f9..3d05a15 100644
--- a/webrtc/video/vie_encoder.h
+++ b/webrtc/video/vie_encoder.h
@@ -33,7 +33,6 @@
 class EncodedImageCallback;
 class OveruseFrameDetector;
 class PacedSender;
-class PayloadRouter;
 class ProcessThread;
 class QMVideoSettingsCallback;
 class SendStatisticsProxy;
@@ -41,6 +40,16 @@
 class ViEEffectFilter;
 class VideoEncoder;
 
+// VieEncoder represent a video encoder that accepts raw video frames as input
+// and produces an encoded bit stream.
+// Usage:
+// 1. Instantiate
+// 2. Call Init
+// 3. Call RegisterExternalEncoder if available.
+// 4. Call SetEncoder with the codec settings and the object that shall receive
+//    the encoded bit stream.
+// 5. Call Start.
+// 6. For each available raw video frame call EncodeVideoFrame.
 class ViEEncoder : public VideoEncoderRateObserver,
                    public EncodedImageCallback,
                    public VCMPacketizationCallback,
@@ -55,9 +64,7 @@
              // TODO(nisse): Used only for tests, delete?
              rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
              OveruseFrameDetector* overuse_detector,
-             PacedSender* pacer,
-             PayloadRouter* payload_router,
-             EncodedImageCallback* post_encode_callback);
+             PacedSender* pacer);
   ~ViEEncoder();
 
   bool Init();
@@ -69,16 +76,19 @@
   // Returns the id of the owning channel.
   int Owner() const;
 
+  void Start();
   // Drops incoming packets before they get to the encoder.
   void Pause();
-  void Restart();
 
   // Codec settings.
   int32_t RegisterExternalEncoder(VideoEncoder* encoder,
                                   uint8_t pl_type,
                                   bool internal_source);
   int32_t DeRegisterExternalEncoder(uint8_t pl_type);
-  void SetEncoder(const VideoCodec& video_codec, int min_transmit_bitrate_bps);
+  void SetEncoder(const VideoCodec& video_codec,
+                  int min_transmit_bitrate_bps,
+                  size_t max_data_payload_length,
+                  EncodedImageCallback* sink);
 
   void EncodeVideoFrame(const VideoFrame& video_frame);
   void SendKeyFrame();
@@ -136,8 +146,6 @@
   rtc::VideoSinkInterface<VideoFrame>* const pre_encode_callback_;
   OveruseFrameDetector* const overuse_detector_;
   PacedSender* const pacer_;
-  PayloadRouter* const send_payload_router_;
-  EncodedImageCallback* const post_encode_callback_;
 
   // The time we last received an input frame or encoded frame. This is used to
   // track when video is stopped long enough that we also want to stop sending
@@ -151,6 +159,9 @@
   bool encoder_paused_and_dropped_frame_ GUARDED_BY(data_cs_);
   std::vector<int64_t> time_last_intra_request_ms_ GUARDED_BY(data_cs_);
 
+  rtc::CriticalSection sink_cs_;
+  EncodedImageCallback* sink_ GUARDED_BY(sink_cs_);
+
   ProcessThread* module_process_thread_;
 
   bool has_received_sli_ GUARDED_BY(data_cs_);