Remove ViE interface usage from VideoReceiveStream.

References channels and underlying objects directly instead of using
interfaces referenced with channel id. Channel creation is still done as
before for now.

BUG=1695
R=stefan@webrtc.org
TBR=mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/46849004

Cr-Commit-Position: refs/heads/master@{#8958}
diff --git a/talk/media/webrtc/fakewebrtcvideoengine.h b/talk/media/webrtc/fakewebrtcvideoengine.h
index 24a1cbb..f792456 100644
--- a/talk/media/webrtc/fakewebrtcvideoengine.h
+++ b/talk/media/webrtc/fakewebrtcvideoengine.h
@@ -699,6 +699,13 @@
     return 0;
   }
   WEBRTC_STUB(CreateChannelWithoutDefaultEncoder, (int&, int original_channel));
+  webrtc::ChannelGroup* GetChannelGroup(int channel_id) override {
+    return nullptr;
+  }
+  webrtc::ViEChannel* GetChannel(int channel_id) override { return nullptr; }
+  webrtc::ViEEncoder* GetEncoder(int channel_id) override { return nullptr; }
+  webrtc::ViERenderManager* GetRenderManager() override { return nullptr; }
+
   WEBRTC_FUNC(CreateReceiveChannel, (int& channel, int original_channel)) {
     return CreateChannel(channel, original_channel);
   }
diff --git a/webrtc/call.h b/webrtc/call.h
index f5b7fed..4319cc5 100644
--- a/webrtc/call.h
+++ b/webrtc/call.h
@@ -62,15 +62,12 @@
   };
   struct Config {
     explicit Config(newapi::Transport* send_transport)
-        : webrtc_config(NULL),
-          send_transport(send_transport),
+        : send_transport(send_transport),
           voice_engine(NULL),
           overuse_callback(NULL) {}
 
     static const int kDefaultStartBitrateBps;
 
-    webrtc::Config* webrtc_config;
-
     newapi::Transport* send_transport;
 
     // VoiceEngine used for audio/video synchronization for this Call.
@@ -108,9 +105,6 @@
 
   static Call* Create(const Call::Config& config);
 
-  static Call* Create(const Call::Config& config,
-                      const webrtc::Config& webrtc_config);
-
   virtual VideoSendStream* CreateVideoSendStream(
       const VideoSendStream::Config& config,
       const VideoEncoderConfig& encoder_config) = 0;
diff --git a/webrtc/video/call.cc b/webrtc/video/call.cc
index d9dc334..7c8b059 100644
--- a/webrtc/video/call.cc
+++ b/webrtc/video/call.cc
@@ -157,6 +157,7 @@
   ViEBase* base_;
   ViENetwork* network_;
   int base_channel_id_;
+  ChannelGroup* channel_group_;
 
   rtc::scoped_ptr<VideoRender> external_render_;
 
@@ -165,9 +166,7 @@
 }  // namespace internal
 
 Call* Call::Create(const Call::Config& config) {
-  VideoEngine* video_engine = config.webrtc_config != nullptr
-                                  ? VideoEngine::Create(*config.webrtc_config)
-                                  : VideoEngine::Create();
+  VideoEngine* video_engine = VideoEngine::Create();
   DCHECK(video_engine != nullptr);
 
   return new internal::Call(video_engine, config);
@@ -221,6 +220,7 @@
 
   base_->CreateChannel(base_channel_id_);
   DCHECK(base_channel_id_ != -1);
+  channel_group_ = base_->GetChannelGroup(base_channel_id_);
 
   network_->SetBitrateConfig(base_channel_id_,
                              config_.bitrate_config.min_bitrate_bps,
@@ -309,6 +309,7 @@
   LOG(LS_INFO) << "CreateVideoReceiveStream: " << config.ToString();
   VideoReceiveStream* receive_stream =
       new VideoReceiveStream(video_engine_,
+                             channel_group_,
                              config,
                              config_.send_transport,
                              config_.voice_engine,
diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc
index 126d485..a8dea5e 100644
--- a/webrtc/video/video_receive_stream.cc
+++ b/webrtc/video/video_receive_stream.cc
@@ -132,6 +132,7 @@
 }  // namespace
 
 VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
+                                       ChannelGroup* channel_group,
                                        const VideoReceiveStream::Config& config,
                                        newapi::Transport* transport,
                                        webrtc::VoiceEngine* voice_engine,
@@ -140,17 +141,19 @@
       encoded_frame_proxy_(config.pre_decode_callback),
       config_(config),
       clock_(Clock::GetRealTimeClock()),
+      channel_group_(channel_group),
+      voe_sync_interface_(nullptr),
       channel_(-1) {
   video_engine_base_ = ViEBase::GetInterface(video_engine);
   video_engine_base_->CreateReceiveChannel(channel_, base_channel);
   DCHECK(channel_ != -1);
 
-  rtp_rtcp_ = ViERTP_RTCP::GetInterface(video_engine);
-  DCHECK(rtp_rtcp_ != nullptr);
+  vie_channel_ = video_engine_base_->GetChannel(channel_);
+  vie_render_manager_ = video_engine_base_->GetRenderManager();
 
   // TODO(pbos): This is not fine grained enough...
-  rtp_rtcp_->SetNACKStatus(channel_, config_.rtp.nack.rtp_history_ms > 0);
-  rtp_rtcp_->SetKeyFrameRequestMethod(channel_, kViEKeyFrameRequestPliRtcp);
+  vie_channel_->SetNACKStatus(config_.rtp.nack.rtp_history_ms > 0);
+  vie_channel_->SetKeyFrameRequestMethod(kKeyFrameReqPliRtcp);
   SetRtcpMode(config_.rtp.rtcp_mode);
 
   DCHECK(config_.rtp.remote_ssrc != 0);
@@ -158,18 +161,20 @@
   DCHECK(config_.rtp.local_ssrc != 0);
   DCHECK(config_.rtp.remote_ssrc != config_.rtp.local_ssrc);
 
-  rtp_rtcp_->SetLocalSSRC(channel_, config_.rtp.local_ssrc);
+  vie_channel_->SetSSRC(config_.rtp.local_ssrc, kViEStreamTypeNormal, 0);
   // TODO(pbos): Support multiple RTX, per video payload.
   Config::Rtp::RtxMap::const_iterator it = config_.rtp.rtx.begin();
   if (it != config_.rtp.rtx.end()) {
     DCHECK(it->second.ssrc != 0);
     DCHECK(it->second.payload_type != 0);
 
-    rtp_rtcp_->SetRemoteSSRCType(channel_, kViEStreamTypeRtx, it->second.ssrc);
-    rtp_rtcp_->SetRtxReceivePayloadType(channel_, it->second.payload_type);
+    vie_channel_->SetRemoteSSRCType(kViEStreamTypeRtx, it->second.ssrc);
+    vie_channel_->SetRtxReceivePayloadType(it->second.payload_type);
   }
 
-  rtp_rtcp_->SetRembStatus(channel_, false, config_.rtp.remb);
+  // TODO(pbos): Remove channel_group_ usage from VideoReceiveStream. This
+  // should be configured in call.cc.
+  channel_group_->SetChannelRembStatus(false, config_.rtp.remb, vie_channel_);
 
   for (size_t i = 0; i < config_.rtp.extensions.size(); ++i) {
     const std::string& extension = config_.rtp.extensions[i].name;
@@ -178,24 +183,17 @@
     DCHECK_GE(id, 1);
     DCHECK_LE(id, 14);
     if (extension == RtpExtension::kTOffset) {
-      CHECK_EQ(0,
-               rtp_rtcp_->SetReceiveTimestampOffsetStatus(channel_, true, id));
+      CHECK_EQ(0, vie_channel_->SetReceiveTimestampOffsetStatus(true, id));
     } else if (extension == RtpExtension::kAbsSendTime) {
-      CHECK_EQ(0,
-               rtp_rtcp_->SetReceiveAbsoluteSendTimeStatus(channel_, true, id));
+      CHECK_EQ(0, vie_channel_->SetReceiveAbsoluteSendTimeStatus(true, id));
     } else if (extension == RtpExtension::kVideoRotation) {
-      CHECK_EQ(0, rtp_rtcp_->SetReceiveVideoRotationStatus(channel_, true, id));
+      CHECK_EQ(0, vie_channel_->SetReceiveVideoRotationStatus(true, id));
     } else {
       RTC_NOTREACHED() << "Unsupported RTP extension.";
     }
   }
 
-  network_ = ViENetwork::GetInterface(video_engine);
-  DCHECK(network_ != nullptr);
-
-  network_->RegisterSendTransport(channel_, transport_adapter_);
-
-  codec_ = ViECodec::GetInterface(video_engine);
+  vie_channel_->RegisterSendTransport(&transport_adapter_);
 
   if (config_.rtp.fec.ulpfec_payload_type != -1) {
     // ULPFEC without RED doesn't make sense.
@@ -205,7 +203,7 @@
     codec.codecType = kVideoCodecULPFEC;
     strcpy(codec.plName, "ulpfec");
     codec.plType = config_.rtp.fec.ulpfec_payload_type;
-    CHECK_EQ(0, codec_->SetReceiveCodec(channel_, codec));
+    CHECK_EQ(0, vie_channel_->SetReceiveCodec(codec));
   }
   if (config_.rtp.fec.red_payload_type != -1) {
     VideoCodec codec;
@@ -213,97 +211,86 @@
     codec.codecType = kVideoCodecRED;
     strcpy(codec.plName, "red");
     codec.plType = config_.rtp.fec.red_payload_type;
-    CHECK_EQ(0, codec_->SetReceiveCodec(channel_, codec));
+    CHECK_EQ(0, vie_channel_->SetReceiveCodec(codec));
   }
 
+  if (config.rtp.rtcp_xr.receiver_reference_time_report)
+    vie_channel_->SetRtcpXrRrtrStatus(true);
+
   stats_proxy_.reset(
       new ReceiveStatisticsProxy(config_.rtp.remote_ssrc, clock_));
 
-  CHECK_EQ(0, rtp_rtcp_->RegisterReceiveChannelRtcpStatisticsCallback(
-                  channel_, stats_proxy_.get()));
-  CHECK_EQ(0, rtp_rtcp_->RegisterReceiveChannelRtpStatisticsCallback(
-                  channel_, stats_proxy_.get()));
-  CHECK_EQ(0, rtp_rtcp_->RegisterRtcpPacketTypeCounterObserver(
-                  channel_, stats_proxy_.get()));
-  CHECK_EQ(0, codec_->RegisterDecoderObserver(channel_, *stats_proxy_));
+  vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(
+      stats_proxy_.get());
+  vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(stats_proxy_.get());
+  vie_channel_->RegisterRtcpPacketTypeCounterObserver(stats_proxy_.get());
+  vie_channel_->RegisterCodecObserver(stats_proxy_.get());
 
-  video_engine_base_->RegisterReceiveStatisticsProxy(channel_,
-                                                     stats_proxy_.get());
+  vie_channel_->RegisterReceiveStatisticsProxy(stats_proxy_.get());
 
-  external_codec_ = ViEExternalCodec::GetInterface(video_engine);
   DCHECK(!config_.decoders.empty());
   for (size_t i = 0; i < config_.decoders.size(); ++i) {
     const Decoder& decoder = config_.decoders[i];
-    CHECK_EQ(0, external_codec_->RegisterExternalReceiveCodec(
-                    channel_, decoder.payload_type, decoder.decoder,
-                    decoder.is_renderer, decoder.expected_delay_ms));
+    CHECK_EQ(0, vie_channel_->RegisterExternalDecoder(
+                    decoder.payload_type, decoder.decoder, decoder.is_renderer,
+                    decoder.expected_delay_ms));
 
     VideoCodec codec = CreateDecoderVideoCodec(decoder);
 
-    CHECK_EQ(0, codec_->SetReceiveCodec(channel_, codec));
+    CHECK_EQ(0, vie_channel_->SetReceiveCodec(codec));
   }
 
-  render_ = ViERender::GetInterface(video_engine);
-  DCHECK(render_ != nullptr);
-
-  render_->AddRenderer(channel_, kVideoI420, this);
+  // Register a renderer without a window handle, at depth 0, that covers the
+  // entire rendered area (0->1 both axes). This registers a renderer that
+  // renders the entire video.
+  vie_renderer_ = vie_render_manager_->AddRenderStream(channel_, nullptr, 0,
+                                                       0.0f, 0.0f, 1.0f, 1.0f);
+  vie_renderer_->SetExternalRenderer(channel_, kVideoI420, this);
+  vie_channel_->RegisterFrameCallback(channel_, vie_renderer_);
 
   if (voice_engine && config_.audio_channel_id != -1) {
-    video_engine_base_->SetVoiceEngine(voice_engine);
-    video_engine_base_->ConnectAudioChannel(channel_, config_.audio_channel_id);
+    voe_sync_interface_ = VoEVideoSync::GetInterface(voice_engine);
+    vie_channel_->SetVoiceChannel(config.audio_channel_id, voe_sync_interface_);
   }
 
-  image_process_ = ViEImageProcess::GetInterface(video_engine);
-  if (config.pre_decode_callback) {
-    image_process_->RegisterPreDecodeImageCallback(channel_,
-                                                   &encoded_frame_proxy_);
-  }
-  image_process_->RegisterPreRenderCallback(channel_, this);
-
-  if (config.rtp.rtcp_xr.receiver_reference_time_report) {
-    rtp_rtcp_->SetRtcpXrRrtrStatus(channel_, true);
-  }
+  if (config.pre_decode_callback)
+    vie_channel_->RegisterPreDecodeImageCallback(&encoded_frame_proxy_);
+  vie_channel_->RegisterPreRenderCallback(this);
 }
 
 VideoReceiveStream::~VideoReceiveStream() {
-  image_process_->DeRegisterPreRenderCallback(channel_);
-  image_process_->DeRegisterPreDecodeCallback(channel_);
+  vie_channel_->RegisterPreRenderCallback(nullptr);
+  vie_channel_->RegisterPreDecodeImageCallback(nullptr);
 
-  render_->RemoveRenderer(channel_);
+  vie_channel_->DeregisterFrameCallback(vie_renderer_);
+  vie_render_manager_->RemoveRenderStream(channel_);
 
-  for (size_t i = 0; i < config_.decoders.size(); ++i) {
-    external_codec_->DeRegisterExternalReceiveCodec(
-        channel_, config_.decoders[i].payload_type);
+  for (size_t i = 0; i < config_.decoders.size(); ++i)
+    vie_channel_->DeRegisterExternalDecoder(config_.decoders[i].payload_type);
+
+  vie_channel_->DeregisterSendTransport();
+
+  if (voe_sync_interface_ != nullptr) {
+    vie_channel_->SetVoiceChannel(-1, nullptr);
+    voe_sync_interface_->Release();
   }
-
-  network_->DeregisterSendTransport(channel_);
-
-  video_engine_base_->SetVoiceEngine(nullptr);
-  image_process_->Release();
-  external_codec_->Release();
-  codec_->DeregisterDecoderObserver(channel_);
-  rtp_rtcp_->DeregisterReceiveChannelRtpStatisticsCallback(channel_,
-                                                           stats_proxy_.get());
-  rtp_rtcp_->DeregisterReceiveChannelRtcpStatisticsCallback(channel_,
-                                                            stats_proxy_.get());
-  rtp_rtcp_->RegisterRtcpPacketTypeCounterObserver(channel_, nullptr);
-  codec_->Release();
-  network_->Release();
-  render_->Release();
-  rtp_rtcp_->Release();
+  vie_channel_->RegisterCodecObserver(nullptr);
+  vie_channel_->RegisterReceiveChannelRtpStatisticsCallback(nullptr);
+  vie_channel_->RegisterReceiveChannelRtcpStatisticsCallback(nullptr);
+  vie_channel_->RegisterRtcpPacketTypeCounterObserver(nullptr);
   video_engine_base_->DeleteChannel(channel_);
   video_engine_base_->Release();
 }
 
 void VideoReceiveStream::Start() {
   transport_adapter_.Enable();
-  CHECK_EQ(0, render_->StartRender(channel_));
-  CHECK_EQ(0, video_engine_base_->StartReceive(channel_));
+  vie_renderer_->StartRender();
+  vie_channel_->StartReceive();
 }
 
 void VideoReceiveStream::Stop() {
-  CHECK_EQ(0, render_->StopRender(channel_));
-  CHECK_EQ(0, video_engine_base_->StopReceive(channel_));
+  vie_renderer_->StopRender();
+  vie_channel_->StopReceive();
   transport_adapter_.Disable();
 }
 
@@ -312,12 +299,11 @@
 }
 
 bool VideoReceiveStream::DeliverRtcp(const uint8_t* packet, size_t length) {
-  return network_->ReceivedRTCPPacket(channel_, packet, length) == 0;
+  return vie_channel_->ReceivedRTCPPacket(packet, length) == 0;
 }
 
 bool VideoReceiveStream::DeliverRtp(const uint8_t* packet, size_t length) {
-  return network_->ReceivedRTPPacket(channel_, packet, length, PacketTime()) ==
-      0;
+  return vie_channel_->ReceivedRTPPacket(packet, length, PacketTime()) == 0;
 }
 
 void VideoReceiveStream::FrameCallback(I420VideoFrame* video_frame) {
@@ -364,18 +350,17 @@
 void VideoReceiveStream::SignalNetworkState(Call::NetworkState state) {
   if (state == Call::kNetworkUp)
     SetRtcpMode(config_.rtp.rtcp_mode);
-  network_->SetNetworkTransmissionState(channel_, state == Call::kNetworkUp);
   if (state == Call::kNetworkDown)
-    rtp_rtcp_->SetRTCPStatus(channel_, kRtcpNone);
+    vie_channel_->SetRTCPMode(kRtcpOff);
 }
 
 void VideoReceiveStream::SetRtcpMode(newapi::RtcpMode mode) {
   switch (mode) {
     case newapi::kRtcpCompound:
-      rtp_rtcp_->SetRTCPStatus(channel_, kRtcpCompound_RFC4585);
+      vie_channel_->SetRTCPMode(kRtcpCompound);
       break;
     case newapi::kRtcpReducedSize:
-      rtp_rtcp_->SetRTCPStatus(channel_, kRtcpNonCompound_RFC5506);
+      vie_channel_->SetRTCPMode(kRtcpNonCompound);
       break;
   }
 }
diff --git a/webrtc/video/video_receive_stream.h b/webrtc/video/video_receive_stream.h
index dcc8122..8e4a9e5 100644
--- a/webrtc/video/video_receive_stream.h
+++ b/webrtc/video/video_receive_stream.h
@@ -22,6 +22,11 @@
 #include "webrtc/video/receive_statistics_proxy.h"
 #include "webrtc/video/transport_adapter.h"
 #include "webrtc/video_engine/include/vie_render.h"
+#include "webrtc/video_engine/vie_channel.h"
+#include "webrtc/video_engine/vie_channel_group.h"
+#include "webrtc/video_engine/vie_encoder.h"
+#include "webrtc/video_engine/vie_render_manager.h"
+#include "webrtc/video_engine/vie_renderer.h"
 #include "webrtc/video_receive_stream.h"
 
 namespace webrtc {
@@ -43,6 +48,7 @@
                            public ExternalRenderer {
  public:
   VideoReceiveStream(webrtc::VideoEngine* video_engine,
+                     ChannelGroup* channel_group,
                      const VideoReceiveStream::Config& config,
                      newapi::Transport* transport,
                      webrtc::VoiceEngine* voice_engine,
@@ -82,13 +88,14 @@
   const VideoReceiveStream::Config config_;
   Clock* const clock_;
 
+  ChannelGroup* const channel_group_;
+  ViEChannel* vie_channel_;
+  ViERenderManager* vie_render_manager_;
+  ViERenderer* vie_renderer_;
+
   ViEBase* video_engine_base_;
-  ViECodec* codec_;
-  ViEExternalCodec* external_codec_;
-  ViENetwork* network_;
-  ViERender* render_;
-  ViERTP_RTCP* rtp_rtcp_;
-  ViEImageProcess* image_process_;
+
+  VoEVideoSync* voe_sync_interface_;
 
   rtc::scoped_ptr<ReceiveStatisticsProxy> stats_proxy_;
 
diff --git a/webrtc/video_engine/include/vie_base.h b/webrtc/video_engine/include/vie_base.h
index 7262ca2..55bc5f5 100644
--- a/webrtc/video_engine/include/vie_base.h
+++ b/webrtc/video_engine/include/vie_base.h
@@ -28,6 +28,14 @@
 class ReceiveStatisticsProxy;
 class SendStatisticsProxy;
 
+// Internal-class forward declarations, used to break out implementations for
+// the new video API to remove interface dependencies to the VideoEngine API
+// See webrtc:1695.
+class ChannelGroup;
+class ViEChannel;
+class ViEEncoder;
+class ViERenderManager;
+
 // CpuOveruseObserver is called when a system overuse is detected and
 // VideoEngine cannot keep up the encoding frequency.
 class CpuOveruseObserver {
@@ -190,6 +198,11 @@
   virtual int CreateChannelWithoutDefaultEncoder(int& video_channel,
                                                  int original_channel) = 0;
 
+  virtual ChannelGroup* GetChannelGroup(int channel_id) = 0;
+  virtual ViEChannel* GetChannel(int channel_id) = 0;
+  virtual ViEEncoder* GetEncoder(int channel_id) = 0;
+  virtual ViERenderManager* GetRenderManager() = 0;
+
   // Creates a new channel grouped together with |original_channel|. The channel
   // can only receive video and it is assumed the remote end-point is the same
   // as for |original_channel|.
diff --git a/webrtc/video_engine/vie_base_impl.cc b/webrtc/video_engine/vie_base_impl.cc
index ca7fd50..7d25172 100644
--- a/webrtc/video_engine/vie_base_impl.cc
+++ b/webrtc/video_engine/vie_base_impl.cc
@@ -13,6 +13,7 @@
 #include <string>
 #include <utility>
 
+#include "webrtc/base/checks.h"
 #include "webrtc/engine_configurations.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
@@ -195,6 +196,28 @@
   return CreateChannel(video_channel, original_channel, true, true);
 }
 
+ChannelGroup* ViEBaseImpl::GetChannelGroup(int channel_id) {
+  return shared_data_.channel_manager()->GetChannelGroup(channel_id);
+}
+
+ViEChannel* ViEBaseImpl::GetChannel(int channel_id) {
+  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(channel_id);
+  DCHECK(vie_channel);
+  return vie_channel;
+}
+
+ViEEncoder* ViEBaseImpl::GetEncoder(int channel_id) {
+  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
+  ViEEncoder* vie_encoder = cs.Encoder(channel_id);
+  DCHECK(vie_encoder);
+  return vie_encoder;
+}
+
+ViERenderManager* ViEBaseImpl::GetRenderManager() {
+  return shared_data_.render_manager();
+}
+
 int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
                                       int original_channel) {
   return CreateChannel(video_channel, original_channel, false, true);
diff --git a/webrtc/video_engine/vie_base_impl.h b/webrtc/video_engine/vie_base_impl.h
index 958e1c1..5df9490 100644
--- a/webrtc/video_engine/vie_base_impl.h
+++ b/webrtc/video_engine/vie_base_impl.h
@@ -50,6 +50,11 @@
   virtual int CreateChannelWithoutDefaultEncoder(int& video_channel,  // NOLINT
                                                  int original_channel);
 
+  ChannelGroup* GetChannelGroup(int channel_id) override;
+  ViEChannel* GetChannel(int channel_id) override;
+  ViEEncoder* GetEncoder(int channel_id) override;
+  ViERenderManager* GetRenderManager() override;
+
   virtual int CreateReceiveChannel(int& video_channel,  // NOLINT
                                    int original_channel);
   virtual int DeleteChannel(const int video_channel);
diff --git a/webrtc/video_engine/vie_channel_group.cc b/webrtc/video_engine/vie_channel_group.cc
index 3508d6a..f573ff1 100644
--- a/webrtc/video_engine/vie_channel_group.cc
+++ b/webrtc/video_engine/vie_channel_group.cc
@@ -285,7 +285,7 @@
   DCHECK(vie_encoder != NULL);
 
   call_stats_->DeregisterStatsObserver(vie_channel->GetStatsObserver());
-  SetChannelRembStatus(channel_id, false, false, vie_channel);
+  SetChannelRembStatus(false, false, vie_channel);
 
   // If we're owning the encoder, remove the feedback and stop all encoding
   // threads and processing. This must be done before deleting the channel.
@@ -446,8 +446,7 @@
   return pacer_->QueueInMs();
 }
 
-void ChannelGroup::SetChannelRembStatus(int channel_id,
-                                        bool sender,
+void ChannelGroup::SetChannelRembStatus(bool sender,
                                         bool receiver,
                                         ViEChannel* channel) {
   // Update the channel state.
diff --git a/webrtc/video_engine/vie_channel_group.h b/webrtc/video_engine/vie_channel_group.h
index 546da69..a20a541 100644
--- a/webrtc/video_engine/vie_channel_group.h
+++ b/webrtc/video_engine/vie_channel_group.h
@@ -64,10 +64,7 @@
 
   void SetSyncInterface(VoEVideoSync* sync_interface);
 
-  void SetChannelRembStatus(int channel_id,
-                            bool sender,
-                            bool receiver,
-                            ViEChannel* channel);
+  void SetChannelRembStatus(bool sender, bool receiver, ViEChannel* channel);
 
   BitrateController* GetBitrateController() const;
   CallStats* GetCallStats() const;
diff --git a/webrtc/video_engine/vie_channel_manager.cc b/webrtc/video_engine/vie_channel_manager.cc
index c06b7e3..3e091e1 100644
--- a/webrtc/video_engine/vie_channel_manager.cc
+++ b/webrtc/video_engine/vie_channel_manager.cc
@@ -12,6 +12,7 @@
 
 #include <vector>
 
+#include "webrtc/base/checks.h"
 #include "webrtc/common.h"
 #include "webrtc/engine_configurations.h"
 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
@@ -134,6 +135,13 @@
   return 0;
 }
 
+ChannelGroup* ViEChannelManager::GetChannelGroup(int channel_id) {
+  CriticalSectionScoped cs(channel_id_critsect_);
+  ChannelGroup* group = FindGroup(channel_id);
+  DCHECK(group);
+  return group;
+}
+
 int ViEChannelManager::DeleteChannel(int channel_id) {
   ChannelGroup* group = NULL;
   {
@@ -224,7 +232,7 @@
   ViEChannel* channel = ViEChannelPtr(channel_id);
   assert(channel);
 
-  group->SetChannelRembStatus(channel_id, sender, receiver, channel);
+  group->SetChannelRembStatus(sender, receiver, channel);
   return true;
 }
 
diff --git a/webrtc/video_engine/vie_channel_manager.h b/webrtc/video_engine/vie_channel_manager.h
index 1732d79..0fbbaf6 100644
--- a/webrtc/video_engine/vie_channel_manager.h
+++ b/webrtc/video_engine/vie_channel_manager.h
@@ -59,6 +59,8 @@
                     bool sender,
                     bool disable_default_encoder);
 
+  ChannelGroup* GetChannelGroup(int channel_id);
+
   // Deletes a channel.
   int DeleteChannel(int channel_id);