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 293ff36c15cc52bb58e0edc8c0f0ae7ef91255a0..9dddd4289349a1d23f6a2a551a559e4fc525baab 100644 |
--- a/content/renderer/media/webrtc_audio_device_impl.cc |
+++ b/content/renderer/media/webrtc_audio_device_impl.cc |
@@ -18,6 +18,10 @@ |
using media::AudioParameters; |
using media::ChannelLayout; |
+namespace { |
+ int g_capturer_id_counter = 0; |
no longer working on chromium
2014/06/16 18:30:55
why? can't it be a member instead?
Henrik Grunell
2014/06/17 20:21:41
Right, it can. Done.
|
+} |
+ |
namespace content { |
WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl() |
@@ -227,6 +231,16 @@ int32_t WebRtcAudioDeviceImpl::Init() { |
DVLOG(1) << "WebRtcAudioDeviceImpl::Init()"; |
DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()) { |
no longer working on chromium
2014/06/16 18:30:55
WebRtcAudioDeviceImpl is not the right place for a
Henrik Grunell
2014/06/17 20:21:41
After discussing offline I understand that this is
|
+ aec_dump_message_filter_ = AecDumpMessageFilter::Get(); |
+ DCHECK(aec_dump_message_filter_); |
no longer working on chromium
2014/06/16 18:30:55
you don't need this DCHECK(), the following line w
Henrik Grunell
2014/06/17 20:21:41
Done.
|
+ aec_dump_message_filter_->SetObserver(this); |
+ for (CapturerMap::const_iterator iter = capturers_.begin(); |
+ iter != capturers_.end(); ++iter) { |
+ RegisterAecDumpForId(iter->first); |
no longer working on chromium
2014/06/16 18:30:55
indentation.
Henrik Grunell
2014/06/17 20:21:41
Done.
|
+ } |
+ } |
+ |
// We need to return a success to continue the initialization of WebRtc VoE |
// because failure on the capturer_ initialization should not prevent WebRTC |
// from working. See issue http://crbug.com/144421 for details. |
@@ -249,17 +263,22 @@ int32_t WebRtcAudioDeviceImpl::Terminate() { |
DCHECK(!renderer_.get() || !renderer_->IsStarted()) |
<< "The shared audio renderer shouldn't be running"; |
+ if (aec_dump_message_filter_) { |
+ aec_dump_message_filter_->SetObserver(NULL); |
no longer working on chromium
2014/06/16 18:30:55
if you have more than 1 tab using webrtc, this Set
Henrik Grunell
2014/06/17 20:21:41
This is changed now. MSAP is a delegate instead.
|
+ aec_dump_message_filter_ = NULL; |
+ } |
+ |
DisableAecDump(); |
// 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; |
+ CapturerMap capturers; |
capturers.swap(capturers_); |
- for (CapturerList::const_iterator iter = capturers.begin(); |
+ for (CapturerMap::const_iterator iter = capturers.begin(); |
iter != capturers.end(); ++iter) { |
- (*iter)->Stop(); |
+ iter->second->Stop(); |
} |
initialized_ = false; |
@@ -450,6 +469,32 @@ int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate( |
return 0; |
} |
+void WebRtcAudioDeviceImpl::OnAecDumpFile( |
+ int id, |
+ const IPC::PlatformFileForTransit& file_handle) { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ base::File file = IPC::PlatformFileForTransitToFile(file_handle); |
+ DCHECK(file.IsValid()); |
+ |
+ CapturerMap::iterator iter = capturers_.find(id); |
+ if (iter != capturers_.end()) { |
+ iter->second->StartAecDump(file.Pass()); |
+ } else { |
+ // The capturer has been removed. |
+ file.Close(); |
+ } |
+} |
+ |
+void WebRtcAudioDeviceImpl::OnDisableAecDump() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ DisableAecDump(); |
+} |
+ |
+void WebRtcAudioDeviceImpl::OnIpcClosed() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ aec_dump_message_filter_ = NULL; |
+} |
+ |
bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(renderer); |
@@ -471,17 +516,18 @@ void WebRtcAudioDeviceImpl::AddAudioCapturer( |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(capturer.get()); |
DCHECK(!capturer->device_id().empty()); |
+ |
+ int id = g_capturer_id_counter++; |
Tom Sepez
2014/06/16 17:33:18
why is it OK to increment this outside the lock?
Henrik Grunell
2014/06/17 20:21:41
This has been removed, ids are handled in the mess
|
{ |
base::AutoLock auto_lock(lock_); |
- DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) == |
- capturers_.end()); |
- capturers_.push_back(capturer); |
+ DCHECK(capturers_.find(id) == capturers_.end()); |
+ for (CapturerMap::const_iterator iter = capturers_.begin(); |
+ iter != capturers_.end(); ++iter) { |
+ DCHECK(capturer != iter->second); |
+ } |
+ capturers_[id] = capturer; |
} |
- |
- // Start the Aec dump if the Aec dump has been enabled and has not been |
- // started. |
- if (aec_dump_file_.IsValid()) |
- MaybeStartAecDump(); |
+ RegisterAecDumpForId(id); |
} |
void WebRtcAudioDeviceImpl::RemoveAudioCapturer( |
@@ -489,16 +535,38 @@ void WebRtcAudioDeviceImpl::RemoveAudioCapturer( |
DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()"; |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(capturer.get()); |
- base::AutoLock auto_lock(lock_); |
- capturers_.remove(capturer); |
+ |
+ int id = -1; |
+ { |
+ base::AutoLock auto_lock(lock_); |
+ for (CapturerMap::iterator iter = capturers_.begin(); |
+ iter != capturers_.end(); ++iter) { |
+ if (iter->second == capturer) { |
+ id = iter->first; |
+ capturers_.erase(iter); |
+ break; |
+ } |
+ } |
+ } |
+ DCHECK_GE(id, 0); |
+ |
+ if (aec_dump_message_filter_) { |
+ aec_dump_message_filter_->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &AecDumpMessageFilter::UnregisterAecDumpConsumer, |
+ aec_dump_message_filter_, |
+ id)); |
+ } |
} |
scoped_refptr<WebRtcAudioCapturer> |
WebRtcAudioDeviceImpl::GetDefaultCapturer() const { |
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(); |
+ // the default capture device. The last capturer will have the largest key, |
+ // so it will be last entry in the map. |
+ return capturers_.empty() ? NULL : capturers_.rbegin()->second; |
} |
void WebRtcAudioDeviceImpl::AddPlayoutSink( |
@@ -533,48 +601,24 @@ bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer( |
session_id, output_sample_rate, output_frames_per_buffer); |
} |
-void WebRtcAudioDeviceImpl::EnableAecDump(base::File aec_dump_file) { |
+void WebRtcAudioDeviceImpl::RegisterAecDumpForId(int id) { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(aec_dump_file.IsValid()); |
- |
- // Close the previous AEC dump file description if it has not been consumed. |
- // This can happen if no getUserMedia has been made yet. |
- // TODO(xians): DCHECK(!aec_dump_file_.IsValid()) after the browser |
- // guarantees it won't call EnableAecDump() more than once in a row. |
- if (aec_dump_file_.IsValid()) |
- aec_dump_file_.Close(); |
- |
- aec_dump_file_ = aec_dump_file.Pass(); |
- MaybeStartAecDump(); |
+ if (aec_dump_message_filter_) { |
+ aec_dump_message_filter_->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ base::Bind( |
+ &AecDumpMessageFilter::RegisterAecDumpConsumer, |
+ aec_dump_message_filter_, |
+ id)); |
+ } |
} |
void WebRtcAudioDeviceImpl::DisableAecDump() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
- // Simply invalidate the |aec_dump_file_| if we have not pass the ownership |
- // to WebRtc. |
- if (aec_dump_file_.IsValid()) { |
- aec_dump_file_.Close(); |
- return; |
- } |
- |
- // We might have call StartAecDump() on one of the capturer. Loop |
- // through all the capturers and call StopAecDump() on each of them. |
- for (CapturerList::const_iterator iter = capturers_.begin(); |
+ for (CapturerMap::const_iterator iter = capturers_.begin(); |
iter != capturers_.end(); ++iter) { |
- (*iter)->StopAecDump(); |
+ iter->second->StopAecDump(); |
} |
} |
-void WebRtcAudioDeviceImpl::MaybeStartAecDump() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(aec_dump_file_.IsValid()); |
- |
- // Start the Aec dump on the current default capturer. |
- scoped_refptr<WebRtcAudioCapturer> default_capturer(GetDefaultCapturer()); |
- if (!default_capturer) |
- return; |
- |
- default_capturer->StartAecDump(aec_dump_file_.Pass()); |
-} |
- |
} // namespace content |