OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/media_stream_impl.h" | 5 #include "content/renderer/media/media_stream_impl.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
12 #include "base/stringprintf.h" | |
12 #include "base/synchronization/waitable_event.h" | 13 #include "base/synchronization/waitable_event.h" |
13 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
14 #include "content/renderer/media/capture_video_decoder.h" | 15 #include "content/renderer/media/capture_video_decoder.h" |
16 #include "content/renderer/media/media_stream_extra_data.h" | |
15 #include "content/renderer/media/media_stream_dependency_factory.h" | 17 #include "content/renderer/media/media_stream_dependency_factory.h" |
16 #include "content/renderer/media/media_stream_dispatcher.h" | 18 #include "content/renderer/media/media_stream_dispatcher.h" |
17 #include "content/renderer/media/peer_connection_handler.h" | 19 #include "content/renderer/media/peer_connection_handler.h" |
18 #include "content/renderer/media/peer_connection_handler_jsep.h" | 20 #include "content/renderer/media/peer_connection_handler_jsep.h" |
19 #include "content/renderer/media/video_capture_impl_manager.h" | 21 #include "content/renderer/media/video_capture_impl_manager.h" |
20 #include "content/renderer/media/video_capture_module_impl.h" | 22 #include "content/renderer/media/video_capture_module_impl.h" |
21 #include "content/renderer/media/webrtc_audio_device_impl.h" | 23 #include "content/renderer/media/webrtc_audio_device_impl.h" |
22 #include "content/renderer/p2p/ipc_network_manager.h" | 24 #include "content/renderer/p2p/ipc_network_manager.h" |
23 #include "content/renderer/p2p/ipc_socket_factory.h" | 25 #include "content/renderer/p2p/ipc_socket_factory.h" |
24 #include "content/renderer/p2p/socket_dispatcher.h" | 26 #include "content/renderer/p2p/socket_dispatcher.h" |
(...skipping 23 matching lines...) Expand all Loading... | |
48 | 50 |
49 // Helper method used to collect information about the number of times | 51 // Helper method used to collect information about the number of times |
50 // different WebRTC API:s are called from JavaScript. | 52 // different WebRTC API:s are called from JavaScript. |
51 // The histogram can be viewed at chrome://histograms/WebRTC.webkitApiCount. | 53 // The histogram can be viewed at chrome://histograms/WebRTC.webkitApiCount. |
52 static void UpdateWebRTCMethodCount(JavaScriptAPIName api_name) { | 54 static void UpdateWebRTCMethodCount(JavaScriptAPIName api_name) { |
53 UMA_HISTOGRAM_ENUMERATION("WebRTC.webkitApiCount", api_name, kInvalidName); | 55 UMA_HISTOGRAM_ENUMERATION("WebRTC.webkitApiCount", api_name, kInvalidName); |
54 } | 56 } |
55 | 57 |
56 static int g_next_request_id = 0; | 58 static int g_next_request_id = 0; |
57 | 59 |
58 // The MediaStreamMananger label for a stream is globally unique. The track | |
59 // session id is globally unique for the set of audio tracks and video tracks | |
60 // respectively. An audio track and a video track can have the same session id | |
61 // (without being related). Hence we create a unique track label from the stream | |
62 // label, track type and track session id: | |
63 // <MediaStreamManager-label>#{audio,video}-<session-ID>. | |
64 static std::string CreateTrackLabel( | |
65 const std::string& manager_label, | |
66 int session_id, | |
67 bool is_video) { | |
68 std::string track_label = manager_label; | |
69 if (is_video) { | |
70 track_label += "#video-"; | |
71 } else { | |
72 track_label += "#audio-"; | |
73 } | |
74 track_label += session_id; | |
75 return track_label; | |
76 } | |
77 | |
78 // Extracting the MediaStreamManager stream label will only work for track | |
79 // labels created by CreateTrackLabel. If is wasn't, the contents of the | |
80 // returned string is undefined. | |
81 static std::string ExtractManagerStreamLabel( | |
82 const std::string& track_label) { | |
83 std::string manager_label = track_label; | |
84 size_t pos = manager_label.rfind("#"); | |
85 // If # isn't found, the string is left intact. | |
86 manager_label = manager_label.substr(0, pos); | |
87 return manager_label; | |
88 } | |
89 | |
90 static void CreateWebKitSourceVector( | 60 static void CreateWebKitSourceVector( |
91 const std::string& label, | 61 const std::string& label, |
92 const media_stream::StreamDeviceInfoArray& devices, | 62 const media_stream::StreamDeviceInfoArray& devices, |
93 WebKit::WebMediaStreamSource::Type type, | 63 WebKit::WebMediaStreamSource::Type type, |
94 WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) { | 64 WebKit::WebVector<WebKit::WebMediaStreamSource>& webkit_sources) { |
95 ASSERT(devices.size() == webkit_sources.size()); | 65 ASSERT(devices.size() == webkit_sources.size()); |
96 | |
97 for (size_t i = 0; i < devices.size(); ++i) { | 66 for (size_t i = 0; i < devices.size(); ++i) { |
98 std::string track_label = CreateTrackLabel( | 67 std::string source_id = label; |
99 label, devices[i].session_id, | 68 base::StringAppendF(&source_id, "_%lu", i); |
tommi (sloooow) - chröme
2012/05/13 20:08:46
is %lu always the right format specifier for size_
perkj_chrome
2012/05/14 11:50:25
It seems like u is the correct way but not all com
| |
100 type == WebKit::WebMediaStreamSource::TypeVideo); | |
101 webkit_sources[i].initialize( | 69 webkit_sources[i].initialize( |
102 UTF8ToUTF16(track_label), | 70 UTF8ToUTF16(source_id), |
103 type, | 71 type, |
104 UTF8ToUTF16(devices[i].name)); | 72 UTF8ToUTF16(devices[i].name)); |
105 } | 73 } |
106 } | 74 } |
107 | 75 |
108 MediaStreamImpl::MediaStreamImpl( | 76 MediaStreamImpl::MediaStreamImpl( |
109 content::RenderView* render_view, | 77 content::RenderView* render_view, |
110 MediaStreamDispatcher* media_stream_dispatcher, | 78 MediaStreamDispatcher* media_stream_dispatcher, |
111 content::P2PSocketDispatcher* p2p_socket_dispatcher, | 79 content::P2PSocketDispatcher* p2p_socket_dispatcher, |
112 VideoCaptureImplManager* vc_manager, | 80 VideoCaptureImplManager* vc_manager, |
113 MediaStreamDependencyFactory* dependency_factory) | 81 MediaStreamDependencyFactory* dependency_factory) |
114 : content::RenderViewObserver(render_view), | 82 : content::RenderViewObserver(render_view), |
115 dependency_factory_(dependency_factory), | 83 dependency_factory_(dependency_factory), |
116 media_stream_dispatcher_(media_stream_dispatcher), | 84 media_stream_dispatcher_(media_stream_dispatcher), |
117 p2p_socket_dispatcher_(p2p_socket_dispatcher), | 85 p2p_socket_dispatcher_(p2p_socket_dispatcher), |
118 network_manager_(NULL), | 86 network_manager_(NULL), |
119 vc_manager_(vc_manager), | 87 vc_manager_(vc_manager), |
120 signaling_thread_(NULL), | 88 signaling_thread_(NULL), |
121 worker_thread_(NULL), | 89 worker_thread_(NULL), |
122 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { | 90 chrome_worker_thread_("Chrome_libJingle_WorkerThread") { |
123 } | 91 } |
124 | 92 |
125 MediaStreamImpl::~MediaStreamImpl() { | 93 MediaStreamImpl::~MediaStreamImpl() { |
126 DCHECK(peer_connection_handlers_.empty()); | |
127 DCHECK(local_media_streams_.empty()); | 94 DCHECK(local_media_streams_.empty()); |
128 if (dependency_factory_.get()) | 95 if (dependency_factory_.get()) |
129 dependency_factory_->ReleasePeerConnectionFactory(); | 96 dependency_factory_->ReleasePeerConnectionFactory(); |
130 if (network_manager_) { | 97 if (network_manager_) { |
131 // The network manager needs to free its resources on the thread they were | 98 // The network manager needs to free its resources on the thread they were |
132 // created, which is the worked thread. | 99 // created, which is the worked thread. |
133 if (chrome_worker_thread_.IsRunning()) { | 100 if (chrome_worker_thread_.IsRunning()) { |
134 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( | 101 chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( |
135 &MediaStreamImpl::DeleteIpcNetworkManager, | 102 &MediaStreamImpl::DeleteIpcNetworkManager, |
136 base::Unretained(this))); | 103 base::Unretained(this))); |
(...skipping 12 matching lines...) Expand all Loading... | |
149 // Save histogram data so we can see how much PeerConnetion is used. | 116 // Save histogram data so we can see how much PeerConnetion is used. |
150 // The histogram counts the number of calls to the JS API | 117 // The histogram counts the number of calls to the JS API |
151 // webKitDeprecatedPeerConnection. | 118 // webKitDeprecatedPeerConnection. |
152 UpdateWebRTCMethodCount(kWebkitDeprecatedPeerConnection); | 119 UpdateWebRTCMethodCount(kWebkitDeprecatedPeerConnection); |
153 DCHECK(CalledOnValidThread()); | 120 DCHECK(CalledOnValidThread()); |
154 if (!EnsurePeerConnectionFactory()) | 121 if (!EnsurePeerConnectionFactory()) |
155 return NULL; | 122 return NULL; |
156 | 123 |
157 PeerConnectionHandler* pc_handler = new PeerConnectionHandler( | 124 PeerConnectionHandler* pc_handler = new PeerConnectionHandler( |
158 client, | 125 client, |
159 this, | |
160 dependency_factory_.get()); | 126 dependency_factory_.get()); |
161 peer_connection_handlers_.push_back(pc_handler); | |
162 | |
163 return pc_handler; | 127 return pc_handler; |
164 } | 128 } |
165 | 129 |
166 WebKit::WebPeerConnection00Handler* | 130 WebKit::WebPeerConnection00Handler* |
167 MediaStreamImpl::CreatePeerConnectionHandlerJsep( | 131 MediaStreamImpl::CreatePeerConnectionHandlerJsep( |
168 WebKit::WebPeerConnection00HandlerClient* client) { | 132 WebKit::WebPeerConnection00HandlerClient* client) { |
169 // Save histogram data so we can see how much PeerConnetion is used. | 133 // Save histogram data so we can see how much PeerConnetion is used. |
170 // The histogram counts the number of calls to the JS API | 134 // The histogram counts the number of calls to the JS API |
171 // webKitPeerConnection00. | 135 // webKitPeerConnection00. |
172 UpdateWebRTCMethodCount(kWebkitPeerConnection); | 136 UpdateWebRTCMethodCount(kWebkitPeerConnection); |
173 DCHECK(CalledOnValidThread()); | 137 DCHECK(CalledOnValidThread()); |
174 if (!EnsurePeerConnectionFactory()) | 138 if (!EnsurePeerConnectionFactory()) |
175 return NULL; | 139 return NULL; |
176 | 140 |
177 PeerConnectionHandlerJsep* pc_handler = new PeerConnectionHandlerJsep( | 141 PeerConnectionHandlerJsep* pc_handler = new PeerConnectionHandlerJsep( |
178 client, | 142 client, |
179 this, | |
180 dependency_factory_.get()); | 143 dependency_factory_.get()); |
181 peer_connection_handlers_.push_back(pc_handler); | |
182 | |
183 return pc_handler; | 144 return pc_handler; |
184 } | 145 } |
185 | 146 |
186 void MediaStreamImpl::ClosePeerConnection( | 147 void MediaStreamImpl::StopLocalMediaStream( |
187 PeerConnectionHandlerBase* pc_handler) { | 148 const WebKit::WebMediaStreamDescriptor& stream) { |
188 DCHECK(CalledOnValidThread()); | 149 DVLOG(1) << "MediaStreamImpl::StopLocalMediaStream"; |
189 peer_connection_handlers_.remove(pc_handler); | 150 |
151 MediaStreamExtraData* extra_data = | |
152 static_cast<MediaStreamExtraData*>(stream.extraData()); | |
153 if (extra_data && extra_data->local_stream()) { | |
154 media_stream_dispatcher_->StopStream(extra_data->local_stream()->label()); | |
155 local_media_streams_.erase(extra_data->local_stream()->label()); | |
156 } else { | |
157 NOTREACHED(); | |
158 } | |
190 } | 159 } |
191 | 160 |
192 webrtc::LocalMediaStreamInterface* MediaStreamImpl::GetLocalMediaStream( | 161 void MediaStreamImpl::CreateMediaStream( |
193 const WebKit::WebMediaStreamDescriptor& stream) { | 162 WebKit::WebFrame* frame, |
194 // TODO(perkj): Change the mapping between a native local media stream and | 163 WebKit::WebMediaStreamDescriptor* stream) { |
195 // WebMediaStreamDescriptor once there is a common id. | 164 DVLOG(1) << "MediaStreamImpl::CreateMediaStream"; |
196 // For now, we are forced to lookup the sources within a MediaStream. | 165 // TODO(perkj): Need to find the source from all existing local and |
197 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; | 166 // remote MediaStreams. |
198 stream.videoSources(video_components); | 167 NOTIMPLEMENTED(); |
199 | |
200 std::string msm_label; | |
201 if (!video_components.isEmpty()) { | |
202 std::string source_id = UTF16ToUTF8(video_components[0].source().id()); | |
203 msm_label = ExtractManagerStreamLabel(source_id); | |
204 } | |
205 // If no local video source was found, check if there is an audio source. | |
206 if (msm_label.empty()) { | |
207 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; | |
208 stream.audioSources(audio_components); | |
209 if (!audio_components.isEmpty()) { | |
210 std::string source_id = UTF16ToUTF8(audio_components[0].source().id()); | |
211 msm_label = ExtractManagerStreamLabel(source_id); | |
212 } | |
213 } | |
214 LocalNativeStreamMap::iterator it = local_media_streams_.find(msm_label); | |
215 if (it == local_media_streams_.end()) | |
216 return NULL; | |
217 return it->second.stream_.get(); | |
218 } | |
219 | |
220 bool MediaStreamImpl::StopLocalMediaStream( | |
221 const WebKit::WebMediaStreamDescriptor& stream) { | |
222 DVLOG(1) << "MediaStreamImpl::StopLocalMediaStream"; | |
223 webrtc::LocalMediaStreamInterface* native_stream = GetLocalMediaStream( | |
224 stream); | |
225 if (native_stream) { | |
226 media_stream_dispatcher_->StopStream(native_stream->label()); | |
227 local_media_streams_.erase(native_stream->label()); | |
228 return true; | |
229 } else { | |
230 return false; | |
231 } | |
232 } | 168 } |
233 | 169 |
234 void MediaStreamImpl::requestUserMedia( | 170 void MediaStreamImpl::requestUserMedia( |
235 const WebKit::WebUserMediaRequest& user_media_request, | 171 const WebKit::WebUserMediaRequest& user_media_request, |
236 const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources, | 172 const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources, |
237 const WebKit::WebVector<WebKit::WebMediaStreamSource>& video_sources) { | 173 const WebKit::WebVector<WebKit::WebMediaStreamSource>& video_sources) { |
238 // Save histogram data so we can see how much GetUserMedia is used. | 174 // Save histogram data so we can see how much GetUserMedia is used. |
239 // The histogram counts the number of calls to the JS API | 175 // The histogram counts the number of calls to the JS API |
240 // webGetUserMedia. | 176 // webGetUserMedia. |
241 UpdateWebRTCMethodCount(kWebkitGetUserMedia); | 177 UpdateWebRTCMethodCount(kWebkitGetUserMedia); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 for (; it != user_media_requests_.end(); ++it) { | 222 for (; it != user_media_requests_.end(); ++it) { |
287 if (it->second.request_ == user_media_request) | 223 if (it->second.request_ == user_media_request) |
288 break; | 224 break; |
289 } | 225 } |
290 if (it != user_media_requests_.end()) { | 226 if (it != user_media_requests_.end()) { |
291 media_stream_dispatcher_->CancelGenerateStream(it->first); | 227 media_stream_dispatcher_->CancelGenerateStream(it->first); |
292 user_media_requests_.erase(it); | 228 user_media_requests_.erase(it); |
293 } | 229 } |
294 } | 230 } |
295 | 231 |
232 WebKit::WebMediaStreamDescriptor MediaStreamImpl::GetMediaStream( | |
233 const GURL& url) { | |
234 return WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url); | |
235 } | |
296 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( | 236 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( |
297 const GURL& url, | 237 const GURL& url, |
298 media::MessageLoopFactory* message_loop_factory) { | 238 media::MessageLoopFactory* message_loop_factory) { |
299 DCHECK(CalledOnValidThread()); | 239 DCHECK(CalledOnValidThread()); |
300 WebKit::WebMediaStreamDescriptor descriptor( | 240 WebKit::WebMediaStreamDescriptor descriptor(GetMediaStream(url)); |
301 WebKit::WebMediaStreamRegistry::lookupMediaStreamDescriptor(url)); | 241 |
302 if (descriptor.isNull()) | 242 if (descriptor.isNull() || !descriptor.extraData()) |
303 return NULL; // This is not a valid stream. | 243 return NULL; // This is not a valid stream. |
304 | 244 |
305 webrtc::LocalMediaStreamInterface* local_stream = | 245 DVLOG(1) << "MediaStreamImpl::GetVideoDecoder stream:" |
306 GetLocalMediaStream(descriptor); | 246 << UTF16ToUTF8(descriptor.label()); |
307 if (local_stream) | |
308 return CreateLocalVideoDecoder(local_stream, message_loop_factory); | |
309 | 247 |
310 PeerConnectionHandlerBase* pc_handler = | 248 MediaStreamExtraData* extra_data = |
311 FindPeerConnectionByStream(descriptor); | 249 static_cast<MediaStreamExtraData*>(descriptor.extraData()); |
312 if (pc_handler != NULL) { | 250 if (extra_data->local_stream()) |
313 return CreateRemoteVideoDecoder(descriptor, | 251 return CreateLocalVideoDecoder(extra_data->local_stream(), |
314 pc_handler, | 252 message_loop_factory); |
315 url, | 253 if (extra_data->remote_stream()) |
254 return CreateRemoteVideoDecoder(extra_data->remote_stream(), url, | |
316 message_loop_factory); | 255 message_loop_factory); |
317 } | 256 NOTREACHED(); |
318 return NULL; | 257 return NULL; |
319 } | 258 } |
320 | 259 |
321 // Callback from MediaStreamDispatcher. | 260 // Callback from MediaStreamDispatcher. |
322 // The requested stream have been generated. | 261 // The requested stream have been generated. |
323 void MediaStreamImpl::OnStreamGenerated( | 262 void MediaStreamImpl::OnStreamGenerated( |
324 int request_id, | 263 int request_id, |
325 const std::string& label, | 264 const std::string& label, |
326 const media_stream::StreamDeviceInfoArray& audio_array, | 265 const media_stream::StreamDeviceInfoArray& audio_array, |
327 const media_stream::StreamDeviceInfoArray& video_array) { | 266 const media_stream::StreamDeviceInfoArray& video_array) { |
328 DCHECK(CalledOnValidThread()); | 267 DCHECK(CalledOnValidThread()); |
329 | 268 |
330 WebKit::WebVector<WebKit::WebMediaStreamSource> audio_source_vector( | 269 WebKit::WebVector<WebKit::WebMediaStreamSource> audio_source_vector( |
331 audio_array.size()); | 270 audio_array.size()); |
332 CreateWebKitSourceVector(label, audio_array, | 271 CreateWebKitSourceVector(label, audio_array, |
333 WebKit::WebMediaStreamSource::TypeAudio, | 272 WebKit::WebMediaStreamSource::TypeAudio, |
334 audio_source_vector); | 273 audio_source_vector); |
335 WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector( | 274 WebKit::WebVector<WebKit::WebMediaStreamSource> video_source_vector( |
336 video_array.size()); | 275 video_array.size()); |
337 CreateWebKitSourceVector(label, video_array, | 276 CreateWebKitSourceVector(label, video_array, |
338 WebKit::WebMediaStreamSource::TypeVideo, | 277 WebKit::WebMediaStreamSource::TypeVideo, |
339 video_source_vector); | 278 video_source_vector); |
340 | 279 |
341 MediaRequestMap::iterator it = user_media_requests_.find(request_id); | 280 MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
342 if (it == user_media_requests_.end()) { | 281 if (it == user_media_requests_.end()) { |
343 DVLOG(1) << "Request ID not found"; | 282 DVLOG(1) << "Request ID not found"; |
344 return; | 283 return; |
345 } | 284 } |
346 | 285 |
347 CreateNativeLocalMediaStream(label, it->second.frame_, | 286 LocalNativeStreamPtr native_stream( |
348 audio_source_vector, video_source_vector); | 287 CreateNativeLocalMediaStream(label, it->second.frame_, |
tommi (sloooow) - chröme
2012/05/13 20:08:46
fix indent...
actually...can you go through the wh
perkj_chrome
2012/05/14 11:50:25
Done.
| |
288 audio_source_vector, video_source_vector)); | |
349 | 289 |
350 WebKit::WebUserMediaRequest user_media_request(it->second.request_); | 290 WebKit::WebString webkit_label = UTF8ToUTF16(label); |
291 WebKit::WebMediaStreamDescriptor description; | |
292 description.initialize(webkit_label, audio_source_vector, | |
293 video_source_vector); | |
294 description.setExtraData(new MediaStreamExtraData(native_stream)); | |
295 | |
296 CompleteGetUserMediaRequest(description, &it->second.request_); | |
351 user_media_requests_.erase(it); | 297 user_media_requests_.erase(it); |
298 } | |
352 | 299 |
353 // |user_media_request| can't be mocked. So in order to test at all we check | 300 void MediaStreamImpl::CompleteGetUserMediaRequest( |
354 // if it isNull. | 301 const WebKit::WebMediaStreamDescriptor& stream, |
355 if (!user_media_request.isNull()) | 302 WebKit::WebUserMediaRequest* request) { |
356 user_media_request.requestSucceeded(audio_source_vector, | 303 request->requestSucceeded(stream); |
357 video_source_vector); | |
358 } | 304 } |
359 | 305 |
360 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { | 306 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) { |
361 DCHECK(CalledOnValidThread()); | 307 DCHECK(CalledOnValidThread()); |
362 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" | 308 DVLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed(" |
363 << request_id << ")"; | 309 << request_id << ")"; |
364 MediaRequestMap::iterator it = user_media_requests_.find(request_id); | 310 MediaRequestMap::iterator it = user_media_requests_.find(request_id); |
365 if (it == user_media_requests_.end()) { | 311 if (it == user_media_requests_.end()) { |
366 DVLOG(1) << "Request ID not found"; | 312 DVLOG(1) << "Request ID not found"; |
367 return; | 313 return; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
415 | 361 |
416 void MediaStreamImpl::OnDeviceOpenFailed(int request_id) { | 362 void MediaStreamImpl::OnDeviceOpenFailed(int request_id) { |
417 DVLOG(1) << "MediaStreamImpl::VideoDeviceOpenFailed(" | 363 DVLOG(1) << "MediaStreamImpl::VideoDeviceOpenFailed(" |
418 << request_id << ")"; | 364 << request_id << ")"; |
419 NOTIMPLEMENTED(); | 365 NOTIMPLEMENTED(); |
420 } | 366 } |
421 | 367 |
422 void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) { | 368 void MediaStreamImpl::FrameWillClose(WebKit::WebFrame* frame) { |
423 LocalNativeStreamMap::iterator it = local_media_streams_.begin(); | 369 LocalNativeStreamMap::iterator it = local_media_streams_.begin(); |
424 while (it != local_media_streams_.end()) { | 370 while (it != local_media_streams_.end()) { |
425 if (it->second.frame_ == frame) { | 371 if (it->second == frame) { |
426 DVLOG(1) << "MediaStreamImpl::FrameWillClose: " | 372 DVLOG(1) << "MediaStreamImpl::FrameWillClose: " |
427 << "Stopping stream " << it->first; | 373 << "Stopping stream " << it->first; |
428 media_stream_dispatcher_->StopStream(it->first); | 374 media_stream_dispatcher_->StopStream(it->first); |
429 local_media_streams_.erase(it); | 375 local_media_streams_.erase(it); |
430 it = local_media_streams_.begin(); | 376 it = local_media_streams_.begin(); |
431 } else { | 377 } else { |
432 ++it; | 378 ++it; |
433 } | 379 } |
434 } | 380 } |
435 } | 381 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
504 socket_factory_.get())) { | 450 socket_factory_.get())) { |
505 LOG(ERROR) << "Could not create PeerConnection factory"; | 451 LOG(ERROR) << "Could not create PeerConnection factory"; |
506 return false; | 452 return false; |
507 } | 453 } |
508 } | 454 } |
509 | 455 |
510 return true; | 456 return true; |
511 } | 457 } |
512 | 458 |
513 scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateLocalVideoDecoder( | 459 scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateLocalVideoDecoder( |
514 webrtc::LocalMediaStreamInterface* stream, | 460 webrtc::MediaStreamInterface* stream, |
515 media::MessageLoopFactory* message_loop_factory) { | 461 media::MessageLoopFactory* message_loop_factory) { |
516 if (!stream->video_tracks() || stream->video_tracks()->count() == 0) | 462 if (!stream->video_tracks() || stream->video_tracks()->count() == 0) |
517 return NULL; | 463 return NULL; |
518 | 464 |
519 int video_session_id = | 465 int video_session_id = |
520 media_stream_dispatcher_->video_session_id(stream->label(), 0); | 466 media_stream_dispatcher_->video_session_id(stream->label(), 0); |
521 media::VideoCaptureCapability capability; | 467 media::VideoCaptureCapability capability; |
522 capability.width = kVideoCaptureWidth; | 468 capability.width = kVideoCaptureWidth; |
523 capability.height = kVideoCaptureHeight; | 469 capability.height = kVideoCaptureHeight; |
524 capability.frame_rate = kVideoCaptureFramePerSecond; | 470 capability.frame_rate = kVideoCaptureFramePerSecond; |
525 capability.color = media::VideoCaptureCapability::kI420; | 471 capability.color = media::VideoCaptureCapability::kI420; |
526 capability.expected_capture_delay = 0; | 472 capability.expected_capture_delay = 0; |
527 capability.interlaced = false; | 473 capability.interlaced = false; |
474 | |
475 DVLOG(1) << "MediaStreamImpl::CreateLocalVideoDecoder video_session_id:" | |
476 << video_session_id; | |
477 | |
528 return new CaptureVideoDecoder( | 478 return new CaptureVideoDecoder( |
529 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), | 479 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"), |
530 video_session_id, | 480 video_session_id, |
531 vc_manager_.get(), | 481 vc_manager_.get(), |
532 capability); | 482 capability); |
533 } | 483 } |
534 | 484 |
535 PeerConnectionHandlerBase* MediaStreamImpl::FindPeerConnectionByStream( | |
536 const WebKit::WebMediaStreamDescriptor& stream) { | |
537 std::list<PeerConnectionHandlerBase*>::iterator it; | |
538 for (it = peer_connection_handlers_.begin(); | |
539 it != peer_connection_handlers_.end(); ++it) { | |
540 if ((*it)->GetRemoteMediaStream(stream) != NULL) { | |
541 return *it; | |
542 } | |
543 } | |
544 return NULL; | |
545 } | |
546 | |
547 scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateRemoteVideoDecoder( | 485 scoped_refptr<media::VideoDecoder> MediaStreamImpl::CreateRemoteVideoDecoder( |
548 const WebKit::WebMediaStreamDescriptor& stream, | 486 webrtc::MediaStreamInterface* stream, |
549 PeerConnectionHandlerBase* pc_handler, | |
550 const GURL& url, | 487 const GURL& url, |
551 media::MessageLoopFactory* message_loop_factory) { | 488 media::MessageLoopFactory* message_loop_factory) { |
552 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_sources; | 489 if (!stream->video_tracks() || stream->video_tracks()->count() == 0) |
553 stream.videoSources(video_sources); | |
554 if (video_sources.isEmpty()) | |
555 return NULL; | 490 return NULL; |
556 | 491 |
557 std::string source_id = UTF16ToUTF8(video_sources[0].source().id()); | 492 DVLOG(1) << "MediaStreamImpl::CreateRemoteVideoDecoder label:" |
493 << stream->label(); | |
494 | |
558 RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder( | 495 RTCVideoDecoder* rtc_video_decoder = new RTCVideoDecoder( |
559 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), | 496 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"), |
560 url.spec()); | 497 url.spec()); |
561 talk_base::scoped_refptr<webrtc::VideoRendererWrapperInterface> renderer( | 498 talk_base::scoped_refptr<webrtc::VideoRendererWrapperInterface> renderer( |
562 new talk_base::RefCountedObject<VideoRendererWrapper>(rtc_video_decoder)); | 499 new talk_base::RefCountedObject<VideoRendererWrapper>(rtc_video_decoder)); |
563 | 500 stream->video_tracks()->at(0)->SetRenderer(renderer); |
564 pc_handler->SetRemoteVideoRenderer(source_id, renderer); | |
565 return rtc_video_decoder; | 501 return rtc_video_decoder; |
566 } | 502 } |
567 | 503 |
568 void MediaStreamImpl::CreateNativeLocalMediaStream( | 504 talk_base::scoped_refptr<webrtc::LocalMediaStreamInterface> |
505 MediaStreamImpl::CreateNativeLocalMediaStream( | |
569 const std::string& label, | 506 const std::string& label, |
570 WebKit::WebFrame* frame, | 507 WebKit::WebFrame* frame, |
571 const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources, | 508 const WebKit::WebVector<WebKit::WebMediaStreamSource>& audio_sources, |
572 const WebKit::WebVector<WebKit::WebMediaStreamSource>& video_sources) { | 509 const WebKit::WebVector<WebKit::WebMediaStreamSource>& video_sources) { |
573 // Creating the peer connection factory can fail if for example the audio | 510 // Creating the peer connection factory can fail if for example the audio |
574 // (input or output) or video device cannot be opened. Handling such cases | 511 // (input or output) or video device cannot be opened. Handling such cases |
575 // better is a higher level design discussion which involves the media | 512 // better is a higher level design discussion which involves the media |
576 // manager, webrtc and libjingle. We cannot create any native | 513 // manager, webrtc and libjingle. We cannot create any native |
577 // track objects however, so we'll just have to skip that. Furthermore, | 514 // track objects however, so we'll just have to skip that. Furthermore, |
578 // creating a peer connection later on will fail if we don't have a factory. | 515 // creating a peer connection later on will fail if we don't have a factory. |
579 if (!EnsurePeerConnectionFactory()) { | 516 if (!EnsurePeerConnectionFactory()) { |
580 return; | 517 return NULL; |
581 } | 518 } |
582 | 519 |
583 LocalMediaStreamPtr native_stream = | 520 LocalNativeStreamPtr native_stream = |
584 dependency_factory_->CreateLocalMediaStream(label); | 521 dependency_factory_->CreateLocalMediaStream(label); |
585 | 522 |
586 // Add audio tracks. | 523 // Add audio tracks. |
587 for (size_t i = 0; i < audio_sources.size(); ++i) { | 524 for (size_t i = 0; i < audio_sources.size(); ++i) { |
588 talk_base::scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( | 525 talk_base::scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( |
589 dependency_factory_->CreateLocalAudioTrack( | 526 dependency_factory_->CreateLocalAudioTrack( |
590 UTF16ToUTF8(audio_sources[i].name()), NULL)); | 527 UTF16ToUTF8(audio_sources[i].id()), NULL)); |
591 native_stream->AddTrack(audio_track); | 528 native_stream->AddTrack(audio_track); |
592 } | 529 } |
593 | 530 |
594 // Add video tracks. | 531 // Add video tracks. |
595 for (size_t i = 0; i < video_sources.size(); ++i) { | 532 for (size_t i = 0; i < video_sources.size(); ++i) { |
596 std::string msm_label = ExtractManagerStreamLabel( | 533 if (!media_stream_dispatcher_->IsStream(label)) { |
597 UTF16ToUTF8(video_sources[i].id())); | |
598 if (!media_stream_dispatcher_->IsStream(msm_label)) { | |
599 continue; | 534 continue; |
600 } | 535 } |
601 int video_session_id = | 536 int video_session_id = |
602 media_stream_dispatcher_->video_session_id(msm_label, 0); | 537 media_stream_dispatcher_->video_session_id(label, 0); |
603 talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface> video_track( | 538 talk_base::scoped_refptr<webrtc::LocalVideoTrackInterface> video_track( |
604 dependency_factory_->CreateLocalVideoTrack( | 539 dependency_factory_->CreateLocalVideoTrack( |
605 UTF16ToUTF8(video_sources[i].name()), video_session_id)); | 540 UTF16ToUTF8(video_sources[i].id()), video_session_id)); |
606 native_stream->AddTrack(video_track); | 541 native_stream->AddTrack(video_track); |
607 } | 542 } |
608 local_media_streams_[label] = LocalMediaStreamInfo(frame, native_stream); | 543 local_media_streams_[label] = frame; |
544 return native_stream; | |
609 } | 545 } |
610 | 546 |
611 MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper( | 547 MediaStreamImpl::VideoRendererWrapper::VideoRendererWrapper( |
612 RTCVideoDecoder* decoder) | 548 RTCVideoDecoder* decoder) |
613 : rtc_video_decoder_(decoder) { | 549 : rtc_video_decoder_(decoder) { |
614 } | 550 } |
615 | 551 |
616 MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() { | 552 MediaStreamImpl::VideoRendererWrapper::~VideoRendererWrapper() { |
617 } | 553 } |
618 | |
619 MediaStreamImpl::LocalMediaStreamInfo::~LocalMediaStreamInfo() { | |
620 } | |
OLD | NEW |