10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
20529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
30529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// found in the LICENSE file.
40529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
60529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/logging.h"
80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/renderer/media/media_stream_audio_source.h"
90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/renderer/media/media_stream_track.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "third_party/WebKit/public/platform/WebString.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace content {
160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
170529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochWebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter(
180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const blink::WebMediaStream& web_stream,
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PeerConnectionDependencyFactory* factory)
200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : web_stream_(web_stream),
210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      factory_(factory) {
220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  webrtc_media_stream_ =
230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      factory_->CreateLocalMediaStream(web_stream.id().utf8());
240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  web_stream_.audioTracks(audio_tracks);
270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < audio_tracks.size(); ++i)
280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CreateAudioTrack(audio_tracks[i]);
290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  web_stream_.videoTracks(video_tracks);
320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (size_t i = 0; i < video_tracks.size(); ++i)
330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CreateVideoTrack(video_tracks[i]);
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  native_stream->AddObserver(this);
370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
390529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochWebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() {
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  native_stream->RemoveObserver(this);
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebRtcMediaStreamAdapter::TrackAdded(
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const blink::WebMediaStreamTrack& track) {
460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (track.source().type() == blink::WebMediaStreamSource::TypeAudio) {
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CreateAudioTrack(track);
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CreateVideoTrack(track);
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebRtcMediaStreamAdapter::TrackRemoved(
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const blink::WebMediaStreamTrack& track) {
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const std::string track_id = track.id().utf8();
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (track.source().type() == blink::WebMediaStreamSource::TypeAudio) {
570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    webrtc_media_stream_->RemoveTrack(
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        webrtc_media_stream_->FindAudioTrack(track_id));
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK_EQ(track.source().type(), blink::WebMediaStreamSource::TypeVideo);
610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        webrtc_media_stream_->FindVideoTrack(track_id).get();
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    webrtc_media_stream_->RemoveTrack(webrtc_track.get());
640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    for (ScopedVector<WebRtcVideoTrackAdapter>::iterator it =
660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch             video_adapters_.begin(); it != video_adapters_.end(); ++it) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if ((*it)->webrtc_video_track() == webrtc_track.get()) {
680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        video_adapters_.erase(it);
690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        break;
700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      }
710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebRtcMediaStreamAdapter::CreateAudioTrack(
760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const blink::WebMediaStreamTrack& track) {
770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_EQ(track.source().type(), blink::WebMediaStreamSource::TypeAudio);
780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // A media stream is connected to a peer connection, enable the
790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // peer connection mode for the sources.
800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStreamTrack* native_track = MediaStreamTrack::GetTrack(track);
810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!native_track || !native_track->is_local_track()) {
820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // We don't support connecting remote audio tracks to PeerConnection yet.
830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // See issue http://crbug/344303.
840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // TODO(xians): Remove this after we support connecting remote audio track
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // to PeerConnection.
860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DLOG(ERROR) << "webrtc audio track can not be created from a remote audio"
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        << " track.";
880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    NOTIMPLEMENTED();
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This is a local audio track.
930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const blink::WebMediaStreamSource& source = track.source();
940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  MediaStreamAudioSource* audio_source =
950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      static_cast<MediaStreamAudioSource*>(source.extraData());
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (audio_source && audio_source->GetAudioCapturer().get())
970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    audio_source->GetAudioCapturer()->EnablePeerConnectionMode();
980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  webrtc_media_stream_->AddTrack(native_track->GetAudioAdapter());
1000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WebRtcMediaStreamAdapter::CreateVideoTrack(
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const blink::WebMediaStreamTrack& track) {
1040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK_EQ(track.source().type(), blink::WebMediaStreamSource::TypeVideo);
1050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  WebRtcVideoTrackAdapter* adapter =
1060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new WebRtcVideoTrackAdapter(track, factory_);
1070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  video_adapters_.push_back(adapter);
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  webrtc_media_stream_->AddTrack(adapter->webrtc_video_track());
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace content
112