Hook up libjingle WebRtcVoiceEngine to Call API for combined A/V BWE.

BUG=4574,3109
R=pbos@webrtc.org, tommi@webrtc.org

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

Cr-Commit-Position: refs/heads/master@{#9150}
diff --git a/talk/session/media/channel.h b/talk/session/media/channel.h
index 14dae3b..441fe64 100644
--- a/talk/session/media/channel.h
+++ b/talk/session/media/channel.h
@@ -526,6 +526,11 @@
   ~VideoChannel();
   bool Init();
 
+  // downcasts a MediaChannel
+  virtual VideoMediaChannel* media_channel() const {
+    return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
+  }
+
   bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
   bool ApplyViewRequest(const ViewRequest& request);
 
@@ -559,12 +564,6 @@
   // Configuration and setting.
   bool SetChannelOptions(const VideoOptions& options);
 
- protected:
-  // downcasts a MediaChannel
-  virtual VideoMediaChannel* media_channel() const {
-    return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
-  }
-
  private:
   typedef std::map<uint32, VideoCapturer*> ScreencastMap;
   struct ScreencastDetailsData;
diff --git a/talk/session/media/channelmanager.cc b/talk/session/media/channelmanager.cc
index 9c30a97..5013fc4 100644
--- a/talk/session/media/channelmanager.cc
+++ b/talk/session/media/channelmanager.cc
@@ -309,7 +309,7 @@
     DestroyVideoChannel_w(video_channels_.back());
   }
   while (!voice_channels_.empty()) {
-    DestroyVoiceChannel_w(voice_channels_.back());
+    DestroyVoiceChannel_w(voice_channels_.back(), nullptr);
   }
   while (!soundclips_.empty()) {
     DestroySoundclip_w(soundclips_.back());
@@ -329,8 +329,8 @@
 
 VoiceChannel* ChannelManager::CreateVoiceChannel_w(
     BaseSession* session, const std::string& content_name, bool rtcp) {
-  // This is ok to alloc from a thread other than the worker thread
   ASSERT(initialized_);
+  ASSERT(worker_thread_ == rtc::Thread::Current());
   VoiceMediaChannel* media_channel = media_engine_->CreateChannel();
   if (media_channel == NULL)
     return NULL;
@@ -346,22 +346,29 @@
   return voice_channel;
 }
 
-void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel) {
+void ChannelManager::DestroyVoiceChannel(VoiceChannel* voice_channel,
+                                         VideoChannel* video_channel) {
   if (voice_channel) {
     worker_thread_->Invoke<void>(
-        Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel));
+        Bind(&ChannelManager::DestroyVoiceChannel_w, this, voice_channel,
+             video_channel));
   }
 }
 
-void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
+void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel,
+                                           VideoChannel* video_channel) {
   // Destroy voice channel.
   ASSERT(initialized_);
+  ASSERT(worker_thread_ == rtc::Thread::Current());
   VoiceChannels::iterator it = std::find(voice_channels_.begin(),
       voice_channels_.end(), voice_channel);
   ASSERT(it != voice_channels_.end());
   if (it == voice_channels_.end())
     return;
 
+  if (video_channel) {
+    video_channel->media_channel()->DetachVoiceChannel();
+  }
   voice_channels_.erase(it);
   delete voice_channel;
 }
@@ -403,8 +410,8 @@
     bool rtcp,
     const VideoOptions& options,
     VoiceChannel* voice_channel) {
-  // This is ok to alloc from a thread other than the worker thread
   ASSERT(initialized_);
+  ASSERT(worker_thread_ == rtc::Thread::Current());
   VideoMediaChannel* media_channel =
       // voice_channel can be NULL in case of NullVoiceEngine.
       media_engine_->CreateVideoChannel(
@@ -433,6 +440,7 @@
 void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
   // Destroy video channel.
   ASSERT(initialized_);
+  ASSERT(worker_thread_ == rtc::Thread::Current());
   VideoChannels::iterator it = std::find(video_channels_.begin(),
       video_channels_.end(), video_channel);
   ASSERT(it != video_channels_.end());
diff --git a/talk/session/media/channelmanager.h b/talk/session/media/channelmanager.h
index a8eb88d..27f874b 100644
--- a/talk/session/media/channelmanager.h
+++ b/talk/session/media/channelmanager.h
@@ -107,7 +107,8 @@
   VoiceChannel* CreateVoiceChannel(
       BaseSession* session, const std::string& content_name, bool rtcp);
   // Destroys a voice channel created with the Create API.
-  void DestroyVoiceChannel(VoiceChannel* voice_channel);
+  void DestroyVoiceChannel(VoiceChannel* voice_channel,
+                           VideoChannel* video_channel);
   // TODO(pbos): Remove as soon as all call sites specify VideoOptions.
   VideoChannel* CreateVideoChannel(BaseSession* session,
                                    const std::string& content_name,
@@ -264,7 +265,8 @@
   void Terminate_w();
   VoiceChannel* CreateVoiceChannel_w(
       BaseSession* session, const std::string& content_name, bool rtcp);
-  void DestroyVoiceChannel_w(VoiceChannel* voice_channel);
+  void DestroyVoiceChannel_w(VoiceChannel* voice_channel,
+                             VideoChannel* video_channel);
   VideoChannel* CreateVideoChannel_w(BaseSession* session,
                                      const std::string& content_name,
                                      bool rtcp,
diff --git a/talk/session/media/channelmanager_unittest.cc b/talk/session/media/channelmanager_unittest.cc
index e57305c..b0abf04 100644
--- a/talk/session/media/channelmanager_unittest.cc
+++ b/talk/session/media/channelmanager_unittest.cc
@@ -135,7 +135,7 @@
                              false, cricket::DCT_RTP);
   EXPECT_TRUE(data_channel != NULL);
   cm_->DestroyVideoChannel(video_channel);
-  cm_->DestroyVoiceChannel(voice_channel);
+  cm_->DestroyVoiceChannel(voice_channel, nullptr);
   cm_->DestroyDataChannel(data_channel);
   cm_->Terminate();
 }
@@ -158,7 +158,7 @@
                              false, cricket::DCT_RTP);
   EXPECT_TRUE(data_channel != NULL);
   cm_->DestroyVideoChannel(video_channel);
-  cm_->DestroyVoiceChannel(voice_channel);
+  cm_->DestroyVoiceChannel(voice_channel, nullptr);
   cm_->DestroyDataChannel(data_channel);
   cm_->Terminate();
 }