Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: content/renderer/media/media_stream_impl.cc

Issue 23731007: Implicit audio output device selection for getUserMedia. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_impl.h" 5 #include "content/renderer/media/media_stream_impl.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "content/public/common/desktop_media_id.h" 13 #include "content/public/common/desktop_media_id.h"
14 #include "content/renderer/media/media_stream_audio_renderer.h" 14 #include "content/renderer/media/media_stream_audio_renderer.h"
15 #include "content/renderer/media/media_stream_dependency_factory.h" 15 #include "content/renderer/media/media_stream_dependency_factory.h"
16 #include "content/renderer/media/media_stream_dispatcher.h" 16 #include "content/renderer/media/media_stream_dispatcher.h"
17 #include "content/renderer/media/media_stream_extra_data.h" 17 #include "content/renderer/media/media_stream_extra_data.h"
18 #include "content/renderer/media/media_stream_source_extra_data.h" 18 #include "content/renderer/media/media_stream_source_extra_data.h"
19 #include "content/renderer/media/rtc_video_renderer.h" 19 #include "content/renderer/media/rtc_video_renderer.h"
20 #include "content/renderer/media/webrtc_audio_capturer.h" 20 #include "content/renderer/media/webrtc_audio_capturer.h"
21 #include "content/renderer/media/webrtc_audio_renderer.h" 21 #include "content/renderer/media/webrtc_audio_renderer.h"
22 #include "content/renderer/media/webrtc_local_audio_renderer.h" 22 #include "content/renderer/media/webrtc_local_audio_renderer.h"
23 #include "content/renderer/media/webrtc_uma_histograms.h" 23 #include "content/renderer/media/webrtc_uma_histograms.h"
24 #include "content/renderer/render_thread_impl.h"
25 #include "media/base/audio_hardware_config.h"
24 #include "third_party/WebKit/public/platform/WebMediaConstraints.h" 26 #include "third_party/WebKit/public/platform/WebMediaConstraints.h"
25 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 27 #include "third_party/WebKit/public/platform/WebMediaStreamSource.h"
26 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 28 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
27 #include "third_party/WebKit/public/platform/WebVector.h" 29 #include "third_party/WebKit/public/platform/WebVector.h"
28 #include "third_party/WebKit/public/web/WebDocument.h" 30 #include "third_party/WebKit/public/web/WebDocument.h"
29 #include "third_party/WebKit/public/web/WebFrame.h" 31 #include "third_party/WebKit/public/web/WebFrame.h"
30 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" 32 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h"
31 33
32 namespace content { 34 namespace content {
33 namespace { 35 namespace {
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 } 587 }
586 588
587 scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer( 589 scoped_refptr<WebRtcAudioRenderer> MediaStreamImpl::CreateRemoteAudioRenderer(
588 webrtc::MediaStreamInterface* stream) { 590 webrtc::MediaStreamInterface* stream) {
589 if (stream->GetAudioTracks().empty()) 591 if (stream->GetAudioTracks().empty())
590 return NULL; 592 return NULL;
591 593
592 DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:" 594 DVLOG(1) << "MediaStreamImpl::CreateRemoteAudioRenderer label:"
593 << stream->label(); 595 << stream->label();
594 596
595 return new WebRtcAudioRenderer(RenderViewObserver::routing_id()); 597 int session_id = -1, sample_rate = 0, buffer_size = 0;
598 if (!GetAuthorizedInputDeviceSessionIdForAudioRenderer(&session_id,
599 &sample_rate,
600 &buffer_size)) {
601 // Fetch the default audio output hardware config.
602 media::AudioHardwareConfig* hardware_config =
603 RenderThreadImpl::current()->GetAudioHardwareConfig();
604 sample_rate = hardware_config->GetOutputSampleRate();
605 buffer_size = hardware_config->GetOutputBufferSize();
606 // Use session_id of 0 to indicate no association with the capture device
Jói 2013/09/06 14:49:26 Above you use a guard of -1, which is correct?
tommi (sloooow) - chröme 2013/09/06 16:56:54 I changed it to 0 for consistency with what's used
607 // (i.e. use the default device).
608 session_id = 0;
609 }
610
611 return new WebRtcAudioRenderer(RenderViewObserver::routing_id(),
612 session_id, sample_rate, buffer_size);
596 } 613 }
597 614
598 scoped_refptr<WebRtcLocalAudioRenderer> 615 scoped_refptr<WebRtcLocalAudioRenderer>
599 MediaStreamImpl::CreateLocalAudioRenderer( 616 MediaStreamImpl::CreateLocalAudioRenderer(
600 webrtc::MediaStreamInterface* stream) { 617 webrtc::MediaStreamInterface* stream) {
601 if (stream->GetAudioTracks().empty()) 618 if (stream->GetAudioTracks().empty())
602 return NULL; 619 return NULL;
603 620
604 DVLOG(1) << "MediaStreamImpl::CreateLocalAudioRenderer label:" 621 DVLOG(1) << "MediaStreamImpl::CreateLocalAudioRenderer label:"
605 << stream->label(); 622 << stream->label();
606 623
607 webrtc::AudioTrackVector audio_tracks = stream->GetAudioTracks(); 624 webrtc::AudioTrackVector audio_tracks = stream->GetAudioTracks();
608 DCHECK_EQ(audio_tracks.size(), 1u); 625 DCHECK_EQ(audio_tracks.size(), 1u);
609 webrtc::AudioTrackInterface* audio_track = audio_tracks[0]; 626 webrtc::AudioTrackInterface* audio_track = audio_tracks[0];
610 DVLOG(1) << "audio_track.kind : " << audio_track->kind() 627 DVLOG(1) << "audio_track.kind : " << audio_track->kind()
611 << "audio_track.id : " << audio_track->id() 628 << "audio_track.id : " << audio_track->id()
612 << "audio_track.enabled: " << audio_track->enabled(); 629 << "audio_track.enabled: " << audio_track->enabled();
613 630
631 int session_id = -1, sample_rate = 0, buffer_size = 0;
Jói 2013/09/06 14:49:26 Same code, DRY.
tommi (sloooow) - chröme 2013/09/06 16:56:54 Done.
632 if (!GetAuthorizedInputDeviceSessionIdForAudioRenderer(&session_id,
633 &sample_rate,
634 &buffer_size)) {
635 // Fetch the default audio output hardware config.
636 media::AudioHardwareConfig* hardware_config =
637 RenderThreadImpl::current()->GetAudioHardwareConfig();
638 sample_rate = hardware_config->GetOutputSampleRate();
639 buffer_size = hardware_config->GetOutputBufferSize();
640 // Use session_id of 0 to indicate no association with the capture device
641 // (i.e. use the default device).
642 session_id = 0;
643 }
644
614 // Create a new WebRtcLocalAudioRenderer instance and connect it to the 645 // Create a new WebRtcLocalAudioRenderer instance and connect it to the
615 // existing WebRtcAudioCapturer so that the renderer can use it as source. 646 // existing WebRtcAudioCapturer so that the renderer can use it as source.
616 return new WebRtcLocalAudioRenderer( 647 return new WebRtcLocalAudioRenderer(
617 static_cast<WebRtcLocalAudioTrack*>(audio_track), 648 static_cast<WebRtcLocalAudioTrack*>(audio_track),
618 RenderViewObserver::routing_id()); 649 RenderViewObserver::routing_id(),
650 session_id,
651 sample_rate,
652 buffer_size);
619 } 653 }
620 654
621 void MediaStreamImpl::StopLocalAudioTrack( 655 void MediaStreamImpl::StopLocalAudioTrack(
622 const WebKit::WebMediaStream& web_stream) { 656 const WebKit::WebMediaStream& web_stream) {
623 MediaStreamExtraData* extra_data = static_cast<MediaStreamExtraData*>( 657 MediaStreamExtraData* extra_data = static_cast<MediaStreamExtraData*>(
624 web_stream.extraData()); 658 web_stream.extraData());
625 if (extra_data && extra_data->is_local() && extra_data->stream().get() && 659 if (extra_data && extra_data->is_local() && extra_data->stream().get() &&
626 !extra_data->stream()->GetAudioTracks().empty()) { 660 !extra_data->stream()->GetAudioTracks().empty()) {
627 webrtc::AudioTrackVector audio_tracks = 661 webrtc::AudioTrackVector audio_tracks =
628 extra_data->stream()->GetAudioTracks(); 662 extra_data->stream()->GetAudioTracks();
629 for (size_t i = 0; i < audio_tracks.size(); ++i) { 663 for (size_t i = 0; i < audio_tracks.size(); ++i) {
630 WebRtcLocalAudioTrack* audio_track = static_cast<WebRtcLocalAudioTrack*>( 664 WebRtcLocalAudioTrack* audio_track = static_cast<WebRtcLocalAudioTrack*>(
631 audio_tracks[i].get()); 665 audio_tracks[i].get());
632 // Remove the WebRtcAudioDevice as the sink to the local audio track. 666 // Remove the WebRtcAudioDevice as the sink to the local audio track.
633 audio_track->RemoveSink(dependency_factory_->GetWebRtcAudioDevice()); 667 audio_track->RemoveSink(dependency_factory_->GetWebRtcAudioDevice());
634 // Stop the audio track. This will unhook the audio track from the 668 // Stop the audio track. This will unhook the audio track from the
635 // capturer and will shutdown the source of the capturer if it is the 669 // capturer and will shutdown the source of the capturer if it is the
636 // last audio track connecting to the capturer. 670 // last audio track connecting to the capturer.
637 audio_track->Stop(); 671 audio_track->Stop();
638 } 672 }
639 } 673 }
640 } 674 }
641 675
676 bool MediaStreamImpl::GetAuthorizedInputDeviceSessionIdForAudioRenderer(
no longer working on chromium 2013/09/06 15:17:37 The name does not completely fit to its functional
tommi (sloooow) - chröme 2013/09/06 16:56:54 Done (fixed typo).
677 int* session_id,
678 int* output_sample_rate,
679 int* output_frames_per_buffer) {
680 DCHECK(CalledOnValidThread());
681
682 const StreamDeviceInfo* device_info = NULL;
683 WebKit::WebString device_id;
684 UserMediaRequests::iterator it = user_media_requests_.begin();
685 for (; it != user_media_requests_.end(); ++it) {
686 UserMediaRequestInfo* request = (*it);
687 for (size_t i = 0; i < request->audio_sources.size(); ++i) {
688 const WebKit::WebMediaStreamSource& source = request->audio_sources[i];
689 if (source.readyState() == WebKit::WebMediaStreamSource::ReadyStateEnded)
690 continue;
691
692 if (!device_id.isEmpty() && !device_id.equals(source.deviceId())) {
693 DLOG(WARNING)
Jói 2013/09/06 14:49:26 Not sure this is "bad" enough to demand a warning;
tommi (sloooow) - chröme 2013/09/06 16:56:54 Yeah, that's why I picked DLOG so that while debug
694 << "Multiple capture devices are open so we can't pick a "
695 "session for a matching output device.";
696 return false;
697 }
698
699 device_id = source.deviceId();
no longer working on chromium 2013/09/06 15:17:37 this should be the session_id
tommi (sloooow) - chröme 2013/09/06 16:56:54 Renamed the variable. Also added a todo to store
700 content::MediaStreamSourceExtraData* extra_data =
701 static_cast<content::MediaStreamSourceExtraData*>(source.extraData());
702 device_info = &extra_data->device_info();
703 }
704 }
705
706 if (device_id.isEmpty() || !device_info)
707 return false;
708
709 base::StringToInt(UTF16ToUTF8(device_id), session_id);
710 *output_sample_rate = device_info->device.matched_output.sample_rate;
711 *output_frames_per_buffer =
712 device_info->device.matched_output.frames_per_buffer;
713
714 return true;
715 }
716
642 MediaStreamSourceExtraData::MediaStreamSourceExtraData( 717 MediaStreamSourceExtraData::MediaStreamSourceExtraData(
643 const StreamDeviceInfo& device_info, 718 const StreamDeviceInfo& device_info,
644 const WebKit::WebMediaStreamSource& webkit_source) 719 const WebKit::WebMediaStreamSource& webkit_source)
645 : device_info_(device_info), 720 : device_info_(device_info),
646 webkit_source_(webkit_source) { 721 webkit_source_(webkit_source) {
647 } 722 }
648 723
649 MediaStreamSourceExtraData::MediaStreamSourceExtraData( 724 MediaStreamSourceExtraData::MediaStreamSourceExtraData(
650 media::AudioCapturerSource* source) 725 media::AudioCapturerSource* source)
651 : audio_source_(source) { 726 : audio_source_(source) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 } 772 }
698 773
699 for (size_t i = 0; i < video_sources.size(); ++i) { 774 for (size_t i = 0; i < video_sources.size(); ++i) {
700 video_sources[i].setReadyState( 775 video_sources[i].setReadyState(
701 WebKit::WebMediaStreamSource::ReadyStateEnded); 776 WebKit::WebMediaStreamSource::ReadyStateEnded);
702 video_sources[i].setExtraData(NULL); 777 video_sources[i].setExtraData(NULL);
703 } 778 }
704 } 779 }
705 780
706 } // namespace content 781 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698