| 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_dependency_factory.h" | 5 #include "content/renderer/media/media_stream_dependency_factory.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 CreateVideoSource(source_data->device_info().session_id, | 221 CreateVideoSource(source_data->device_info().session_id, |
| 222 is_screencast, | 222 is_screencast, |
| 223 &native_video_constraints)); | 223 &native_video_constraints)); |
| 224 source_observer->AddSource(source_data->video_source()); | 224 source_observer->AddSource(source_data->video_source()); |
| 225 } | 225 } |
| 226 source_observer->StartObservering(); | 226 source_observer->StartObservering(); |
| 227 } | 227 } |
| 228 | 228 |
| 229 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( | 229 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( |
| 230 WebKit::WebMediaStreamDescriptor* description) { | 230 WebKit::WebMediaStreamDescriptor* description) { |
| 231 DCHECK(PeerConnectionFactoryCreated()); | 231 if (!EnsurePeerConnectionFactory()) { |
| 232 DVLOG(1) << "EnsurePeerConnectionFactory() failed!"; |
| 233 return; |
| 234 } |
| 235 |
| 236 DVLOG(1) << "---MediaStreamDependencyFactory::CreateNativeLocalMediaStream()"; |
| 232 | 237 |
| 233 std::string label = UTF16ToUTF8(description->label()); | 238 std::string label = UTF16ToUTF8(description->label()); |
| 234 scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream = | 239 scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream = |
| 235 CreateLocalMediaStream(label); | 240 CreateLocalMediaStream(label); |
| 236 | 241 |
| 242 WebRtcAudioCapturer* capturer = GetWebRtcAudioDevice()->capturer(); |
| 243 if (!capturer) |
| 244 DVLOG(1) << "CreateNativeLocalMediaStream: missing WebRtcAudioCapturer."; |
| 245 |
| 237 // Add audio tracks. | 246 // Add audio tracks. |
| 238 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; | 247 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; |
| 239 description->audioSources(audio_components); | 248 description->audioSources(audio_components); |
| 249 |
| 240 for (size_t i = 0; i < audio_components.size(); ++i) { | 250 for (size_t i = 0; i < audio_components.size(); ++i) { |
| 241 const WebKit::WebMediaStreamSource& source = audio_components[i].source(); | 251 WebKit::WebMediaStreamSource source = audio_components[i].source(); |
| 242 MediaStreamSourceExtraData* source_data = | 252 |
| 243 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 253 // See if we're adding a WebAudio MediaStream. |
| 244 if (!source_data) { | 254 if (source.requiresAudioConsumer()) { |
| 245 // TODO(perkj): Implement support for sources from remote MediaStreams. | 255 if (!webaudio_capturer_source_.get() && capturer) { |
| 246 NOTIMPLEMENTED(); | 256 DVLOG(1) << "CreateNativeLocalMediaStream: WebAudio MediaStream."; |
| 247 continue; | 257 DCHECK(GetWebRtcAudioDevice()); |
| 258 |
| 259 // TODO(crogers, xians): In reality we should be able to send a unique |
| 260 // audio stream to each PeerConnection separately. But currently WebRTC |
| 261 // is only able to handle a global audio stream sent to ALL peers. |
| 262 |
| 263 // TODO(henrika) - why store it here webaudio_capturer_source_? |
| 264 |
| 265 webaudio_capturer_source_ = new WebAudioCapturerSource(); |
| 266 capturer->SetCapturerSource(webaudio_capturer_source_); |
| 267 capturer->Start(); |
| 268 |
| 269 // For lifetime, we're relying on the fact that |
| 270 // |webaudio_capturer_source_| will live longer than any |
| 271 // MediaStreamSource, since we're never calling removeAudioConsumer(). |
| 272 source.addAudioConsumer(webaudio_capturer_source_.get()); |
| 273 |
| 274 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( |
| 275 CreateLocalAudioTrack(label + "a0", NULL)); |
| 276 native_stream->AddTrack(audio_track); |
| 277 audio_track->set_enabled(audio_components[i].isEnabled()); |
| 278 |
| 279 // Do we need to set a sessionId??? |
| 280 // SetAudioDeviceSessionId(99); |
| 281 } else { |
| 282 // TODO(crogers): this is very likely to be less important, but |
| 283 // in theory we should be able to "connect" multiple WebAudio |
| 284 // MediaStreams to a single peer, mixing their results. |
| 285 // Instead we just ignore additional ones after the first. |
| 286 DVLOG(1) |
| 287 << "Multiple MediaStreamAudioDestinationNodes not yet supported!"; |
| 288 } |
| 289 } else { |
| 290 MediaStreamSourceExtraData* source_data = |
| 291 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 292 |
| 293 if (!source_data) { |
| 294 // TODO(perkj): Implement support for sources from |
| 295 // remote MediaStreams. |
| 296 NOTIMPLEMENTED(); |
| 297 continue; |
| 298 } |
| 299 |
| 300 // TODO(perkj): Refactor the creation of audio tracks to use a proper |
| 301 // interface for receiving audio input data. Currently NULL is passed |
| 302 // since the |audio_device| is the wrong class and is unused. |
| 303 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( |
| 304 CreateLocalAudioTrack(UTF16ToUTF8(source.id()), NULL)); |
| 305 native_stream->AddTrack(audio_track); |
| 306 audio_track->set_enabled(audio_components[i].isEnabled()); |
| 307 // TODO(xians): This set the source of all audio tracks to the same |
| 308 // microphone. Implement support for setting the source per audio track |
| 309 // instead. |
| 310 SetAudioDeviceSessionId(source_data->device_info().session_id); |
| 248 } | 311 } |
| 249 // TODO(perkj): Refactor the creation of audio tracks to use a proper | |
| 250 // interface for receiving audio input data. Currently NULL is passed since | |
| 251 // the |audio_device| is the wrong class and is unused. | |
| 252 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( | |
| 253 CreateLocalAudioTrack(UTF16ToUTF8(source.id()), NULL)); | |
| 254 native_stream->AddTrack(audio_track); | |
| 255 audio_track->set_enabled(audio_components[i].isEnabled()); | |
| 256 // TODO(xians): This set the source of all audio tracks to the same | |
| 257 // microphone. Implement support for setting the source per audio track | |
| 258 // instead. | |
| 259 SetAudioDeviceSessionId(source_data->device_info().session_id); | |
| 260 } | 312 } |
| 261 | 313 |
| 262 // Add video tracks. | 314 // Add video tracks. |
| 263 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; | 315 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; |
| 264 description->videoSources(video_components); | 316 description->videoSources(video_components); |
| 265 for (size_t i = 0; i < video_components.size(); ++i) { | 317 for (size_t i = 0; i < video_components.size(); ++i) { |
| 266 const WebKit::WebMediaStreamSource& source = video_components[i].source(); | 318 const WebKit::WebMediaStreamSource& source = video_components[i].source(); |
| 267 MediaStreamSourceExtraData* source_data = | 319 MediaStreamSourceExtraData* source_data = |
| 268 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 320 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 269 if (!source_data || !source_data->video_source()) { | 321 if (!source_data || !source_data->video_source()) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 network_manager_, | 380 network_manager_, |
| 329 socket_factory_.get(), | 381 socket_factory_.get(), |
| 330 web_frame); | 382 web_frame); |
| 331 return pc_factory_->CreatePeerConnection( | 383 return pc_factory_->CreatePeerConnection( |
| 332 ice_servers, constraints, pa_factory, observer).get(); | 384 ice_servers, constraints, pa_factory, observer).get(); |
| 333 } | 385 } |
| 334 | 386 |
| 335 scoped_refptr<webrtc::LocalMediaStreamInterface> | 387 scoped_refptr<webrtc::LocalMediaStreamInterface> |
| 336 MediaStreamDependencyFactory::CreateLocalMediaStream( | 388 MediaStreamDependencyFactory::CreateLocalMediaStream( |
| 337 const std::string& label) { | 389 const std::string& label) { |
| 390 DVLOG(1) << "---MediaStreamDependencyFactory::CreateLocalMediaStream()"; |
| 338 return pc_factory_->CreateLocalMediaStream(label).get(); | 391 return pc_factory_->CreateLocalMediaStream(label).get(); |
| 339 } | 392 } |
| 340 | 393 |
| 341 scoped_refptr<webrtc::VideoSourceInterface> | 394 scoped_refptr<webrtc::VideoSourceInterface> |
| 342 MediaStreamDependencyFactory::CreateVideoSource( | 395 MediaStreamDependencyFactory::CreateVideoSource( |
| 343 int video_session_id, | 396 int video_session_id, |
| 344 bool is_screencast, | 397 bool is_screencast, |
| 345 const webrtc::MediaConstraintsInterface* constraints) { | 398 const webrtc::MediaConstraintsInterface* constraints) { |
| 399 DVLOG(1) << "---MediaStreamDependencyFactory::CreateVideoSource()"; |
| 346 RtcVideoCapturer* capturer = new RtcVideoCapturer( | 400 RtcVideoCapturer* capturer = new RtcVideoCapturer( |
| 347 video_session_id, vc_manager_.get(), is_screencast); | 401 video_session_id, vc_manager_.get(), is_screencast); |
| 348 | 402 |
| 349 // The video source takes ownership of |capturer|. | 403 // The video source takes ownership of |capturer|. |
| 350 scoped_refptr<webrtc::VideoSourceInterface> source = | 404 scoped_refptr<webrtc::VideoSourceInterface> source = |
| 351 pc_factory_->CreateVideoSource(capturer, constraints).get(); | 405 pc_factory_->CreateVideoSource(capturer, constraints).get(); |
| 352 return source; | 406 return source; |
| 353 } | 407 } |
| 354 | 408 |
| 355 scoped_refptr<webrtc::VideoTrackInterface> | 409 scoped_refptr<webrtc::VideoTrackInterface> |
| 356 MediaStreamDependencyFactory::CreateLocalVideoTrack( | 410 MediaStreamDependencyFactory::CreateLocalVideoTrack( |
| 357 const std::string& label, | 411 const std::string& label, |
| 358 webrtc::VideoSourceInterface* source) { | 412 webrtc::VideoSourceInterface* source) { |
| 413 DVLOG(1) << "---MediaStreamDependencyFactory::CreateLocalVideoTrack()"; |
| 359 return pc_factory_->CreateVideoTrack(label, source).get(); | 414 return pc_factory_->CreateVideoTrack(label, source).get(); |
| 360 } | 415 } |
| 361 | 416 |
| 362 scoped_refptr<webrtc::LocalAudioTrackInterface> | 417 scoped_refptr<webrtc::LocalAudioTrackInterface> |
| 363 MediaStreamDependencyFactory::CreateLocalAudioTrack( | 418 MediaStreamDependencyFactory::CreateLocalAudioTrack( |
| 364 const std::string& label, | 419 const std::string& label, |
| 365 webrtc::AudioDeviceModule* audio_device) { | 420 webrtc::AudioDeviceModule* audio_device) { |
| 421 DVLOG(1) << "---MediaStreamDependencyFactory::CreateLocalAudioTrack()"; |
| 366 return pc_factory_->CreateLocalAudioTrack(label, audio_device).get(); | 422 return pc_factory_->CreateLocalAudioTrack(label, audio_device).get(); |
| 367 } | 423 } |
| 368 | 424 |
| 369 webrtc::SessionDescriptionInterface* | 425 webrtc::SessionDescriptionInterface* |
| 370 MediaStreamDependencyFactory::CreateSessionDescription(const std::string& sdp) { | 426 MediaStreamDependencyFactory::CreateSessionDescription(const std::string& sdp) { |
| 371 return webrtc::CreateSessionDescription(sdp); | 427 return webrtc::CreateSessionDescription(sdp); |
| 372 } | 428 } |
| 373 | 429 |
| 374 webrtc::SessionDescriptionInterface* | 430 webrtc::SessionDescriptionInterface* |
| 375 MediaStreamDependencyFactory::CreateSessionDescription(const std::string& type, | 431 MediaStreamDependencyFactory::CreateSessionDescription(const std::string& type, |
| 376 const std::string& sdp) { | 432 const std::string& sdp) { |
| 377 return webrtc::CreateSessionDescription(type, sdp); | 433 return webrtc::CreateSessionDescription(type, sdp); |
| 378 } | 434 } |
| 379 | 435 |
| 380 webrtc::IceCandidateInterface* MediaStreamDependencyFactory::CreateIceCandidate( | 436 webrtc::IceCandidateInterface* MediaStreamDependencyFactory::CreateIceCandidate( |
| 381 const std::string& sdp_mid, | 437 const std::string& sdp_mid, |
| 382 int sdp_mline_index, | 438 int sdp_mline_index, |
| 383 const std::string& sdp) { | 439 const std::string& sdp) { |
| 384 return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp); | 440 return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp); |
| 385 } | 441 } |
| 386 | 442 |
| 387 WebRtcAudioDeviceImpl* | 443 WebRtcAudioDeviceImpl* |
| 388 MediaStreamDependencyFactory::GetWebRtcAudioDevice() { | 444 MediaStreamDependencyFactory::GetWebRtcAudioDevice() { |
| 389 return audio_device_; | 445 return audio_device_; |
| 390 } | 446 } |
| 391 | 447 |
| 392 void MediaStreamDependencyFactory::SetAudioDeviceSessionId(int session_id) { | 448 void MediaStreamDependencyFactory::SetAudioDeviceSessionId(int session_id) { |
| 449 DVLOG(1) << "--- MediaStreamDependencyFactory::SetAudioDeviceSessionId()"; |
| 450 DVLOG(1) << "--- session_id: " << session_id; |
| 393 audio_device_->SetSessionId(session_id); | 451 audio_device_->SetSessionId(session_id); |
| 394 } | 452 } |
| 395 | 453 |
| 396 void MediaStreamDependencyFactory::InitializeWorkerThread( | 454 void MediaStreamDependencyFactory::InitializeWorkerThread( |
| 397 talk_base::Thread** thread, | 455 talk_base::Thread** thread, |
| 398 base::WaitableEvent* event) { | 456 base::WaitableEvent* event) { |
| 399 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | 457 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| 400 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 458 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| 401 *thread = jingle_glue::JingleThreadWrapper::current(); | 459 *thread = jingle_glue::JingleThreadWrapper::current(); |
| 402 event->Signal(); | 460 event->Signal(); |
| 403 } | 461 } |
| 404 | 462 |
| 405 void MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( | 463 void MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( |
| 406 base::WaitableEvent* event) { | 464 base::WaitableEvent* event) { |
| 407 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); | 465 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); |
| 408 network_manager_ = new IpcNetworkManager(p2p_socket_dispatcher_); | 466 network_manager_ = new IpcNetworkManager(p2p_socket_dispatcher_); |
| 409 event->Signal(); | 467 event->Signal(); |
| 410 } | 468 } |
| 411 | 469 |
| 412 void MediaStreamDependencyFactory::DeleteIpcNetworkManager() { | 470 void MediaStreamDependencyFactory::DeleteIpcNetworkManager() { |
| 413 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); | 471 DCHECK_EQ(MessageLoop::current(), chrome_worker_thread_.message_loop()); |
| 414 delete network_manager_; | 472 delete network_manager_; |
| 415 network_manager_ = NULL; | 473 network_manager_ = NULL; |
| 416 } | 474 } |
| 417 | 475 |
| 418 bool MediaStreamDependencyFactory::EnsurePeerConnectionFactory() { | 476 bool MediaStreamDependencyFactory::EnsurePeerConnectionFactory() { |
| 477 DVLOG(1) << "--- MediaStreamDependencyFactory::EnsurePeerConnectionFactory()"; |
| 419 DCHECK(CalledOnValidThread()); | 478 DCHECK(CalledOnValidThread()); |
| 420 if (PeerConnectionFactoryCreated()) | 479 if (PeerConnectionFactoryCreated()) |
| 421 return true; | 480 return true; |
| 422 | 481 |
| 423 if (!signaling_thread_) { | 482 if (!signaling_thread_) { |
| 424 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | 483 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| 425 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 484 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| 426 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); | 485 signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); |
| 427 CHECK(signaling_thread_); | 486 CHECK(signaling_thread_); |
| 428 } | 487 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 // processed before returning. We wait for the above task to finish before | 543 // processed before returning. We wait for the above task to finish before |
| 485 // letting the the function continue to avoid any potential race issues. | 544 // letting the the function continue to avoid any potential race issues. |
| 486 chrome_worker_thread_.Stop(); | 545 chrome_worker_thread_.Stop(); |
| 487 } else { | 546 } else { |
| 488 NOTREACHED() << "Worker thread not running."; | 547 NOTREACHED() << "Worker thread not running."; |
| 489 } | 548 } |
| 490 } | 549 } |
| 491 } | 550 } |
| 492 | 551 |
| 493 } // namespace content | 552 } // namespace content |
| OLD | NEW |