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/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 WebKit::WebMediaStream* web_stream, | 365 WebKit::WebMediaStream* web_stream, |
366 const MediaStreamExtraData::StreamStopCallback& stream_stop) { | 366 const MediaStreamExtraData::StreamStopCallback& stream_stop) { |
367 CreateNativeLocalMediaStream(web_stream); | 367 CreateNativeLocalMediaStream(web_stream); |
368 | 368 |
369 MediaStreamExtraData* extra_data = | 369 MediaStreamExtraData* extra_data = |
370 static_cast<MediaStreamExtraData*>(web_stream->extraData()); | 370 static_cast<MediaStreamExtraData*>(web_stream->extraData()); |
371 extra_data->SetLocalStreamStopCallback(stream_stop); | 371 extra_data->SetLocalStreamStopCallback(stream_stop); |
372 } | 372 } |
373 | 373 |
374 bool MediaStreamDependencyFactory::AddNativeMediaStreamTrack( | 374 bool MediaStreamDependencyFactory::AddNativeMediaStreamTrack( |
375 const WebKit::WebMediaStream& stream, | 375 const WebKit::WebMediaStream& stream, |
376 const WebKit::WebMediaStreamTrack& track) { | 376 const WebKit::WebMediaStreamTrack& track) { |
377 MediaStreamExtraData* extra_data = | 377 MediaStreamExtraData* extra_data = |
378 static_cast<MediaStreamExtraData*>(stream.extraData()); | 378 static_cast<MediaStreamExtraData*>(stream.extraData()); |
379 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); | 379 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); |
380 DCHECK(native_stream); | 380 DCHECK(native_stream); |
381 | 381 |
382 WebKit::WebMediaStreamSource source = track.source(); | 382 WebKit::WebMediaStreamSource source = track.source(); |
383 MediaStreamSourceExtraData* source_data = | 383 MediaStreamSourceExtraData* source_data = |
384 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 384 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
385 | 385 |
386 // In the future the constraints will belong to the track itself, but | 386 // In the future the constraints will belong to the track itself, but |
387 // right now they're on the source, so we fetch them from there. | 387 // right now they're on the source, so we fetch them from there. |
388 RTCMediaConstraints track_constraints(source.constraints()); | 388 RTCMediaConstraints track_constraints(source.constraints()); |
389 | 389 |
390 scoped_refptr<WebRtcAudioCapturer> capturer; | 390 scoped_refptr<WebAudioCapturerSource> webaudio_source; |
391 if (!source_data) { | 391 if (!source_data) { |
392 if (source.requiresAudioConsumer()) { | 392 if (source.requiresAudioConsumer()) { |
393 // We're adding a WebAudio MediaStream. | 393 // We're adding a WebAudio MediaStream. |
394 // Create a specific capturer for each WebAudio consumer. | 394 // Create a specific capturer for each WebAudio consumer. |
395 capturer = CreateWebAudioSource(&source, &track_constraints); | 395 webaudio_source = CreateWebAudioSource(&source, &track_constraints); |
396 source_data = | 396 source_data = |
397 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 397 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
398 } else { | 398 } else { |
399 // TODO(perkj): Implement support for sources from | 399 // TODO(perkj): Implement support for sources from |
400 // remote MediaStreams. | 400 // remote MediaStreams. |
401 NOTIMPLEMENTED(); | 401 NOTIMPLEMENTED(); |
402 return false; | 402 return false; |
403 } | 403 } |
404 } | 404 } |
405 | 405 |
406 WebKit::WebMediaStreamSource::Type type = track.source().type(); | 406 WebKit::WebMediaStreamSource::Type type = track.source().type(); |
407 DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio || | 407 DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio || |
408 type == WebKit::WebMediaStreamSource::TypeVideo); | 408 type == WebKit::WebMediaStreamSource::TypeVideo); |
409 | 409 |
410 std::string track_id = UTF16ToUTF8(track.id()); | 410 std::string track_id = UTF16ToUTF8(track.id()); |
411 if (source.type() == WebKit::WebMediaStreamSource::TypeAudio) { | 411 if (source.type() == WebKit::WebMediaStreamSource::TypeAudio) { |
412 if (!capturer.get() && GetWebRtcAudioDevice()) | 412 scoped_refptr<WebRtcAudioCapturer> capturer; |
| 413 if (GetWebRtcAudioDevice()) |
413 capturer = GetWebRtcAudioDevice()->GetDefaultCapturer(); | 414 capturer = GetWebRtcAudioDevice()->GetDefaultCapturer(); |
414 | 415 |
415 scoped_refptr<webrtc::AudioTrackInterface> audio_track( | 416 scoped_refptr<webrtc::AudioTrackInterface> audio_track( |
416 CreateLocalAudioTrack(track_id, | 417 CreateLocalAudioTrack(track_id, |
417 capturer, | 418 capturer, |
| 419 webaudio_source.get(), |
418 source_data->local_audio_source(), | 420 source_data->local_audio_source(), |
419 &track_constraints)); | 421 &track_constraints)); |
420 audio_track->set_enabled(track.isEnabled()); | 422 audio_track->set_enabled(track.isEnabled()); |
| 423 if (capturer.get()) { |
| 424 WebKit::WebMediaStreamTrack writable_track = track; |
| 425 writable_track.setSourceProvider(capturer->audio_source_provider()); |
| 426 } |
421 return native_stream->AddTrack(audio_track.get()); | 427 return native_stream->AddTrack(audio_track.get()); |
422 } else { | 428 } else { |
423 DCHECK(source.type() == WebKit::WebMediaStreamSource::TypeVideo); | 429 DCHECK(source.type() == WebKit::WebMediaStreamSource::TypeVideo); |
424 scoped_refptr<webrtc::VideoTrackInterface> video_track( | 430 scoped_refptr<webrtc::VideoTrackInterface> video_track( |
425 CreateLocalVideoTrack(track_id, source_data->video_source())); | 431 CreateLocalVideoTrack(track_id, source_data->video_source())); |
426 video_track->set_enabled(track.isEnabled()); | 432 video_track->set_enabled(track.isEnabled()); |
427 return native_stream->AddTrack(video_track.get()); | 433 return native_stream->AddTrack(video_track.get()); |
428 } | 434 } |
429 } | 435 } |
430 | 436 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 MediaStreamExtraData* extra_data = | 474 MediaStreamExtraData* extra_data = |
469 static_cast<MediaStreamExtraData*>(stream.extraData()); | 475 static_cast<MediaStreamExtraData*>(stream.extraData()); |
470 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); | 476 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); |
471 DCHECK(native_stream); | 477 DCHECK(native_stream); |
472 | 478 |
473 WebKit::WebMediaStreamSource::Type type = track.source().type(); | 479 WebKit::WebMediaStreamSource::Type type = track.source().type(); |
474 DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio || | 480 DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio || |
475 type == WebKit::WebMediaStreamSource::TypeVideo); | 481 type == WebKit::WebMediaStreamSource::TypeVideo); |
476 | 482 |
477 std::string track_id = UTF16ToUTF8(track.id()); | 483 std::string track_id = UTF16ToUTF8(track.id()); |
478 return type == WebKit::WebMediaStreamSource::TypeAudio ? | 484 if (type == WebKit::WebMediaStreamSource::TypeAudio) { |
479 native_stream->RemoveTrack(native_stream->FindAudioTrack(track_id)) : | 485 // Remove the source provider as the track is going away. |
480 native_stream->RemoveTrack(native_stream->FindVideoTrack(track_id)); | 486 WebKit::WebMediaStreamTrack writable_track = track; |
| 487 writable_track.setSourceProvider(NULL); |
| 488 return native_stream->RemoveTrack(native_stream->FindAudioTrack(track_id)); |
| 489 } |
| 490 |
| 491 CHECK_EQ(type, WebKit::WebMediaStreamSource::TypeVideo); |
| 492 return native_stream->RemoveTrack(native_stream->FindVideoTrack(track_id)); |
481 } | 493 } |
482 | 494 |
483 bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { | 495 bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { |
484 DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()"; | 496 DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()"; |
485 if (!pc_factory_.get()) { | 497 if (!pc_factory_.get()) { |
486 DCHECK(!audio_device_.get()); | 498 DCHECK(!audio_device_.get()); |
487 audio_device_ = new WebRtcAudioDeviceImpl(); | 499 audio_device_ = new WebRtcAudioDeviceImpl(); |
488 | 500 |
489 scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; | 501 scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; |
490 scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; | 502 scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
589 const webrtc::MediaConstraintsInterface* constraints) { | 601 const webrtc::MediaConstraintsInterface* constraints) { |
590 RtcVideoCapturer* capturer = new RtcVideoCapturer( | 602 RtcVideoCapturer* capturer = new RtcVideoCapturer( |
591 video_session_id, vc_manager_.get(), is_screencast); | 603 video_session_id, vc_manager_.get(), is_screencast); |
592 | 604 |
593 // The video source takes ownership of |capturer|. | 605 // The video source takes ownership of |capturer|. |
594 scoped_refptr<webrtc::VideoSourceInterface> source = | 606 scoped_refptr<webrtc::VideoSourceInterface> source = |
595 pc_factory_->CreateVideoSource(capturer, constraints).get(); | 607 pc_factory_->CreateVideoSource(capturer, constraints).get(); |
596 return source; | 608 return source; |
597 } | 609 } |
598 | 610 |
599 scoped_refptr<WebRtcAudioCapturer> | 611 scoped_refptr<WebAudioCapturerSource> |
600 MediaStreamDependencyFactory::CreateWebAudioSource( | 612 MediaStreamDependencyFactory::CreateWebAudioSource( |
601 WebKit::WebMediaStreamSource* source, | 613 WebKit::WebMediaStreamSource* source, |
602 RTCMediaConstraints* constraints) { | 614 RTCMediaConstraints* constraints) { |
603 DVLOG(1) << "MediaStreamDependencyFactory::CreateWebAudioSource()"; | 615 DVLOG(1) << "MediaStreamDependencyFactory::CreateWebAudioSource()"; |
604 DCHECK(GetWebRtcAudioDevice()); | 616 DCHECK(GetWebRtcAudioDevice()); |
605 | 617 |
606 // Set up the source and ensure that WebAudio is driving things instead of | |
607 // a microphone. For WebAudio, we always create a new capturer without | |
608 // calling initialize(), WebAudio will re-configure the capturer later on. | |
609 // Pass -1 as the |render_view_id| and an empty device struct to tell the | |
610 // capturer not to start the default source. | |
611 scoped_refptr<WebRtcAudioCapturer> capturer( | |
612 MaybeCreateAudioCapturer(-1, StreamDeviceInfo())); | |
613 DCHECK(capturer.get()); | |
614 | |
615 scoped_refptr<WebAudioCapturerSource> | 618 scoped_refptr<WebAudioCapturerSource> |
616 webaudio_capturer_source(new WebAudioCapturerSource(capturer.get())); | 619 webaudio_capturer_source(new WebAudioCapturerSource()); |
617 MediaStreamSourceExtraData* source_data = | 620 MediaStreamSourceExtraData* source_data = |
618 new content::MediaStreamSourceExtraData(webaudio_capturer_source.get()); | 621 new content::MediaStreamSourceExtraData(); |
619 | 622 |
620 // Create a LocalAudioSource object which holds audio options. | 623 // Create a LocalAudioSource object which holds audio options. |
621 // Use audio constraints where all values are true, i.e., enable | 624 // Use audio constraints where all values are true, i.e., enable |
622 // echo cancellation, automatic gain control, noise suppression and | 625 // echo cancellation, automatic gain control, noise suppression and |
623 // high-pass filter. SetLocalAudioSource() affects core audio parts in | 626 // high-pass filter. SetLocalAudioSource() affects core audio parts in |
624 // third_party/Libjingle. | 627 // third_party/Libjingle. |
625 ApplyFixedWebAudioConstraints(constraints); | 628 ApplyFixedWebAudioConstraints(constraints); |
626 source_data->SetLocalAudioSource(CreateLocalAudioSource(constraints).get()); | 629 source_data->SetLocalAudioSource(CreateLocalAudioSource(constraints).get()); |
627 source->setExtraData(source_data); | 630 source->setExtraData(source_data); |
628 | 631 |
629 // Replace the default source with WebAudio as source instead. | 632 // Replace the default source with WebAudio as source instead. |
630 source->addAudioConsumer(webaudio_capturer_source.get()); | 633 source->addAudioConsumer(webaudio_capturer_source.get()); |
631 | 634 |
632 return capturer; | 635 return webaudio_capturer_source; |
633 } | 636 } |
634 | 637 |
635 scoped_refptr<webrtc::VideoTrackInterface> | 638 scoped_refptr<webrtc::VideoTrackInterface> |
636 MediaStreamDependencyFactory::CreateLocalVideoTrack( | 639 MediaStreamDependencyFactory::CreateLocalVideoTrack( |
637 const std::string& id, | 640 const std::string& id, |
638 webrtc::VideoSourceInterface* source) { | 641 webrtc::VideoSourceInterface* source) { |
639 return pc_factory_->CreateVideoTrack(id, source).get(); | 642 return pc_factory_->CreateVideoTrack(id, source).get(); |
640 } | 643 } |
641 | 644 |
642 scoped_refptr<webrtc::VideoTrackInterface> | 645 scoped_refptr<webrtc::VideoTrackInterface> |
643 MediaStreamDependencyFactory::CreateLocalVideoTrack( | 646 MediaStreamDependencyFactory::CreateLocalVideoTrack( |
644 const std::string& id, cricket::VideoCapturer* capturer) { | 647 const std::string& id, cricket::VideoCapturer* capturer) { |
645 if (!capturer) { | 648 if (!capturer) { |
646 LOG(ERROR) << "CreateLocalVideoTrack called with null VideoCapturer."; | 649 LOG(ERROR) << "CreateLocalVideoTrack called with null VideoCapturer."; |
647 return NULL; | 650 return NULL; |
648 } | 651 } |
649 | 652 |
650 // Create video source from the |capturer|. | 653 // Create video source from the |capturer|. |
651 scoped_refptr<webrtc::VideoSourceInterface> source = | 654 scoped_refptr<webrtc::VideoSourceInterface> source = |
652 pc_factory_->CreateVideoSource(capturer, NULL).get(); | 655 pc_factory_->CreateVideoSource(capturer, NULL).get(); |
653 | 656 |
654 // Create native track from the source. | 657 // Create native track from the source. |
655 return pc_factory_->CreateVideoTrack(id, source.get()).get(); | 658 return pc_factory_->CreateVideoTrack(id, source.get()).get(); |
656 } | 659 } |
657 | 660 |
658 scoped_refptr<webrtc::AudioTrackInterface> | 661 scoped_refptr<webrtc::AudioTrackInterface> |
659 MediaStreamDependencyFactory::CreateLocalAudioTrack( | 662 MediaStreamDependencyFactory::CreateLocalAudioTrack( |
660 const std::string& id, | 663 const std::string& id, |
661 const scoped_refptr<WebRtcAudioCapturer>& capturer, | 664 const scoped_refptr<WebRtcAudioCapturer>& capturer, |
| 665 WebAudioCapturerSource* webaudio_source, |
662 webrtc::AudioSourceInterface* source, | 666 webrtc::AudioSourceInterface* source, |
663 const webrtc::MediaConstraintsInterface* constraints) { | 667 const webrtc::MediaConstraintsInterface* constraints) { |
664 // TODO(xians): Merge |source| to the capturer(). We can't do this today | 668 // TODO(xians): Merge |source| to the capturer(). We can't do this today |
665 // because only one capturer() is supported while one |source| is created | 669 // because only one capturer() is supported while one |source| is created |
666 // for each audio track. | 670 // for each audio track. |
667 scoped_refptr<WebRtcLocalAudioTrack> audio_track( | 671 scoped_refptr<WebRtcLocalAudioTrack> audio_track( |
668 WebRtcLocalAudioTrack::Create(id, capturer, source, constraints)); | 672 WebRtcLocalAudioTrack::Create(id, capturer, webaudio_source, |
| 673 source, constraints)); |
| 674 |
669 // Add the WebRtcAudioDevice as the sink to the local audio track. | 675 // Add the WebRtcAudioDevice as the sink to the local audio track. |
670 audio_track->AddSink(GetWebRtcAudioDevice()); | 676 audio_track->AddSink(GetWebRtcAudioDevice()); |
671 // Start the audio track. This will hook the |audio_track| to the capturer | 677 // Start the audio track. This will hook the |audio_track| to the capturer |
672 // as the sink of the audio, and only start the source of the capturer if | 678 // as the sink of the audio, and only start the source of the capturer if |
673 // it is the first audio track connecting to the capturer. | 679 // it is the first audio track connecting to the capturer. |
674 audio_track->Start(); | 680 audio_track->Start(); |
675 return audio_track; | 681 return audio_track; |
676 } | 682 } |
677 | 683 |
678 webrtc::SessionDescriptionInterface* | 684 webrtc::SessionDescriptionInterface* |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 } else { | 801 } else { |
796 NOTREACHED() << "Worker thread not running."; | 802 NOTREACHED() << "Worker thread not running."; |
797 } | 803 } |
798 } | 804 } |
799 } | 805 } |
800 | 806 |
801 scoped_refptr<WebRtcAudioCapturer> | 807 scoped_refptr<WebRtcAudioCapturer> |
802 MediaStreamDependencyFactory::MaybeCreateAudioCapturer( | 808 MediaStreamDependencyFactory::MaybeCreateAudioCapturer( |
803 int render_view_id, | 809 int render_view_id, |
804 const StreamDeviceInfo& device_info) { | 810 const StreamDeviceInfo& device_info) { |
805 scoped_refptr<WebRtcAudioCapturer> capturer; | 811 // TODO(xians): Handle the cases when gUM is called without a proper render |
806 if (render_view_id != -1) { | 812 // view, for example, by an extension. |
807 // From a normal getUserMedia, re-use the existing default capturer. | 813 DCHECK_GE(render_view_id, 0); |
808 capturer = GetWebRtcAudioDevice()->GetDefaultCapturer(); | 814 |
809 } | 815 scoped_refptr<WebRtcAudioCapturer> capturer = |
| 816 GetWebRtcAudioDevice()->GetDefaultCapturer(); |
| 817 |
810 // If the default capturer does not exist or |render_view_id| == -1, create | 818 // If the default capturer does not exist or |render_view_id| == -1, create |
811 // a new capturer. | 819 // a new capturer. |
812 bool is_new_capturer = false; | 820 bool is_new_capturer = false; |
813 if (!capturer.get()) { | 821 if (!capturer.get()) { |
814 capturer = WebRtcAudioCapturer::CreateCapturer(); | 822 capturer = WebRtcAudioCapturer::CreateCapturer(); |
815 is_new_capturer = true; | 823 is_new_capturer = true; |
816 } | 824 } |
817 | 825 |
818 if (!capturer->Initialize( | 826 if (!capturer->Initialize( |
819 render_view_id, | 827 render_view_id, |
820 static_cast<media::ChannelLayout>( | 828 static_cast<media::ChannelLayout>( |
821 device_info.device.input.channel_layout), | 829 device_info.device.input.channel_layout), |
822 device_info.device.input.sample_rate, | 830 device_info.device.input.sample_rate, |
| 831 device_info.device.input.frames_per_buffer, |
823 device_info.session_id, | 832 device_info.session_id, |
824 device_info.device.id)) { | 833 device_info.device.id)) { |
825 return NULL; | 834 return NULL; |
826 } | 835 } |
827 | 836 |
828 // Add the capturer to the WebRtcAudioDeviceImpl if it is a new capturer. | 837 // Add the capturer to the WebRtcAudioDeviceImpl if it is a new capturer. |
829 if (is_new_capturer) | 838 if (is_new_capturer) |
830 GetWebRtcAudioDevice()->AddAudioCapturer(capturer); | 839 GetWebRtcAudioDevice()->AddAudioCapturer(capturer); |
831 | 840 |
832 return capturer; | 841 return capturer; |
833 } | 842 } |
834 | 843 |
835 } // namespace content | 844 } // namespace content |
OLD | NEW |