Update talk to 60923971

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5475 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/media/webrtc/webrtcvoiceengine.cc b/talk/media/webrtc/webrtcvoiceengine.cc
index b4b96d1..4ad2ff5 100644
--- a/talk/media/webrtc/webrtcvoiceengine.cc
+++ b/talk/media/webrtc/webrtcvoiceengine.cc
@@ -1639,17 +1639,68 @@
   return CreateVoiceChannel(voe_wrapper_sc_.get());
 }
 
-// This struct relies on the generated copy constructor and assignment operator
-// since it is used in an stl::map.
-struct WebRtcVoiceMediaChannel::WebRtcVoiceChannelInfo {
-  WebRtcVoiceChannelInfo() : channel(-1), renderer(NULL) {}
-  WebRtcVoiceChannelInfo(int ch, AudioRenderer* r)
-      : channel(ch),
-        renderer(r) {}
-  ~WebRtcVoiceChannelInfo() {}
+class WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer
+    : public AudioRenderer::Sink {
+ public:
+  WebRtcVoiceChannelRenderer(int ch,
+                             webrtc::AudioTransport* voe_audio_transport)
+      : channel_(ch),
+        voe_audio_transport_(voe_audio_transport),
+        renderer_(NULL) {
+  }
+  virtual ~WebRtcVoiceChannelRenderer() {
+    Stop();
+  }
 
-  int channel;
-  AudioRenderer* renderer;
+  // Starts the rendering by setting a sink to the renderer to get data
+  // callback.
+  // TODO(xians): Make sure Start() is called only once.
+  void Start(AudioRenderer* renderer) {
+    ASSERT(renderer != NULL);
+    if (renderer_) {
+      ASSERT(renderer_ == renderer);
+      return;
+    }
+
+    // TODO(xians): Remove AddChannel() call after Chrome turns on APM
+    // in getUserMedia by default.
+    renderer->AddChannel(channel_);
+    renderer->SetSink(this);
+    renderer_ = renderer;
+  }
+
+  // Stops rendering by setting the sink of the renderer to NULL. No data
+  // callback will be received after this method.
+  void Stop() {
+    if (!renderer_)
+      return;
+
+    renderer_->RemoveChannel(channel_);
+    renderer_->SetSink(NULL);
+    renderer_ = NULL;
+  }
+
+  // AudioRenderer::Sink implementation.
+  virtual void OnData(const void* audio_data,
+                      int bits_per_sample,
+                      int sample_rate,
+                      int number_of_channels,
+                      int number_of_frames) OVERRIDE {
+    // TODO(xians): Make new interface in AudioTransport to pass the data to
+    // WebRtc VoE channel.
+  }
+
+  // Accessor to the VoE channel ID.
+  int channel() const { return channel_; }
+
+ private:
+  const int channel_;
+  webrtc::AudioTransport* const voe_audio_transport_;
+
+  // Raw pointer to AudioRenderer owned by LocalAudioTrackHandler.
+  // PeerConnection will make sure invalidating the pointer before the object
+  // goes away.
+  AudioRenderer* renderer_;
 };
 
 // WebRtcVoiceMediaChannel
@@ -1841,8 +1892,8 @@
       for (ChannelMap::iterator it = receive_channels_.begin();
            it != receive_channels_.end() && ret; ++it) {
         if (engine()->voe()->codec()->SetRecPayloadType(
-                it->second.channel, voe_codec) == -1) {
-          LOG_RTCERR2(SetRecPayloadType, it->second.channel,
+                it->second->channel(), voe_codec) == -1) {
+          LOG_RTCERR2(SetRecPayloadType, it->second->channel(),
                       ToString(voe_codec));
           ret = false;
         }
@@ -2047,7 +2098,7 @@
   send_codecs_ = codecs;
   for (ChannelMap::iterator iter = send_channels_.begin();
        iter != send_channels_.end(); ++iter) {
-    if (!SetSendCodecs(iter->second.channel, codecs)) {
+    if (!SetSendCodecs(iter->second->channel(), codecs)) {
       return false;
     }
   }
@@ -2061,7 +2112,7 @@
                                       bool nack_enabled) {
   for (ChannelMap::const_iterator it = channels.begin();
        it != channels.end(); ++it) {
-    SetNack(it->second.channel, nack_enabled);
+    SetNack(it->second->channel(), nack_enabled);
   }
 }
 
@@ -2081,7 +2132,7 @@
                << ", bitrate=" << send_codec.rate;
   for (ChannelMap::iterator iter = send_channels_.begin();
        iter != send_channels_.end(); ++iter) {
-    if (!SetSendCodec(iter->second.channel, send_codec))
+    if (!SetSendCodec(iter->second->channel(), send_codec))
       return false;
   }
 
@@ -2132,9 +2183,9 @@
   for (ChannelMap::const_iterator iter = send_channels_.begin();
        iter != send_channels_.end(); ++iter) {
     if (engine()->voe()->rtp()->SetRTPAudioLevelIndicationStatus(
-            iter->second.channel, enable, id) == -1) {
+            iter->second->channel(), enable, id) == -1) {
       LOG_RTCERR3(SetRTPAudioLevelIndicationStatus,
-                  iter->second.channel, enable, id);
+                  iter->second->channel(), enable, id);
       return false;
     }
   }
@@ -2168,9 +2219,9 @@
   }
   for (ChannelMap::iterator it = receive_channels_.begin();
        it != receive_channels_.end() && result; ++it) {
-    if (!SetPlayout(it->second.channel, playout)) {
+    if (!SetPlayout(it->second->channel(), playout)) {
       LOG(LS_ERROR) << "SetPlayout " << playout << " on channel "
-                    << it->second.channel << " failed";
+                    << it->second->channel() << " failed";
       result = false;
     }
   }
@@ -2208,7 +2259,7 @@
   // Change the settings on each send channel.
   for (ChannelMap::iterator iter = send_channels_.begin();
        iter != send_channels_.end(); ++iter) {
-    if (!ChangeSend(iter->second.channel, send))
+    if (!ChangeSend(iter->second->channel(), send))
       return false;
   }
 
@@ -2280,7 +2331,7 @@
   bool default_channel_is_available = true;
   for (ChannelMap::const_iterator iter = send_channels_.begin();
        iter != send_channels_.end(); ++iter) {
-    if (IsDefaultChannel(iter->second.channel)) {
+    if (IsDefaultChannel(iter->second->channel())) {
       default_channel_is_available = false;
       break;
     }
@@ -2300,7 +2351,15 @@
 
   // Save the channel to send_channels_, so that RemoveSendStream() can still
   // delete the channel in case failure happens below.
-  send_channels_[sp.first_ssrc()] = WebRtcVoiceChannelInfo(channel, NULL);
+#ifdef USE_WEBRTC_DEV_BRANCH
+  webrtc::AudioTransport* audio_transport =
+      engine()->voe()->base()->audio_transport();
+#else
+  webrtc::AudioTransport* audio_transport = NULL;
+#endif
+  send_channels_.insert(std::make_pair(
+      sp.first_ssrc(),
+      new WebRtcVoiceChannelRenderer(channel, audio_transport)));
 
   // Set the send (local) SSRC.
   // If there are multiple send SSRCs, we can only set the first one here, and
@@ -2319,10 +2378,10 @@
     for (ChannelMap::const_iterator it = receive_channels_.begin();
          it != receive_channels_.end(); ++it) {
       // Only update the SSRC for non-default channels.
-      if (!IsDefaultChannel(it->second.channel)) {
-        if (engine()->voe()->rtp()->SetLocalSSRC(it->second.channel,
+      if (!IsDefaultChannel(it->second->channel())) {
+        if (engine()->voe()->rtp()->SetLocalSSRC(it->second->channel(),
                                                  sp.first_ssrc()) != 0) {
-          LOG_RTCERR2(SetLocalSSRC, it->second.channel, sp.first_ssrc());
+          LOG_RTCERR2(SetLocalSSRC, it->second->channel(), sp.first_ssrc());
           return false;
         }
       }
@@ -2349,12 +2408,13 @@
     return false;
   }
 
-  int channel = it->second.channel;
+  int channel = it->second->channel();
   ChangeSend(channel, SEND_NOTHING);
 
-  // Notify the audio renderer that the send channel is going away.
-  if (it->second.renderer)
-    it->second.renderer->RemoveChannel(channel);
+  // Delete the WebRtcVoiceChannelRenderer object connected to the channel,
+  // this will disconnect the audio renderer with the send channel.
+  delete it->second;
+  send_channels_.erase(it);
 
   if (IsDefaultChannel(channel)) {
     // Do not delete the default channel since the receive channels depend on
@@ -2368,7 +2428,6 @@
       return false;
   }
 
-  send_channels_.erase(it);
   if (send_channels_.empty())
     ChangeSend(SEND_NOTHING);
 
@@ -2394,12 +2453,19 @@
 
   // Reuse default channel for recv stream in non-conference mode call
   // when the default channel is not being used.
+#ifdef USE_WEBRTC_DEV_BRANCH
+  webrtc::AudioTransport* audio_transport =
+      engine()->voe()->base()->audio_transport();
+#else
+  webrtc::AudioTransport* audio_transport = NULL;
+#endif
   if (!InConferenceMode() && default_receive_ssrc_ == 0) {
     LOG(LS_INFO) << "Recv stream " << sp.first_ssrc()
                  << " reuse default channel";
     default_receive_ssrc_ = sp.first_ssrc();
     receive_channels_.insert(std::make_pair(
-        default_receive_ssrc_, WebRtcVoiceChannelInfo(voe_channel(), NULL)));
+        default_receive_ssrc_,
+        new WebRtcVoiceChannelRenderer(voe_channel(), audio_transport)));
     return SetPlayout(voe_channel(), playout_);
   }
 
@@ -2416,7 +2482,8 @@
   }
 
   receive_channels_.insert(
-      std::make_pair(ssrc, WebRtcVoiceChannelInfo(channel, NULL)));
+      std::make_pair(
+          ssrc, new WebRtcVoiceChannelRenderer(channel, audio_transport)));
 
   LOG(LS_INFO) << "New audio stream " << ssrc
                << " registered to VoiceEngine channel #"
@@ -2493,34 +2560,28 @@
     return false;
   }
 
+  // Delete the WebRtcVoiceChannelRenderer object connected to the channel, this
+  // will disconnect the audio renderer with the receive channel.
+  // Cache the channel before the deletion.
+  const int channel = it->second->channel();
+  delete it->second;
+  receive_channels_.erase(it);
+
   if (ssrc == default_receive_ssrc_) {
-    ASSERT(IsDefaultChannel(it->second.channel));
+    ASSERT(IsDefaultChannel(channel));
     // Recycle the default channel is for recv stream.
     if (playout_)
       SetPlayout(voe_channel(), false);
 
-    if (it->second.renderer)
-      it->second.renderer->RemoveChannel(voe_channel());
-
     default_receive_ssrc_ = 0;
-    receive_channels_.erase(it);
     return true;
   }
 
-  // Non default channel.
-  // Notify the renderer that channel is going away.
-  if (it->second.renderer)
-    it->second.renderer->RemoveChannel(it->second.channel);
-
   LOG(LS_INFO) << "Removing audio stream " << ssrc
-               << " with VoiceEngine channel #" << it->second.channel << ".";
-  if (!DeleteChannel(it->second.channel)) {
-    // Erase the entry anyhow.
-    receive_channels_.erase(it);
+               << " with VoiceEngine channel #" << channel << ".";
+  if (!DeleteChannel(channel))
     return false;
-  }
 
-  receive_channels_.erase(it);
   bool enable_default_channel_playout = false;
   if (receive_channels_.empty()) {
     // The last stream was removed. We can now enable the default
@@ -2558,19 +2619,11 @@
     return true;
   }
 
-  AudioRenderer* remote_renderer = it->second.renderer;
-  if (renderer) {
-    ASSERT(remote_renderer == NULL || remote_renderer == renderer);
-    if (!remote_renderer) {
-      renderer->AddChannel(it->second.channel);
-    }
-  } else if (remote_renderer) {
-    // |renderer| == NULL, remove the channel from the renderer.
-    remote_renderer->RemoveChannel(it->second.channel);
-  }
+  if (renderer)
+    it->second->Start(renderer);
+  else
+    it->second->Stop();
 
-  // Assign the new value to the struct.
-  it->second.renderer = renderer;
   return true;
 }
 
@@ -2588,17 +2641,11 @@
     return true;
   }
 
-  AudioRenderer* local_renderer = it->second.renderer;
-  if (renderer) {
-    ASSERT(local_renderer == NULL || local_renderer == renderer);
-    if (!local_renderer)
-      renderer->AddChannel(it->second.channel);
-  } else if (local_renderer) {
-    local_renderer->RemoveChannel(it->second.channel);
-  }
+  if (renderer)
+    it->second->Start(renderer);
+  else
+    it->second->Stop();
 
-  // Assign the new value to the struct.
-  it->second.renderer = renderer;
   return true;
 }
 
@@ -2609,7 +2656,7 @@
   actives->clear();
   for (ChannelMap::iterator it = receive_channels_.begin();
        it != receive_channels_.end(); ++it) {
-    int level = GetOutputLevel(it->second.channel);
+    int level = GetOutputLevel(it->second->channel());
     if (level > 0) {
       actives->push_back(std::make_pair(it->first, level));
     }
@@ -2622,7 +2669,7 @@
   int highest = GetOutputLevel(voe_channel());
   for (ChannelMap::iterator it = receive_channels_.begin();
        it != receive_channels_.end(); ++it) {
-    int level = GetOutputLevel(it->second.channel);
+    int level = GetOutputLevel(it->second->channel());
     highest = talk_base::_max(level, highest);
   }
   return highest;
@@ -2665,7 +2712,7 @@
       channels.push_back(voe_channel());
     for (ChannelMap::const_iterator it = receive_channels_.begin();
          it != receive_channels_.end(); ++it) {
-      channels.push_back(it->second.channel);
+      channels.push_back(it->second->channel());
     }
   } else {  // Collect only the channel of the specified ssrc.
     int channel = GetReceiveChannelNum(ssrc);
@@ -2801,7 +2848,7 @@
       bool default_channel_is_inuse = false;
       for (ChannelMap::const_iterator iter = send_channels_.begin();
            iter != send_channels_.end(); ++iter) {
-        if (IsDefaultChannel(iter->second.channel)) {
+        if (IsDefaultChannel(iter->second->channel())) {
           default_channel_is_inuse = true;
           break;
         }
@@ -2809,7 +2856,7 @@
       if (default_channel_is_inuse) {
         channel = voe_channel();
       } else if (!send_channels_.empty()) {
-        channel = send_channels_.begin()->second.channel;
+        channel = send_channels_.begin()->second->channel();
       }
     } else {
       channel = GetSendChannelNum(ssrc);
@@ -2907,11 +2954,12 @@
   for (ChannelMap::iterator iter = send_channels_.begin();
        iter != send_channels_.end(); ++iter) {
     // Make sure not sending the same packet to default channel more than once.
-    if (IsDefaultChannel(iter->second.channel) && has_sent_to_default_channel)
+    if (IsDefaultChannel(iter->second->channel()) &&
+        has_sent_to_default_channel)
       continue;
 
     engine()->voe()->network()->ReceivedRTCPPacket(
-        iter->second.channel,
+        iter->second->channel(),
         packet->data(),
         static_cast<unsigned int>(packet->length()));
   }
@@ -3022,7 +3070,7 @@
 
   for (ChannelMap::const_iterator channel_iter = send_channels_.begin();
        channel_iter != send_channels_.end(); ++channel_iter) {
-    const int channel = channel_iter->second.channel;
+    const int channel = channel_iter->second->channel();
 
     // Fill in the sender info, based on what we know, and what the
     // remote side told us it got from its RTCP report.
@@ -3094,7 +3142,7 @@
   std::vector<int> channels;
   for (ChannelMap::const_iterator it = receive_channels_.begin();
        it != receive_channels_.end(); ++it) {
-    channels.push_back(it->second.channel);
+    channels.push_back(it->second->channel());
   }
   if (channels.empty()) {
     channels.push_back(voe_channel());
@@ -3172,7 +3220,7 @@
     // Check whether this is a sending channel.
     for (ChannelMap::const_iterator it = send_channels_.begin();
          it != send_channels_.end(); ++it) {
-      if (it->second.channel == channel_num) {
+      if (it->second->channel() == channel_num) {
         // This is a sending channel.
         uint32 local_ssrc = 0;
         if (engine()->voe()->rtp()->GetLocalSSRC(
@@ -3186,7 +3234,7 @@
     // Check whether this is a receiving channel.
     for (ChannelMap::const_iterator it = receive_channels_.begin();
         it != receive_channels_.end(); ++it) {
-      if (it->second.channel == channel_num) {
+      if (it->second->channel() == channel_num) {
         *ssrc = it->first;
         return true;
       }
@@ -3214,14 +3262,14 @@
 int WebRtcVoiceMediaChannel::GetReceiveChannelNum(uint32 ssrc) {
   ChannelMap::iterator it = receive_channels_.find(ssrc);
   if (it != receive_channels_.end())
-    return it->second.channel;
+    return it->second->channel();
   return (ssrc == default_receive_ssrc_) ?  voe_channel() : -1;
 }
 
 int WebRtcVoiceMediaChannel::GetSendChannelNum(uint32 ssrc) {
   ChannelMap::iterator it = send_channels_.find(ssrc);
   if (it != send_channels_.end())
-    return it->second.channel;
+    return it->second->channel();
 
   return -1;
 }