Chromium Code Reviews| 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); |
| 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 } | |
|
perkj_chrome
2012/05/13 13:39:18
Add blank line
perkj_chrome
2012/05/14 11:50:25
Done.
| |
| 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_, |
|
perkj_chrome
2012/05/13 13:39:18
intendtation
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 |