| Index: content/renderer/media/media_stream_impl.cc | 
| diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc | 
| index 95ad1a5d486784ee05c322a92a11afd47f4a4837..f55172ed8dc8810dc7e9ae185c0976e34552bb3e 100644 | 
| --- a/content/renderer/media/media_stream_impl.cc | 
| +++ b/content/renderer/media/media_stream_impl.cc | 
| @@ -20,7 +20,9 @@ | 
| #include "content/renderer/media/rtc_video_renderer.h" | 
| #include "content/renderer/media/video_capture_impl_manager.h" | 
| #include "content/renderer/media/webrtc_uma_histograms.h" | 
| +#include "content/renderer/media/webrtc_audio_renderer.h" | 
| #include "media/base/message_loop_factory.h" | 
| +#include "media/base/rtc_audio_renderer.h" | 
| #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaConstraints.h" | 
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 
| @@ -262,6 +264,40 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( | 
| return NULL; | 
| } | 
|  | 
| +scoped_refptr<media::RtcAudioRenderer> MediaStreamImpl::GetAudioRenderer( | 
| +    const GURL& url) { | 
| +  DCHECK(CalledOnValidThread()); | 
| +  WebKit::WebMediaStreamDescriptor descriptor(GetMediaStream(url)); | 
| + | 
| +  if (descriptor.isNull() || !descriptor.extraData()) | 
| +    return NULL;  // This is not a valid stream. | 
| + | 
| +  DVLOG(1) << "MediaStreamImpl::GetAudioRenderer stream:" | 
| +           << UTF16ToUTF8(descriptor.label()); | 
| + | 
| +  MediaStreamExtraData* extra_data = | 
| +      static_cast<MediaStreamExtraData*>(descriptor.extraData()); | 
| +  if (extra_data->remote_stream()) { | 
| +    scoped_refptr<WebRtcAudioRenderer> renderer = | 
| +        CreateRemoteAudioRenderer(extra_data->remote_stream()); | 
| + | 
| +    if (dependency_factory_->GetWebRtcAudioDevice()->SetRenderer(renderer)) { | 
| +      return renderer; | 
| +    } else { | 
| +      // WebRtcAudioDeviceImpl can only support one renderer. | 
| +      return NULL; | 
| +    } | 
| +  } | 
| + | 
| +  if (extra_data->local_stream()) { | 
| +    // TODO(xians): Implement a WebRtcAudioFIFO to handle the local loopback. | 
| +    return NULL; | 
| +  } | 
| + | 
| +  NOTREACHED(); | 
| +  return NULL; | 
| +} | 
| + | 
| // Callback from MediaStreamDispatcher. | 
| // The requested stream have been generated. | 
| void MediaStreamImpl::OnStreamGenerated( | 
| @@ -472,6 +508,17 @@ scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateRemoteVideoDecoder( | 
| stream->video_tracks()->at(0)); | 
| } | 
|  | 
| +scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer( | 
| +    webrtc::MediaStreamInterface* stream) { | 
| +  if (!stream->audio_tracks() || stream->audio_tracks()->count() == 0) | 
| +    return NULL; | 
| + | 
| +  DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:" | 
| +           << stream->label(); | 
| + | 
| +  return new WebRtcAudioRenderer(); | 
| +} | 
| + | 
| MediaStreamExtraData::MediaStreamExtraData( | 
| webrtc::MediaStreamInterface* remote_stream) | 
| : remote_stream_(remote_stream) { | 
|  |