1 // Copyright (c) 2012 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.
5 #include "content/renderer/media/media_stream_center.h"
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "content/common/media/media_stream_messages.h"
12 #include "content/public/common/content_switches.h"
13 #include "content/public/renderer/media_stream_audio_sink.h"
14 #include "content/public/renderer/render_thread.h"
15 #include "content/renderer/media/media_stream.h"
16 #include "content/renderer/media/media_stream_source.h"
17 #include "content/renderer/media/media_stream_video_source.h"
18 #include "content/renderer/media/media_stream_video_track.h"
19 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
20 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
21 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
22 #include "third_party/WebKit/public/platform/WebMediaStream.h"
23 #include "third_party/WebKit/public/platform/WebMediaStreamCenterClient.h"
24 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
25 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
26 #include "third_party/WebKit/public/platform/WebMediaStreamTrackSourcesRequest.h"
27 #include "third_party/WebKit/public/platform/WebSourceInfo.h"
28 #include "third_party/WebKit/public/platform/WebVector.h"
29 #include "third_party/WebKit/public/web/WebFrame.h"
31 using blink::WebFrame
;
38 void CreateNativeAudioMediaStreamTrack(
39 const blink::WebMediaStreamTrack
& track
,
40 PeerConnectionDependencyFactory
* factory
) {
41 DCHECK(!track
.extraData());
42 blink::WebMediaStreamSource source
= track
.source();
43 DCHECK_EQ(source
.type(), blink::WebMediaStreamSource::TypeAudio
);
44 factory
->CreateLocalAudioTrack(track
);
47 void CreateNativeVideoMediaStreamTrack(
48 const blink::WebMediaStreamTrack
& track
) {
49 DCHECK(track
.extraData() == NULL
);
50 blink::WebMediaStreamSource source
= track
.source();
51 DCHECK_EQ(source
.type(), blink::WebMediaStreamSource::TypeVideo
);
52 MediaStreamVideoSource
* native_source
=
53 MediaStreamVideoSource::GetVideoSource(source
);
54 DCHECK(native_source
);
55 blink::WebMediaStreamTrack
writable_track(track
);
56 // TODO(perkj): The constraints to use here should be passed from blink when
57 // a new track is created. For cloning, it should be the constraints of the
58 // cloned track and not the originating source.
59 // Also - source.constraints() returns an uninitialized constraint if the
60 // source is coming from a remote video track. See http://crbug/287805.
61 blink::WebMediaConstraints constraints
= source
.constraints();
62 if (constraints
.isNull())
63 constraints
.initialize();
64 writable_track
.setExtraData(
65 new MediaStreamVideoTrack(native_source
, constraints
,
66 MediaStreamVideoSource::ConstraintsCallback(),
70 void CreateNativeMediaStreamTrack(const blink::WebMediaStreamTrack
& track
,
71 PeerConnectionDependencyFactory
* factory
) {
72 DCHECK(!track
.isNull() && !track
.extraData());
73 DCHECK(!track
.source().isNull());
75 switch (track
.source().type()) {
76 case blink::WebMediaStreamSource::TypeAudio
:
77 CreateNativeAudioMediaStreamTrack(track
, factory
);
79 case blink::WebMediaStreamSource::TypeVideo
:
80 CreateNativeVideoMediaStreamTrack(track
);
87 MediaStreamCenter::MediaStreamCenter(blink::WebMediaStreamCenterClient
* client
,
88 PeerConnectionDependencyFactory
* factory
)
89 : rtc_factory_(factory
), next_request_id_(0) {}
91 MediaStreamCenter::~MediaStreamCenter() {}
93 bool MediaStreamCenter::getMediaStreamTrackSources(
94 const blink::WebMediaStreamTrackSourcesRequest
& request
) {
95 int request_id
= next_request_id_
++;
96 requests_
.insert(std::make_pair(request_id
, request
));
97 RenderThread::Get()->Send(new MediaStreamHostMsg_GetSources(
99 GURL(request
.origin().utf8())));
103 void MediaStreamCenter::didCreateMediaStreamTrack(
104 const blink::WebMediaStreamTrack
& track
) {
105 DVLOG(1) << "MediaStreamCenter::didCreateMediaStreamTrack";
106 CreateNativeMediaStreamTrack(track
, rtc_factory_
);
109 void MediaStreamCenter::didEnableMediaStreamTrack(
110 const blink::WebMediaStreamTrack
& track
) {
111 MediaStreamTrack
* native_track
=
112 MediaStreamTrack::GetTrack(track
);
114 native_track
->SetEnabled(true);
117 void MediaStreamCenter::didDisableMediaStreamTrack(
118 const blink::WebMediaStreamTrack
& track
) {
119 MediaStreamTrack
* native_track
=
120 MediaStreamTrack::GetTrack(track
);
122 native_track
->SetEnabled(false);
125 bool MediaStreamCenter::didStopMediaStreamTrack(
126 const blink::WebMediaStreamTrack
& track
) {
127 DVLOG(1) << "MediaStreamCenter::didStopMediaStreamTrack";
128 MediaStreamTrack
* native_track
= MediaStreamTrack::GetTrack(track
);
129 native_track
->Stop();
133 blink::WebAudioSourceProvider
*
134 MediaStreamCenter::createWebAudioSourceFromMediaStreamTrack(
135 const blink::WebMediaStreamTrack
& track
) {
136 DVLOG(1) << "MediaStreamCenter::createWebAudioSourceFromMediaStreamTrack";
137 MediaStreamTrack
* media_stream_track
=
138 static_cast<MediaStreamTrack
*>(track
.extraData());
139 // Only local audio track is supported now.
140 // TODO(xians): Support remote audio track.
141 if (!media_stream_track
|| !media_stream_track
->is_local_track()) {
146 blink::WebMediaStreamSource source
= track
.source();
147 DCHECK_EQ(source
.type(), blink::WebMediaStreamSource::TypeAudio
);
148 WebRtcLocalAudioSourceProvider
* source_provider
=
149 new WebRtcLocalAudioSourceProvider(track
);
150 return source_provider
;
153 void MediaStreamCenter::didStopLocalMediaStream(
154 const blink::WebMediaStream
& stream
) {
155 DVLOG(1) << "MediaStreamCenter::didStopLocalMediaStream";
156 MediaStream
* native_stream
= MediaStream::GetMediaStream(stream
);
157 if (!native_stream
) {
162 // TODO(perkj): MediaStream::Stop is being deprecated. But for the moment we
163 // need to support both MediaStream::Stop and MediaStreamTrack::Stop.
164 blink::WebVector
<blink::WebMediaStreamTrack
> audio_tracks
;
165 stream
.audioTracks(audio_tracks
);
166 for (size_t i
= 0; i
< audio_tracks
.size(); ++i
)
167 didStopMediaStreamTrack(audio_tracks
[i
]);
169 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
170 stream
.videoTracks(video_tracks
);
171 for (size_t i
= 0; i
< video_tracks
.size(); ++i
)
172 didStopMediaStreamTrack(video_tracks
[i
]);
175 void MediaStreamCenter::didCreateMediaStream(blink::WebMediaStream
& stream
) {
176 DVLOG(1) << "MediaStreamCenter::didCreateMediaStream";
177 blink::WebMediaStream
writable_stream(stream
);
178 MediaStream
* native_stream(
179 new MediaStream(stream
));
180 writable_stream
.setExtraData(native_stream
);
182 blink::WebVector
<blink::WebMediaStreamTrack
> video_tracks
;
183 stream
.videoTracks(video_tracks
);
184 for (size_t i
= 0; i
< video_tracks
.size(); ++i
) {
185 if (!MediaStreamTrack::GetTrack(video_tracks
[i
]))
186 CreateNativeMediaStreamTrack(video_tracks
[i
], rtc_factory_
);
190 bool MediaStreamCenter::didAddMediaStreamTrack(
191 const blink::WebMediaStream
& stream
,
192 const blink::WebMediaStreamTrack
& track
) {
193 DVLOG(1) << "MediaStreamCenter::didAddMediaStreamTrack";
194 MediaStream
* native_stream
= MediaStream::GetMediaStream(stream
);
195 return native_stream
->AddTrack(track
);
198 bool MediaStreamCenter::didRemoveMediaStreamTrack(
199 const blink::WebMediaStream
& stream
,
200 const blink::WebMediaStreamTrack
& track
) {
201 DVLOG(1) << "MediaStreamCenter::didRemoveMediaStreamTrack";
202 MediaStream
* native_stream
= MediaStream::GetMediaStream(stream
);
203 return native_stream
->RemoveTrack(track
);
206 bool MediaStreamCenter::OnControlMessageReceived(const IPC::Message
& message
) {
208 IPC_BEGIN_MESSAGE_MAP(MediaStreamCenter
, message
)
209 IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK
,
210 OnGetSourcesComplete
)
211 IPC_MESSAGE_UNHANDLED(handled
= false)
212 IPC_END_MESSAGE_MAP()
216 void MediaStreamCenter::OnGetSourcesComplete(
218 const content::StreamDeviceInfoArray
& devices
) {
219 RequestMap::iterator request_it
= requests_
.find(request_id
);
220 DCHECK(request_it
!= requests_
.end());
222 blink::WebVector
<blink::WebSourceInfo
> sourceInfos(devices
.size());
223 for (size_t i
= 0; i
< devices
.size(); ++i
) {
224 const MediaStreamDevice
& device
= devices
[i
].device
;
225 DCHECK(device
.type
== MEDIA_DEVICE_AUDIO_CAPTURE
||
226 device
.type
== MEDIA_DEVICE_VIDEO_CAPTURE
);
227 blink::WebSourceInfo::VideoFacingMode video_facing
;
228 switch (device
.video_facing
) {
229 case MEDIA_VIDEO_FACING_USER
:
230 video_facing
= blink::WebSourceInfo::VideoFacingModeUser
;
232 case MEDIA_VIDEO_FACING_ENVIRONMENT
:
233 video_facing
= blink::WebSourceInfo::VideoFacingModeEnvironment
;
236 video_facing
= blink::WebSourceInfo::VideoFacingModeNone
;
240 .initialize(blink::WebString::fromUTF8(device
.id
),
241 device
.type
== MEDIA_DEVICE_AUDIO_CAPTURE
242 ? blink::WebSourceInfo::SourceKindAudio
243 : blink::WebSourceInfo::SourceKindVideo
,
244 blink::WebString::fromUTF8(device
.name
),
247 request_it
->second
.requestSucceeded(sourceInfos
);
250 } // namespace content