Index: content/renderer/media/webrtc_audio_device_impl.cc |
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc |
index 17a058506df29f8345c98812840b888f9844ae4a..b5dc5008ad7ff831a8de3c05ff9d9795c005d950 100644 |
--- a/content/renderer/media/webrtc_audio_device_impl.cc |
+++ b/content/renderer/media/webrtc_audio_device_impl.cc |
@@ -170,9 +170,15 @@ |
DCHECK(!renderer_.get() || !renderer_->IsStarted()) |
<< "The shared audio renderer shouldn't be running"; |
- { |
- base::AutoLock auto_lock(lock_); |
- capturers_.clear(); |
+ // Stop all the capturers to ensure no further OnData() and |
+ // RemoveAudioCapturer() callback. |
+ // Cache the capturers in a local list since WebRtcAudioCapturer::Stop() |
+ // will trigger RemoveAudioCapturer() callback. |
+ CapturerList capturers; |
+ capturers.swap(capturers_); |
+ for (CapturerList::const_iterator iter = capturers.begin(); |
+ iter != capturers.end(); ++iter) { |
+ (*iter)->Stop(); |
} |
initialized_ = false; |
@@ -288,10 +294,11 @@ |
// Only one microphone is supported at the moment, which is represented by |
// the default capturer. |
- base::AutoLock auto_lock(lock_); |
- if (capturers_.empty()) |
+ scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); |
+ if (!capturer.get()) |
return -1; |
- capturers_.back()->SetVolume(volume); |
+ |
+ capturer->SetVolume(volume); |
return 0; |
} |
@@ -302,10 +309,12 @@ |
// We only support one microphone now, which is accessed via the default |
// capturer. |
DCHECK(initialized_); |
- base::AutoLock auto_lock(lock_); |
- if (capturers_.empty()) |
+ scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); |
+ if (!capturer.get()) |
return -1; |
- *volume = static_cast<uint32_t>(capturers_.back()->Volume()); |
+ |
+ *volume = static_cast<uint32_t>(capturer->Volume()); |
+ |
return 0; |
} |
@@ -343,10 +352,11 @@ |
// TODO(xians): These kind of hardware methods do not make much sense since we |
// support multiple sources. Remove or figure out new APIs for such methods. |
- base::AutoLock auto_lock(lock_); |
- if (capturers_.empty()) |
+ scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); |
+ if (!capturer.get()) |
return -1; |
- *available = (capturers_.back()->GetInputFormat().channels() == 2); |
+ |
+ *available = (capturer->source_audio_parameters().channels() == 2); |
return 0; |
} |
@@ -370,11 +380,12 @@ |
uint32_t* sample_rate) const { |
DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
// We use the default capturer as the recording sample rate. |
- base::AutoLock auto_lock(lock_); |
- if (capturers_.empty()) |
+ scoped_refptr<WebRtcAudioCapturer> capturer(GetDefaultCapturer()); |
+ if (!capturer.get()) |
return -1; |
- const media::AudioParameters& params = capturers_.back()->GetInputFormat(); |
- *sample_rate = static_cast<uint32_t>(params.sample_rate()); |
+ |
+ *sample_rate = static_cast<uint32_t>( |
+ capturer->source_audio_parameters().sample_rate()); |
return 0; |
} |
@@ -422,11 +433,12 @@ |
return true; |
} |
-void WebRtcAudioDeviceImpl::AddAudioCapturer(WebRtcAudioCapturer* capturer) { |
+void WebRtcAudioDeviceImpl::AddAudioCapturer( |
+ const scoped_refptr<WebRtcAudioCapturer>& capturer) { |
DCHECK(main_thread_checker_.CalledOnValidThread()); |
DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; |
- DCHECK(capturer); |
- DCHECK(!capturer->device_info().device.id.empty()); |
+ DCHECK(capturer.get()); |
+ DCHECK(!capturer->device_id().empty()); |
base::AutoLock auto_lock(lock_); |
DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) == |
@@ -434,12 +446,27 @@ |
capturers_.push_back(capturer); |
} |
-void WebRtcAudioDeviceImpl::RemoveAudioCapturer(WebRtcAudioCapturer* capturer) { |
- DCHECK(main_thread_checker_.CalledOnValidThread()); |
- DVLOG(1) << "WebRtcAudioDeviceImpl::RemoveAudioCapturer()"; |
- DCHECK(capturer); |
+void WebRtcAudioDeviceImpl::RemoveAudioCapturer( |
+ const scoped_refptr<WebRtcAudioCapturer>& capturer) { |
+ DCHECK(main_thread_checker_.CalledOnValidThread()); |
+ DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; |
+ DCHECK(capturer.get()); |
base::AutoLock auto_lock(lock_); |
capturers_.remove(capturer); |
+} |
+ |
+scoped_refptr<WebRtcAudioCapturer> |
+WebRtcAudioDeviceImpl::GetDefaultCapturer() const { |
+ // Called on the signaling thread (during initialization), worker |
+ // thread during capture or main thread for a WebAudio source. |
+ // We can't DCHECK on those three checks here since GetDefaultCapturer |
+ // may be the first call and therefore could incorrectly initialize the |
+ // thread checkers. |
+ DCHECK(initialized_); |
+ base::AutoLock auto_lock(lock_); |
+ // Use the last |capturer| which is from the latest getUserMedia call as |
+ // the default capture device. |
+ return capturers_.empty() ? NULL : capturers_.back(); |
} |
void WebRtcAudioDeviceImpl::AddPlayoutSink( |
@@ -471,20 +498,8 @@ |
if (capturers_.size() != 1) |
return false; |
- // Don't set output parameters unless all of them are valid. |
- const StreamDeviceInfo& device_info = capturers_.back()->device_info(); |
- if (device_info.session_id <= 0 || |
- !device_info.device.matched_output.sample_rate || |
- !device_info.device.matched_output.frames_per_buffer) { |
- return false; |
- } |
- |
- *session_id = device_info.session_id; |
- *output_sample_rate = device_info.device.matched_output.sample_rate; |
- *output_frames_per_buffer = |
- device_info.device.matched_output.frames_per_buffer; |
- |
- return true; |
+ return capturers_.back()->GetPairedOutputParameters( |
+ session_id, output_sample_rate, output_frames_per_buffer); |
} |
} // namespace content |