OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/webrtc/peer_connection_dependency_factory.h" | 5 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | |
13 #include "base/bind_helpers.h" | |
14 #include "base/command_line.h" | 12 #include "base/command_line.h" |
15 #include "base/location.h" | 13 #include "base/location.h" |
16 #include "base/logging.h" | 14 #include "base/logging.h" |
17 #include "base/macros.h" | 15 #include "base/macros.h" |
18 #include "base/metrics/field_trial.h" | 16 #include "base/metrics/field_trial.h" |
19 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
20 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
21 #include "base/synchronization/waitable_event.h" | 19 #include "base/synchronization/waitable_event.h" |
22 #include "build/build_config.h" | 20 #include "build/build_config.h" |
23 #include "content/common/media/media_stream_messages.h" | 21 #include "content/common/media/media_stream_messages.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 // microphone or tab audio. | 181 // microphone or tab audio. |
184 RTCMediaConstraints native_audio_constraints(audio_constraints); | 182 RTCMediaConstraints native_audio_constraints(audio_constraints); |
185 MediaAudioConstraints::ApplyFixedAudioConstraints(&native_audio_constraints); | 183 MediaAudioConstraints::ApplyFixedAudioConstraints(&native_audio_constraints); |
186 | 184 |
187 StreamDeviceInfo device_info = source_data->device_info(); | 185 StreamDeviceInfo device_info = source_data->device_info(); |
188 RTCMediaConstraints constraints = native_audio_constraints; | 186 RTCMediaConstraints constraints = native_audio_constraints; |
189 // May modify both |constraints| and |effects|. | 187 // May modify both |constraints| and |effects|. |
190 HarmonizeConstraintsAndEffects(&constraints, | 188 HarmonizeConstraintsAndEffects(&constraints, |
191 &device_info.device.input.effects); | 189 &device_info.device.input.effects); |
192 | 190 |
193 scoped_ptr<WebRtcAudioCapturer> capturer = CreateAudioCapturer( | 191 scoped_refptr<WebRtcAudioCapturer> capturer(CreateAudioCapturer( |
194 render_frame_id, device_info, audio_constraints, source_data); | 192 render_frame_id, device_info, audio_constraints, source_data)); |
195 if (!capturer.get()) { | 193 if (!capturer.get()) { |
196 const std::string log_string = | 194 const std::string log_string = |
197 "PCDF::InitializeMediaStreamAudioSource: fails to create capturer"; | 195 "PCDF::InitializeMediaStreamAudioSource: fails to create capturer"; |
198 WebRtcLogMessage(log_string); | 196 WebRtcLogMessage(log_string); |
199 DVLOG(1) << log_string; | 197 DVLOG(1) << log_string; |
200 // TODO(xians): Don't we need to check if source_observer is observing | 198 // TODO(xians): Don't we need to check if source_observer is observing |
201 // something? If not, then it looks like we have a leak here. | 199 // something? If not, then it looks like we have a leak here. |
202 // OTOH, if it _is_ observing something, then the callback might | 200 // OTOH, if it _is_ observing something, then the callback might |
203 // be called multiple times which is likely also a bug. | 201 // be called multiple times which is likely also a bug. |
204 return false; | 202 return false; |
205 } | 203 } |
206 source_data->SetAudioCapturer(std::move(capturer)); | 204 source_data->SetAudioCapturer(capturer.get()); |
207 | 205 |
208 // Creates a LocalAudioSource object which holds audio options. | 206 // Creates a LocalAudioSource object which holds audio options. |
209 // TODO(xians): The option should apply to the track instead of the source. | 207 // TODO(xians): The option should apply to the track instead of the source. |
210 // TODO(perkj): Move audio constraints parsing to Chrome. | 208 // TODO(perkj): Move audio constraints parsing to Chrome. |
211 // Currently there are a few constraints that are parsed by libjingle and | 209 // Currently there are a few constraints that are parsed by libjingle and |
212 // the state is set to ended if parsing fails. | 210 // the state is set to ended if parsing fails. |
213 scoped_refptr<webrtc::AudioSourceInterface> rtc_source( | 211 scoped_refptr<webrtc::AudioSourceInterface> rtc_source( |
214 CreateLocalAudioSource(&constraints).get()); | 212 CreateLocalAudioSource(&constraints).get()); |
215 if (rtc_source->state() != webrtc::MediaSourceInterface::kLive) { | 213 if (rtc_source->state() != webrtc::MediaSourceInterface::kLive) { |
216 DLOG(WARNING) << "Failed to create rtc LocalAudioSource."; | 214 DLOG(WARNING) << "Failed to create rtc LocalAudioSource."; |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 const webrtc::MediaConstraintsInterface* constraints) { | 527 const webrtc::MediaConstraintsInterface* constraints) { |
530 scoped_refptr<webrtc::AudioSourceInterface> source = | 528 scoped_refptr<webrtc::AudioSourceInterface> source = |
531 GetPcFactory()->CreateAudioSource(constraints).get(); | 529 GetPcFactory()->CreateAudioSource(constraints).get(); |
532 return source; | 530 return source; |
533 } | 531 } |
534 | 532 |
535 void PeerConnectionDependencyFactory::CreateLocalAudioTrack( | 533 void PeerConnectionDependencyFactory::CreateLocalAudioTrack( |
536 const blink::WebMediaStreamTrack& track) { | 534 const blink::WebMediaStreamTrack& track) { |
537 blink::WebMediaStreamSource source = track.source(); | 535 blink::WebMediaStreamSource source = track.source(); |
538 DCHECK_EQ(source.getType(), blink::WebMediaStreamSource::TypeAudio); | 536 DCHECK_EQ(source.getType(), blink::WebMediaStreamSource::TypeAudio); |
539 MediaStreamAudioSource* source_data = MediaStreamAudioSource::From(source); | 537 DCHECK(!source.remote()); |
| 538 MediaStreamAudioSource* source_data = |
| 539 static_cast<MediaStreamAudioSource*>(source.getExtraData()); |
540 | 540 |
| 541 scoped_refptr<WebAudioCapturerSource> webaudio_source; |
541 if (!source_data) { | 542 if (!source_data) { |
542 if (source.requiresAudioConsumer()) { | 543 if (source.requiresAudioConsumer()) { |
543 // We're adding a WebAudio MediaStream. | 544 // We're adding a WebAudio MediaStream. |
544 // Create a specific capturer for each WebAudio consumer. | 545 // Create a specific capturer for each WebAudio consumer. |
545 CreateWebAudioSource(&source); | 546 webaudio_source = CreateWebAudioSource(&source); |
546 source_data = MediaStreamAudioSource::From(source); | 547 source_data = static_cast<MediaStreamAudioSource*>(source.getExtraData()); |
547 DCHECK(source_data->webaudio_capturer()); | |
548 } else { | 548 } else { |
549 NOTREACHED() << "Local track missing MediaStreamAudioSource instance."; | 549 NOTREACHED() << "Local track missing source extra data."; |
550 return; | 550 return; |
551 } | 551 } |
552 } | 552 } |
553 | 553 |
554 // Creates an adapter to hold all the libjingle objects. | 554 // Creates an adapter to hold all the libjingle objects. |
555 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( | 555 scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter( |
556 WebRtcLocalAudioTrackAdapter::Create(track.id().utf8(), | 556 WebRtcLocalAudioTrackAdapter::Create(track.id().utf8(), |
557 source_data->local_audio_source())); | 557 source_data->local_audio_source())); |
558 static_cast<webrtc::AudioTrackInterface*>(adapter.get())->set_enabled( | 558 static_cast<webrtc::AudioTrackInterface*>(adapter.get())->set_enabled( |
559 track.isEnabled()); | 559 track.isEnabled()); |
560 | 560 |
561 // TODO(xians): Merge |source| to the capturer(). We can't do this today | 561 // TODO(xians): Merge |source| to the capturer(). We can't do this today |
562 // because only one capturer() is supported while one |source| is created | 562 // because only one capturer() is supported while one |source| is created |
563 // for each audio track. | 563 // for each audio track. |
564 scoped_ptr<WebRtcLocalAudioTrack> audio_track( | 564 scoped_ptr<WebRtcLocalAudioTrack> audio_track(new WebRtcLocalAudioTrack( |
565 new WebRtcLocalAudioTrack(adapter.get())); | 565 adapter.get(), source_data->GetAudioCapturer(), webaudio_source.get())); |
566 | 566 |
567 // Start the source and connect the audio data flow to the track. | 567 StartLocalAudioTrack(audio_track.get()); |
568 // | |
569 // TODO(miu): This logic will me moved to MediaStreamAudioSource (or a | |
570 // subclass of it) in soon-upcoming changes. | |
571 audio_track->Start(base::Bind(&MediaStreamAudioSource::StopAudioDeliveryTo, | |
572 source_data->GetWeakPtr(), | |
573 audio_track.get())); | |
574 if (source_data->webaudio_capturer()) | |
575 source_data->webaudio_capturer()->Start(audio_track.get()); | |
576 else if (source_data->audio_capturer()) | |
577 source_data->audio_capturer()->AddTrack(audio_track.get()); | |
578 else | |
579 NOTREACHED(); | |
580 | 568 |
581 // Pass the ownership of the native local audio track to the blink track. | 569 // Pass the ownership of the native local audio track to the blink track. |
582 blink::WebMediaStreamTrack writable_track = track; | 570 blink::WebMediaStreamTrack writable_track = track; |
583 writable_track.setExtraData(audio_track.release()); | 571 writable_track.setExtraData(audio_track.release()); |
584 } | 572 } |
585 | 573 |
586 void PeerConnectionDependencyFactory::CreateRemoteAudioTrack( | 574 void PeerConnectionDependencyFactory::CreateRemoteAudioTrack( |
587 const blink::WebMediaStreamTrack& track) { | 575 const blink::WebMediaStreamTrack& track) { |
588 blink::WebMediaStreamSource source = track.source(); | 576 blink::WebMediaStreamSource source = track.source(); |
589 DCHECK_EQ(source.getType(), blink::WebMediaStreamSource::TypeAudio); | 577 DCHECK_EQ(source.getType(), blink::WebMediaStreamSource::TypeAudio); |
590 DCHECK(source.remote()); | 578 DCHECK(source.remote()); |
591 DCHECK(MediaStreamAudioSource::From(source)); | 579 DCHECK(source.getExtraData()); |
592 | 580 |
593 blink::WebMediaStreamTrack writable_track = track; | 581 blink::WebMediaStreamTrack writable_track = track; |
594 writable_track.setExtraData( | 582 writable_track.setExtraData( |
595 new MediaStreamRemoteAudioTrack(source, track.isEnabled())); | 583 new MediaStreamRemoteAudioTrack(source, track.isEnabled())); |
596 } | 584 } |
597 | 585 |
598 void PeerConnectionDependencyFactory::CreateWebAudioSource( | 586 void PeerConnectionDependencyFactory::StartLocalAudioTrack( |
| 587 WebRtcLocalAudioTrack* audio_track) { |
| 588 // Start the audio track. This will hook the |audio_track| to the capturer |
| 589 // as the sink of the audio, and only start the source of the capturer if |
| 590 // it is the first audio track connecting to the capturer. |
| 591 audio_track->Start(); |
| 592 } |
| 593 |
| 594 scoped_refptr<WebAudioCapturerSource> |
| 595 PeerConnectionDependencyFactory::CreateWebAudioSource( |
599 blink::WebMediaStreamSource* source) { | 596 blink::WebMediaStreamSource* source) { |
600 DVLOG(1) << "PeerConnectionDependencyFactory::CreateWebAudioSource()"; | 597 DVLOG(1) << "PeerConnectionDependencyFactory::CreateWebAudioSource()"; |
601 | 598 |
| 599 scoped_refptr<WebAudioCapturerSource> |
| 600 webaudio_capturer_source(new WebAudioCapturerSource(*source)); |
602 MediaStreamAudioSource* source_data = new MediaStreamAudioSource(); | 601 MediaStreamAudioSource* source_data = new MediaStreamAudioSource(); |
603 source_data->SetWebAudioCapturer( | 602 |
604 make_scoped_ptr(new WebAudioCapturerSource(source))); | 603 // Use the current default capturer for the WebAudio track so that the |
| 604 // WebAudio track can pass a valid delay value and |need_audio_processing| |
| 605 // flag to PeerConnection. |
| 606 // TODO(xians): Remove this after moving APM to Chrome. |
| 607 if (GetWebRtcAudioDevice()) { |
| 608 source_data->SetAudioCapturer( |
| 609 GetWebRtcAudioDevice()->GetDefaultCapturer()); |
| 610 } |
605 | 611 |
606 // Create a LocalAudioSource object which holds audio options. | 612 // Create a LocalAudioSource object which holds audio options. |
607 // SetLocalAudioSource() affects core audio parts in third_party/Libjingle. | 613 // SetLocalAudioSource() affects core audio parts in third_party/Libjingle. |
608 source_data->SetLocalAudioSource(CreateLocalAudioSource(NULL).get()); | 614 source_data->SetLocalAudioSource(CreateLocalAudioSource(NULL).get()); |
609 source->setExtraData(source_data); | 615 source->setExtraData(source_data); |
| 616 |
| 617 // Replace the default source with WebAudio as source instead. |
| 618 source->addAudioConsumer(webaudio_capturer_source.get()); |
| 619 |
| 620 return webaudio_capturer_source; |
610 } | 621 } |
611 | 622 |
612 scoped_refptr<webrtc::VideoTrackInterface> | 623 scoped_refptr<webrtc::VideoTrackInterface> |
613 PeerConnectionDependencyFactory::CreateLocalVideoTrack( | 624 PeerConnectionDependencyFactory::CreateLocalVideoTrack( |
614 const std::string& id, | 625 const std::string& id, |
615 webrtc::VideoTrackSourceInterface* source) { | 626 webrtc::VideoTrackSourceInterface* source) { |
616 return GetPcFactory()->CreateVideoTrack(id, source).get(); | 627 return GetPcFactory()->CreateVideoTrack(id, source).get(); |
617 } | 628 } |
618 | 629 |
619 scoped_refptr<webrtc::VideoTrackInterface> | 630 scoped_refptr<webrtc::VideoTrackInterface> |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
740 // Stopping the thread will wait until all tasks have been | 751 // Stopping the thread will wait until all tasks have been |
741 // processed before returning. We wait for the above task to finish before | 752 // processed before returning. We wait for the above task to finish before |
742 // letting the the function continue to avoid any potential race issues. | 753 // letting the the function continue to avoid any potential race issues. |
743 chrome_worker_thread_.Stop(); | 754 chrome_worker_thread_.Stop(); |
744 } else { | 755 } else { |
745 NOTREACHED() << "Worker thread not running."; | 756 NOTREACHED() << "Worker thread not running."; |
746 } | 757 } |
747 } | 758 } |
748 } | 759 } |
749 | 760 |
750 scoped_ptr<WebRtcAudioCapturer> | 761 scoped_refptr<WebRtcAudioCapturer> |
751 PeerConnectionDependencyFactory::CreateAudioCapturer( | 762 PeerConnectionDependencyFactory::CreateAudioCapturer( |
752 int render_frame_id, | 763 int render_frame_id, |
753 const StreamDeviceInfo& device_info, | 764 const StreamDeviceInfo& device_info, |
754 const blink::WebMediaConstraints& constraints, | 765 const blink::WebMediaConstraints& constraints, |
755 MediaStreamAudioSource* audio_source) { | 766 MediaStreamAudioSource* audio_source) { |
756 // TODO(xians): Handle the cases when gUM is called without a proper render | 767 // TODO(xians): Handle the cases when gUM is called without a proper render |
757 // view, for example, by an extension. | 768 // view, for example, by an extension. |
758 DCHECK_GE(render_frame_id, 0); | 769 DCHECK_GE(render_frame_id, 0); |
759 | 770 |
760 EnsureWebRtcAudioDeviceImpl(); | 771 EnsureWebRtcAudioDeviceImpl(); |
(...skipping 24 matching lines...) Expand all Loading... |
785 } | 796 } |
786 | 797 |
787 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { | 798 void PeerConnectionDependencyFactory::EnsureWebRtcAudioDeviceImpl() { |
788 if (audio_device_.get()) | 799 if (audio_device_.get()) |
789 return; | 800 return; |
790 | 801 |
791 audio_device_ = new WebRtcAudioDeviceImpl(); | 802 audio_device_ = new WebRtcAudioDeviceImpl(); |
792 } | 803 } |
793 | 804 |
794 } // namespace content | 805 } // namespace content |
OLD | NEW |