1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/renderer/media/webrtc/webrtc_media_stream_adapter.h"
6
7#include "base/logging.h"
8#include "content/renderer/media/media_stream_audio_source.h"
9#include "content/renderer/media/media_stream_track.h"
10#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
11#include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
12#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
13#include "third_party/WebKit/public/platform/WebString.h"
14
15namespace content {
16
17WebRtcMediaStreamAdapter::WebRtcMediaStreamAdapter(
18    const blink::WebMediaStream& web_stream,
19    PeerConnectionDependencyFactory* factory)
20    : web_stream_(web_stream),
21      factory_(factory) {
22  webrtc_media_stream_ =
23      factory_->CreateLocalMediaStream(web_stream.id().utf8());
24
25  blink::WebVector<blink::WebMediaStreamTrack> audio_tracks;
26  web_stream_.audioTracks(audio_tracks);
27  for (size_t i = 0; i < audio_tracks.size(); ++i)
28    CreateAudioTrack(audio_tracks[i]);
29
30  blink::WebVector<blink::WebMediaStreamTrack> video_tracks;
31  web_stream_.videoTracks(video_tracks);
32  for (size_t i = 0; i < video_tracks.size(); ++i)
33    CreateVideoTrack(video_tracks[i]);
34
35  MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
36  native_stream->AddObserver(this);
37}
38
39WebRtcMediaStreamAdapter::~WebRtcMediaStreamAdapter() {
40  MediaStream* native_stream = MediaStream::GetMediaStream(web_stream_);
41  native_stream->RemoveObserver(this);
42}
43
44void WebRtcMediaStreamAdapter::TrackAdded(
45    const blink::WebMediaStreamTrack& track) {
46  if (track.source().type() == blink::WebMediaStreamSource::TypeAudio) {
47    CreateAudioTrack(track);
48  } else {
49    CreateVideoTrack(track);
50  }
51}
52
53void WebRtcMediaStreamAdapter::TrackRemoved(
54    const blink::WebMediaStreamTrack& track) {
55  const std::string track_id = track.id().utf8();
56  if (track.source().type() == blink::WebMediaStreamSource::TypeAudio) {
57    webrtc_media_stream_->RemoveTrack(
58        webrtc_media_stream_->FindAudioTrack(track_id));
59  } else {
60    DCHECK_EQ(track.source().type(), blink::WebMediaStreamSource::TypeVideo);
61    scoped_refptr<webrtc::VideoTrackInterface> webrtc_track =
62        webrtc_media_stream_->FindVideoTrack(track_id).get();
63    webrtc_media_stream_->RemoveTrack(webrtc_track.get());
64
65    for (ScopedVector<WebRtcVideoTrackAdapter>::iterator it =
66             video_adapters_.begin(); it != video_adapters_.end(); ++it) {
67      if ((*it)->webrtc_video_track() == webrtc_track.get()) {
68        video_adapters_.erase(it);
69        break;
70      }
71    }
72  }
73}
74
75void WebRtcMediaStreamAdapter::CreateAudioTrack(
76    const blink::WebMediaStreamTrack& track) {
77  DCHECK_EQ(track.source().type(), blink::WebMediaStreamSource::TypeAudio);
78  // A media stream is connected to a peer connection, enable the
79  // peer connection mode for the sources.
80  MediaStreamTrack* native_track = MediaStreamTrack::GetTrack(track);
81  if (!native_track || !native_track->is_local_track()) {
82    // We don't support connecting remote audio tracks to PeerConnection yet.
83    // See issue http://crbug/344303.
84    // TODO(xians): Remove this after we support connecting remote audio track
85    // to PeerConnection.
86    DLOG(ERROR) << "webrtc audio track can not be created from a remote audio"
87        << " track.";
88    NOTIMPLEMENTED();
89    return;
90  }
91
92  // This is a local audio track.
93  const blink::WebMediaStreamSource& source = track.source();
94  MediaStreamAudioSource* audio_source =
95      static_cast<MediaStreamAudioSource*>(source.extraData());
96  if (audio_source && audio_source->GetAudioCapturer().get())
97    audio_source->GetAudioCapturer()->EnablePeerConnectionMode();
98
99  webrtc_media_stream_->AddTrack(native_track->GetAudioAdapter());
100}
101
102void WebRtcMediaStreamAdapter::CreateVideoTrack(
103    const blink::WebMediaStreamTrack& track) {
104  DCHECK_EQ(track.source().type(), blink::WebMediaStreamSource::TypeVideo);
105  WebRtcVideoTrackAdapter* adapter =
106      new WebRtcVideoTrackAdapter(track, factory_);
107  video_adapters_.push_back(adapter);
108  webrtc_media_stream_->AddTrack(adapter->webrtc_video_track());
109}
110
111}  // namespace content
112