| 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. |
| 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 |