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 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 {webrtc::MediaConstraintsInterface::kEchoCancellation, | 63 {webrtc::MediaConstraintsInterface::kEchoCancellation, |
64 webrtc::MediaConstraintsInterface::kValueTrue}, | 64 webrtc::MediaConstraintsInterface::kValueTrue}, |
65 {webrtc::MediaConstraintsInterface::kAutoGainControl, | 65 {webrtc::MediaConstraintsInterface::kAutoGainControl, |
66 webrtc::MediaConstraintsInterface::kValueTrue}, | 66 webrtc::MediaConstraintsInterface::kValueTrue}, |
67 {webrtc::MediaConstraintsInterface::kNoiseSuppression, | 67 {webrtc::MediaConstraintsInterface::kNoiseSuppression, |
68 webrtc::MediaConstraintsInterface::kValueTrue}, | 68 webrtc::MediaConstraintsInterface::kValueTrue}, |
69 {webrtc::MediaConstraintsInterface::kHighpassFilter, | 69 {webrtc::MediaConstraintsInterface::kHighpassFilter, |
70 webrtc::MediaConstraintsInterface::kValueTrue}, | 70 webrtc::MediaConstraintsInterface::kValueTrue}, |
71 }; | 71 }; |
72 | 72 |
73 class WebAudioConstraints : public RTCMediaConstraints { | 73 void ApplyFixedWebAudioConstraints(RTCMediaConstraints* constraints) { |
74 public: | 74 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kWebAudioConstraints); ++i) { |
75 WebAudioConstraints() | 75 constraints->AddMandatory(kWebAudioConstraints[i].key, |
76 : RTCMediaConstraints(WebKit::WebMediaConstraints()) { | 76 kWebAudioConstraints[i].value, false); |
77 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kWebAudioConstraints); ++i) { | |
78 webrtc::MediaConstraintsInterface::Constraint constraint; | |
79 constraint.key = kWebAudioConstraints[i].key; | |
80 constraint.value = kWebAudioConstraints[i].value; | |
81 | |
82 DVLOG(1) << "WebAudioConstraints: " << constraint.key | |
83 << " : " << constraint.value; | |
84 mandatory_.push_back(constraint); | |
85 } | |
86 } | 77 } |
87 | 78 } |
88 virtual ~WebAudioConstraints() {} | |
89 }; | |
90 | 79 |
91 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { | 80 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { |
92 public: | 81 public: |
93 P2PPortAllocatorFactory( | 82 P2PPortAllocatorFactory( |
94 P2PSocketDispatcher* socket_dispatcher, | 83 P2PSocketDispatcher* socket_dispatcher, |
95 talk_base::NetworkManager* network_manager, | 84 talk_base::NetworkManager* network_manager, |
96 talk_base::PacketSocketFactory* socket_factory, | 85 talk_base::PacketSocketFactory* socket_factory, |
97 WebKit::WebFrame* web_frame) | 86 WebKit::WebFrame* web_frame) |
98 : socket_dispatcher_(socket_dispatcher), | 87 : socket_dispatcher_(socket_dispatcher), |
99 network_manager_(network_manager), | 88 network_manager_(network_manager), |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 | 307 |
319 // TODO(xians): Create a new capturer for difference microphones when we | 308 // TODO(xians): Create a new capturer for difference microphones when we |
320 // support multiple microphones. See issue crbug/262117 . | 309 // support multiple microphones. See issue crbug/262117 . |
321 const StreamDeviceInfo device_info = source_data->device_info(); | 310 const StreamDeviceInfo device_info = source_data->device_info(); |
322 scoped_refptr<WebRtcAudioCapturer> capturer( | 311 scoped_refptr<WebRtcAudioCapturer> capturer( |
323 MaybeCreateAudioCapturer(render_view_id, device_info)); | 312 MaybeCreateAudioCapturer(render_view_id, device_info)); |
324 if (!capturer.get()) { | 313 if (!capturer.get()) { |
325 DLOG(WARNING) << "Failed to create the capturer for device " | 314 DLOG(WARNING) << "Failed to create the capturer for device " |
326 << device_info.device.id; | 315 << device_info.device.id; |
327 sources_created.Run(web_stream, false); | 316 sources_created.Run(web_stream, false); |
317 // TODO(xians): Don't we need to check if source_observer is observing | |
318 // something? If not, then it looks like we have a leak here. | |
319 // OTOH, if it _is_ observing something, then the callback might | |
320 // be called multiple times which is likely also a bug. | |
328 return; | 321 return; |
329 } | 322 } |
330 | 323 |
331 // Creates a LocalAudioSource object which holds audio options. | 324 // Creates a LocalAudioSource object which holds audio options. |
332 // TODO(xians): The option should apply to the track instead of the source. | 325 // TODO(xians): The option should apply to the track instead of the source. |
333 source_data->SetLocalAudioSource( | 326 source_data->SetLocalAudioSource( |
334 CreateLocalAudioSource(&native_audio_constraints).get()); | 327 CreateLocalAudioSource(&native_audio_constraints).get()); |
335 source_observer->AddSource(source_data->local_audio_source()); | 328 source_observer->AddSource(source_data->local_audio_source()); |
336 } | 329 } |
337 | 330 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
383 const WebKit::WebMediaStreamTrack& track) { | 376 const WebKit::WebMediaStreamTrack& track) { |
384 MediaStreamExtraData* extra_data = | 377 MediaStreamExtraData* extra_data = |
385 static_cast<MediaStreamExtraData*>(stream.extraData()); | 378 static_cast<MediaStreamExtraData*>(stream.extraData()); |
386 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); | 379 webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); |
387 DCHECK(native_stream); | 380 DCHECK(native_stream); |
388 | 381 |
389 WebKit::WebMediaStreamSource source = track.source(); | 382 WebKit::WebMediaStreamSource source = track.source(); |
390 MediaStreamSourceExtraData* source_data = | 383 MediaStreamSourceExtraData* source_data = |
391 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 384 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
392 | 385 |
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. | |
henrika (OOO until Aug 14)
2013/08/26 11:34:55
TODO()?
tommi (sloooow) - chröme
2013/08/27 10:58:22
This isn't really a todo but more of an explanatio
| |
388 RTCMediaConstraints track_constraints(source.constraints()); | |
389 | |
393 scoped_refptr<WebRtcAudioCapturer> capturer; | 390 scoped_refptr<WebRtcAudioCapturer> capturer; |
394 if (!source_data) { | 391 if (!source_data) { |
395 if (source.requiresAudioConsumer()) { | 392 if (source.requiresAudioConsumer()) { |
396 // We're adding a WebAudio MediaStream. | 393 // We're adding a WebAudio MediaStream. |
397 // Create a specific capturer for each WebAudio consumer. | 394 // Create a specific capturer for each WebAudio consumer. |
398 capturer = CreateWebAudioSource(&source); | 395 capturer = CreateWebAudioSource(&source, &track_constraints); |
399 source_data = | 396 source_data = |
400 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 397 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
401 } else { | 398 } else { |
402 // TODO(perkj): Implement support for sources from | 399 // TODO(perkj): Implement support for sources from |
403 // remote MediaStreams. | 400 // remote MediaStreams. |
404 NOTIMPLEMENTED(); | 401 NOTIMPLEMENTED(); |
405 return false; | 402 return false; |
406 } | 403 } |
407 } | 404 } |
408 | 405 |
409 WebKit::WebMediaStreamSource::Type type = track.source().type(); | 406 WebKit::WebMediaStreamSource::Type type = track.source().type(); |
410 DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio || | 407 DCHECK(type == WebKit::WebMediaStreamSource::TypeAudio || |
411 type == WebKit::WebMediaStreamSource::TypeVideo); | 408 type == WebKit::WebMediaStreamSource::TypeVideo); |
412 | 409 |
413 std::string track_id = UTF16ToUTF8(track.id()); | 410 std::string track_id = UTF16ToUTF8(track.id()); |
414 if (source.type() == WebKit::WebMediaStreamSource::TypeAudio) { | 411 if (source.type() == WebKit::WebMediaStreamSource::TypeAudio) { |
415 if (!capturer.get() && GetWebRtcAudioDevice()) | 412 if (!capturer.get() && GetWebRtcAudioDevice()) |
416 capturer = GetWebRtcAudioDevice()->GetDefaultCapturer(); | 413 capturer = GetWebRtcAudioDevice()->GetDefaultCapturer(); |
417 | 414 |
418 scoped_refptr<webrtc::AudioTrackInterface> audio_track( | 415 scoped_refptr<webrtc::AudioTrackInterface> audio_track( |
419 CreateLocalAudioTrack(track_id, | 416 CreateLocalAudioTrack(track_id, |
420 capturer, | 417 capturer, |
421 source_data->local_audio_source())); | 418 source_data->local_audio_source(), |
419 &track_constraints)); | |
422 audio_track->set_enabled(track.isEnabled()); | 420 audio_track->set_enabled(track.isEnabled()); |
423 return native_stream->AddTrack(audio_track.get()); | 421 return native_stream->AddTrack(audio_track.get()); |
424 } else { | 422 } else { |
425 DCHECK(source.type() == WebKit::WebMediaStreamSource::TypeVideo); | 423 DCHECK(source.type() == WebKit::WebMediaStreamSource::TypeVideo); |
426 scoped_refptr<webrtc::VideoTrackInterface> video_track( | 424 scoped_refptr<webrtc::VideoTrackInterface> video_track( |
427 CreateLocalVideoTrack(track_id, source_data->video_source())); | 425 CreateLocalVideoTrack(track_id, source_data->video_source())); |
428 video_track->set_enabled(track.isEnabled()); | 426 video_track->set_enabled(track.isEnabled()); |
429 return native_stream->AddTrack(video_track.get()); | 427 return native_stream->AddTrack(video_track.get()); |
430 } | 428 } |
431 } | 429 } |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 video_session_id, vc_manager_.get(), is_screencast); | 589 video_session_id, vc_manager_.get(), is_screencast); |
592 | 590 |
593 // The video source takes ownership of |capturer|. | 591 // The video source takes ownership of |capturer|. |
594 scoped_refptr<webrtc::VideoSourceInterface> source = | 592 scoped_refptr<webrtc::VideoSourceInterface> source = |
595 pc_factory_->CreateVideoSource(capturer, constraints).get(); | 593 pc_factory_->CreateVideoSource(capturer, constraints).get(); |
596 return source; | 594 return source; |
597 } | 595 } |
598 | 596 |
599 scoped_refptr<WebRtcAudioCapturer> | 597 scoped_refptr<WebRtcAudioCapturer> |
600 MediaStreamDependencyFactory::CreateWebAudioSource( | 598 MediaStreamDependencyFactory::CreateWebAudioSource( |
601 WebKit::WebMediaStreamSource* source) { | 599 WebKit::WebMediaStreamSource* source, |
600 RTCMediaConstraints* constraints) { | |
602 DVLOG(1) << "MediaStreamDependencyFactory::CreateWebAudioSource()"; | 601 DVLOG(1) << "MediaStreamDependencyFactory::CreateWebAudioSource()"; |
603 DCHECK(GetWebRtcAudioDevice()); | 602 DCHECK(GetWebRtcAudioDevice()); |
604 | 603 |
605 // Set up the source and ensure that WebAudio is driving things instead of | 604 // Set up the source and ensure that WebAudio is driving things instead of |
606 // a microphone. For WebAudio, we always create a new capturer without | 605 // a microphone. For WebAudio, we always create a new capturer without |
607 // calling initialize(), WebAudio will re-configure the capturer later on. | 606 // calling initialize(), WebAudio will re-configure the capturer later on. |
608 // Pass -1 as the |render_view_id| and an empty device struct to tell the | 607 // Pass -1 as the |render_view_id| and an empty device struct to tell the |
609 // capturer not to start the default source. | 608 // capturer not to start the default source. |
610 scoped_refptr<WebRtcAudioCapturer> capturer( | 609 scoped_refptr<WebRtcAudioCapturer> capturer( |
611 MaybeCreateAudioCapturer(-1, StreamDeviceInfo())); | 610 MaybeCreateAudioCapturer(-1, StreamDeviceInfo())); |
612 DCHECK(capturer.get()); | 611 DCHECK(capturer.get()); |
613 | 612 |
614 scoped_refptr<WebAudioCapturerSource> | 613 scoped_refptr<WebAudioCapturerSource> |
615 webaudio_capturer_source(new WebAudioCapturerSource(capturer.get())); | 614 webaudio_capturer_source(new WebAudioCapturerSource(capturer.get())); |
616 MediaStreamSourceExtraData* source_data = | 615 MediaStreamSourceExtraData* source_data = |
617 new content::MediaStreamSourceExtraData(webaudio_capturer_source.get()); | 616 new content::MediaStreamSourceExtraData(webaudio_capturer_source.get()); |
618 | 617 |
619 // Create a LocalAudioSource object which holds audio options. | 618 // Create a LocalAudioSource object which holds audio options. |
620 // Use audio constraints where all values are true, i.e., enable | 619 // Use audio constraints where all values are true, i.e., enable |
621 // echo cancellation, automatic gain control, noise suppression and | 620 // echo cancellation, automatic gain control, noise suppression and |
622 // high-pass filter. SetLocalAudioSource() affects core audio parts in | 621 // high-pass filter. SetLocalAudioSource() affects core audio parts in |
623 // third_party/Libjingle. | 622 // third_party/Libjingle. |
624 WebAudioConstraints webaudio_audio_constraints_all_true; | 623 ApplyFixedWebAudioConstraints(constraints); |
625 source_data->SetLocalAudioSource( | 624 source_data->SetLocalAudioSource(CreateLocalAudioSource(constraints).get()); |
626 CreateLocalAudioSource(&webaudio_audio_constraints_all_true).get()); | |
627 source->setExtraData(source_data); | 625 source->setExtraData(source_data); |
628 | 626 |
629 // Replace the default source with WebAudio as source instead. | 627 // Replace the default source with WebAudio as source instead. |
630 source->addAudioConsumer(webaudio_capturer_source.get()); | 628 source->addAudioConsumer(webaudio_capturer_source.get()); |
631 | 629 |
632 return capturer; | 630 return capturer; |
633 } | 631 } |
634 | 632 |
635 scoped_refptr<webrtc::VideoTrackInterface> | 633 scoped_refptr<webrtc::VideoTrackInterface> |
636 MediaStreamDependencyFactory::CreateLocalVideoTrack( | 634 MediaStreamDependencyFactory::CreateLocalVideoTrack( |
(...skipping 15 matching lines...) Expand all Loading... | |
652 pc_factory_->CreateVideoSource(capturer, NULL).get(); | 650 pc_factory_->CreateVideoSource(capturer, NULL).get(); |
653 | 651 |
654 // Create native track from the source. | 652 // Create native track from the source. |
655 return pc_factory_->CreateVideoTrack(id, source.get()).get(); | 653 return pc_factory_->CreateVideoTrack(id, source.get()).get(); |
656 } | 654 } |
657 | 655 |
658 scoped_refptr<webrtc::AudioTrackInterface> | 656 scoped_refptr<webrtc::AudioTrackInterface> |
659 MediaStreamDependencyFactory::CreateLocalAudioTrack( | 657 MediaStreamDependencyFactory::CreateLocalAudioTrack( |
660 const std::string& id, | 658 const std::string& id, |
661 const scoped_refptr<WebRtcAudioCapturer>& capturer, | 659 const scoped_refptr<WebRtcAudioCapturer>& capturer, |
662 webrtc::AudioSourceInterface* source) { | 660 webrtc::AudioSourceInterface* source, |
661 const webrtc::MediaConstraintsInterface* constraints) { | |
663 // TODO(xians): Merge |source| to the capturer(). We can't do this today | 662 // TODO(xians): Merge |source| to the capturer(). We can't do this today |
664 // because only one capturer() is supported while one |source| is created | 663 // because only one capturer() is supported while one |source| is created |
665 // for each audio track. | 664 // for each audio track. |
666 scoped_refptr<WebRtcLocalAudioTrack> audio_track( | 665 scoped_refptr<WebRtcLocalAudioTrack> audio_track( |
667 WebRtcLocalAudioTrack::Create(id, capturer, source)); | 666 WebRtcLocalAudioTrack::Create(id, capturer, source, constraints)); |
668 // Add the WebRtcAudioDevice as the sink to the local audio track. | 667 // Add the WebRtcAudioDevice as the sink to the local audio track. |
669 audio_track->AddSink(GetWebRtcAudioDevice()); | 668 audio_track->AddSink(GetWebRtcAudioDevice()); |
670 // Start the audio track. This will hook the |audio_track| to the capturer | 669 // Start the audio track. This will hook the |audio_track| to the capturer |
671 // as the sink of the audio, and only start the source of the capturer if | 670 // as the sink of the audio, and only start the source of the capturer if |
672 // it is the first audio track connecting to the capturer. | 671 // it is the first audio track connecting to the capturer. |
673 audio_track->Start(); | 672 audio_track->Start(); |
674 return audio_track; | 673 return audio_track; |
675 } | 674 } |
676 | 675 |
677 webrtc::SessionDescriptionInterface* | 676 webrtc::SessionDescriptionInterface* |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
823 } | 822 } |
824 | 823 |
825 // Add the capturer to the WebRtcAudioDeviceImpl if it is a new capturer. | 824 // Add the capturer to the WebRtcAudioDeviceImpl if it is a new capturer. |
826 if (is_new_capturer) | 825 if (is_new_capturer) |
827 GetWebRtcAudioDevice()->AddAudioCapturer(capturer); | 826 GetWebRtcAudioDevice()->AddAudioCapturer(capturer); |
828 | 827 |
829 return capturer; | 828 return capturer; |
830 } | 829 } |
831 | 830 |
832 } // namespace content | 831 } // namespace content |
OLD | NEW |