summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-01 04:42:39 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-01 04:42:39 +0000
commit563d665f0a231e3a0237445b577b68bb9b3f212e (patch)
tree5f4b4dd7497f7fe94653850f3f4f3812fcecf4d8
parentccfa43f042db868f6584f9cceef94ca7c4ddf239 (diff)
downloadchromium_src-563d665f0a231e3a0237445b577b68bb9b3f212e.zip
chromium_src-563d665f0a231e3a0237445b577b68bb9b3f212e.tar.gz
chromium_src-563d665f0a231e3a0237445b577b68bb9b3f212e.tar.bz2
Introduce AudioHardwareConfig for renderer side audio device info.
As discussed, this creates a media::AudioHardwareConfig class lazily created, owned, and filled by RenderThreadImpl via a single synchronous IPC and updated via AudioMessageFilter. This change does not plumb part 2 where AudioRendererMixer recreates itself based on these device change updates. BUG=157216 TEST=New unittest. Device changes on Windows/Mac continue to work. Review URL: https://chromiumcodereview.appspot.com/11880009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@180068 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/media/audio_renderer_host.cc24
-rw-r--r--content/browser/renderer_host/media/audio_renderer_host.h5
-rw-r--r--content/browser/renderer_host/render_message_filter.cc32
-rw-r--r--content/browser/renderer_host/render_message_filter.h7
-rw-r--r--content/common/media/audio_messages.h7
-rw-r--r--content/common/view_messages.h19
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/renderer/media/audio_hardware.cc76
-rw-r--r--content/renderer/media/audio_hardware.h40
-rw-r--r--content/renderer/media/audio_message_filter.cc34
-rw-r--r--content/renderer/media/audio_message_filter.h29
-rw-r--r--content/renderer/media/audio_renderer_mixer_manager.cc12
-rw-r--r--content/renderer/media/audio_renderer_mixer_manager.h11
-rw-r--r--content/renderer/media/audio_renderer_mixer_manager_unittest.cc8
-rw-r--r--content/renderer/media/webrtc_audio_capturer.cc1
-rw-r--r--content/renderer/media/webrtc_audio_device_impl.cc1
-rw-r--r--content/renderer/media/webrtc_audio_device_unittest.cc95
-rw-r--r--content/renderer/media/webrtc_audio_renderer.cc19
-rw-r--r--content/renderer/pepper/pepper_platform_audio_output_impl.cc9
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.cc8
-rw-r--r--content/renderer/render_thread_impl.cc25
-rw-r--r--content/renderer/render_thread_impl.h10
-rw-r--r--content/renderer/renderer_webkitplatformsupport_impl.cc8
-rw-r--r--content/test/webrtc_audio_device_test.cc48
-rw-r--r--content/test/webrtc_audio_device_test.h23
-rw-r--r--media/audio/audio_output_controller.cc5
-rw-r--r--media/audio/audio_output_controller.h2
-rw-r--r--media/audio/audio_output_controller_unittest.cc3
-rw-r--r--media/base/audio_hardware_config.cc53
-rw-r--r--media/base/audio_hardware_config.h50
-rw-r--r--media/base/audio_hardware_config_unittest.cc50
-rw-r--r--media/media.gyp3
32 files changed, 400 insertions, 319 deletions
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc
index 3c87947..1901e2f 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -123,6 +123,17 @@ void AudioRendererHost::OnError(media::AudioOutputController* controller,
this, make_scoped_refptr(controller), error_code));
}
+void AudioRendererHost::OnDeviceChange(media::AudioOutputController* controller,
+ int new_buffer_size,
+ int new_sample_rate) {
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&AudioRendererHost::DoSendDeviceChangeMessage,
+ this, make_scoped_refptr(controller), new_buffer_size,
+ new_sample_rate));
+}
+
void AudioRendererHost::DoCompleteCreation(
media::AudioOutputController* controller) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -196,6 +207,19 @@ void AudioRendererHost::DoSendPausedMessage(
entry->stream_id, media::AudioOutputIPCDelegate::kPaused));
}
+void AudioRendererHost::DoSendDeviceChangeMessage(
+ media::AudioOutputController* controller, int new_buffer_size,
+ int new_sample_rate) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ AudioEntry* entry = LookupByController(controller);
+ if (!entry)
+ return;
+
+ Send(new AudioMsg_NotifyDeviceChanged(
+ entry->stream_id, new_buffer_size, new_sample_rate));
+}
+
void AudioRendererHost::DoHandleError(media::AudioOutputController* controller,
int error_code) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/content/browser/renderer_host/media/audio_renderer_host.h b/content/browser/renderer_host/media/audio_renderer_host.h
index 15ebf89..c90d717 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.h
+++ b/content/browser/renderer_host/media/audio_renderer_host.h
@@ -85,6 +85,9 @@ class CONTENT_EXPORT AudioRendererHost
virtual void OnPaused(media::AudioOutputController* controller) OVERRIDE;
virtual void OnError(media::AudioOutputController* controller,
int error_code) OVERRIDE;
+ virtual void OnDeviceChange(media::AudioOutputController* controller,
+ int new_buffer_size,
+ int new_sample_rate) OVERRIDE;
private:
friend class AudioRendererHostTest;
@@ -135,6 +138,8 @@ class CONTENT_EXPORT AudioRendererHost
// Send a state change message to the renderer.
void DoSendPlayingMessage(media::AudioOutputController* controller);
void DoSendPausedMessage(media::AudioOutputController* controller);
+ void DoSendDeviceChangeMessage(media::AudioOutputController* controller,
+ int new_buffer_size, int new_sample_rate);
// Handle error coming from audio stream.
void DoHandleError(media::AudioOutputController* controller, int error_code);
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc
index 5393f5a..aacc6e9 100644
--- a/content/browser/renderer_host/render_message_filter.cc
+++ b/content/browser/renderer_host/render_message_filter.cc
@@ -417,14 +417,8 @@ bool RenderMessageFilter::OnMessageReceived(const IPC::Message& message,
IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_Keygen, OnKeygen)
IPC_MESSAGE_HANDLER(ViewHostMsg_AsyncOpenFile, OnAsyncOpenFile)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetCPUUsage, OnGetCPUUsage)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareBufferSize,
- OnGetHardwareBufferSize)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareInputSampleRate,
- OnGetHardwareInputSampleRate)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareSampleRate,
- OnGetHardwareSampleRate)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareInputChannelLayout,
- OnGetHardwareInputChannelLayout)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig,
+ OnGetAudioHardwareConfig)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetMonitorColorProfile,
OnGetMonitorColorProfile)
IPC_MESSAGE_HANDLER(ViewHostMsg_MediaLogEvent, OnMediaLogEvent)
@@ -778,24 +772,16 @@ void RenderMessageFilter::OnGetCPUUsage(int* cpu_usage) {
*cpu_usage = cpu_usage_;
}
-void RenderMessageFilter::OnGetHardwareBufferSize(uint32* buffer_size) {
- *buffer_size = static_cast<uint32>(media::GetAudioHardwareBufferSize());
-}
+void RenderMessageFilter::OnGetAudioHardwareConfig(
+ int* output_buffer_size, int* output_sample_rate, int* input_sample_rate,
+ media::ChannelLayout* input_channel_layout) {
+ *output_buffer_size = media::GetAudioHardwareBufferSize();
+ *output_sample_rate = media::GetAudioHardwareSampleRate();
-void RenderMessageFilter::OnGetHardwareInputSampleRate(int* sample_rate) {
// TODO(henrika): add support for all available input devices.
- *sample_rate = media::GetAudioInputHardwareSampleRate(
+ *input_sample_rate = media::GetAudioInputHardwareSampleRate(
media::AudioManagerBase::kDefaultDeviceId);
-}
-
-void RenderMessageFilter::OnGetHardwareSampleRate(int* sample_rate) {
- *sample_rate = media::GetAudioHardwareSampleRate();
-}
-
-void RenderMessageFilter::OnGetHardwareInputChannelLayout(
- media::ChannelLayout* layout) {
- // TODO(henrika): add support for all available input devices.
- *layout = media::GetAudioInputHardwareChannelLayout(
+ *input_channel_layout = media::GetAudioInputHardwareChannelLayout(
media::AudioManagerBase::kDefaultDeviceId);
}
diff --git a/content/browser/renderer_host/render_message_filter.h b/content/browser/renderer_host/render_message_filter.h
index 1d77fb3..af6036e 100644
--- a/content/browser/renderer_host/render_message_filter.h
+++ b/content/browser/renderer_host/render_message_filter.h
@@ -189,10 +189,9 @@ class RenderMessageFilter : public BrowserMessageFilter {
void OnGetCPUUsage(int* cpu_usage);
- void OnGetHardwareBufferSize(uint32* buffer_size);
- void OnGetHardwareInputSampleRate(int* sample_rate);
- void OnGetHardwareSampleRate(int* sample_rate);
- void OnGetHardwareInputChannelLayout(media::ChannelLayout* layout);
+ void OnGetAudioHardwareConfig(int* output_buffer_size,
+ int* output_sample_rate, int* input_sample_rate,
+ media::ChannelLayout* input_channel_layout);
// Used to look up the monitor color profile.
void OnGetMonitorColorProfile(std::vector<char>* profile);
diff --git a/content/common/media/audio_messages.h b/content/common/media/audio_messages.h
index cac43d1..8977417 100644
--- a/content/common/media/audio_messages.h
+++ b/content/common/media/audio_messages.h
@@ -63,6 +63,13 @@ IPC_MESSAGE_CONTROL4(AudioInputMsg_NotifyStreamCreated,
uint32 /* length */)
#endif
+// Notification message sent from AudioRendererHost to renderer after an output
+// device change has occurred.
+IPC_MESSAGE_CONTROL3(AudioMsg_NotifyDeviceChanged,
+ int /* stream_id */,
+ int /* new_buffer_size */,
+ int /* new_sample_rate */)
+
// Notification message sent from AudioRendererHost to renderer for state
// update after the renderer has requested a Create/Start/Close.
IPC_MESSAGE_CONTROL2(AudioMsg_NotifyStreamStateChanged,
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 0b36fdc..4e064fa 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -720,20 +720,11 @@ IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GenerateRoutingID,
int /* routing_id */)
// Asks the browser for the default audio hardware buffer-size.
-IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetHardwareBufferSize,
- uint32 /* buffer_size */)
-
-// Asks the browser for the default audio input hardware sample-rate.
-IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetHardwareInputSampleRate,
- int /* sample_rate */)
-
-// Asks the browser for the default audio hardware sample-rate.
-IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetHardwareSampleRate,
- int /* sample_rate */)
-
-// Asks the browser for the default channel layout.
-IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetHardwareInputChannelLayout,
- media::ChannelLayout /* channel layout */)
+IPC_SYNC_MESSAGE_CONTROL0_4(ViewHostMsg_GetAudioHardwareConfig,
+ int /* output_buffer_size */,
+ int /* output_sample_rate */,
+ int /* input_sample_rate */,
+ media::ChannelLayout /* input_channel_layout */)
// Asks the browser for CPU usage of the renderer process in percents.
IPC_SYNC_MESSAGE_CONTROL0_1(ViewHostMsg_GetCPUUsage,
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 633717c..46b29b1 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -114,8 +114,6 @@
'renderer/load_progress_tracker.h',
'renderer/media/audio_device_factory.cc',
'renderer/media/audio_device_factory.h',
- 'renderer/media/audio_hardware.cc',
- 'renderer/media/audio_hardware.h',
'renderer/media/audio_input_message_filter.cc',
'renderer/media/audio_input_message_filter.h',
'renderer/media/audio_message_filter.cc',
diff --git a/content/renderer/media/audio_hardware.cc b/content/renderer/media/audio_hardware.cc
deleted file mode 100644
index 9f22a2d..0000000
--- a/content/renderer/media/audio_hardware.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/audio_hardware.h"
-
-#include "base/logging.h"
-#include "content/common/view_messages.h"
-#include "content/renderer/render_thread_impl.h"
-
-using media::ChannelLayout;
-using media::CHANNEL_LAYOUT_NONE;
-
-static int output_sample_rate = 0;
-static int input_sample_rate = 0;
-static size_t output_buffer_size = 0;
-static ChannelLayout input_channel_layout = CHANNEL_LAYOUT_NONE;
-
-namespace content {
-
-int GetAudioOutputSampleRate() {
- DCHECK(RenderThreadImpl::current() != NULL);
-
- if (!output_sample_rate) {
- RenderThreadImpl::current()->Send(
- new ViewHostMsg_GetHardwareSampleRate(&output_sample_rate));
- }
- return output_sample_rate;
-}
-
-int GetAudioInputSampleRate() {
- DCHECK(RenderThreadImpl::current() != NULL);
-
- if (!input_sample_rate) {
- RenderThreadImpl::current()->Send(
- new ViewHostMsg_GetHardwareInputSampleRate(&input_sample_rate));
- }
- return input_sample_rate;
-}
-
-size_t GetAudioOutputBufferSize() {
- DCHECK(RenderThreadImpl::current() != NULL);
-
- if (!output_buffer_size) {
- uint32 buffer_size = 0;
- RenderThreadImpl::current()->Send(
- new ViewHostMsg_GetHardwareBufferSize(&buffer_size));
- output_buffer_size = buffer_size;
- }
-
- return output_buffer_size;
-}
-
-ChannelLayout GetAudioInputChannelLayout() {
- DCHECK(RenderThreadImpl::current() != NULL);
-
- if (input_channel_layout == CHANNEL_LAYOUT_NONE) {
- ChannelLayout layout = CHANNEL_LAYOUT_NONE;
- RenderThreadImpl::current()->Send(
- new ViewHostMsg_GetHardwareInputChannelLayout(&layout));
- input_channel_layout = layout;
- }
-
- return input_channel_layout;
-}
-
-void ResetAudioCache() {
- DCHECK(RenderThreadImpl::current() != NULL);
-
- output_sample_rate = 0.0;
- input_sample_rate = 0.0;
- output_buffer_size = 0;
- input_channel_layout = CHANNEL_LAYOUT_NONE;
-}
-
-} // namespace content
diff --git a/content/renderer/media/audio_hardware.h b/content/renderer/media/audio_hardware.h
deleted file mode 100644
index 3171387..0000000
--- a/content/renderer/media/audio_hardware.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-#ifndef CONTENT_RENDERER_MEDIA_AUDIO_HARDWARE_H_
-#define CONTENT_RENDERER_MEDIA_AUDIO_HARDWARE_H_
-
-#include "base/basictypes.h"
-#include "content/common/content_export.h"
-#include "media/base/channel_layout.h"
-
-// This file contains static methods to query audio hardware properties from
-// the browser process. Values are cached to avoid unnecessary round trips,
-// but the cache can be cleared if needed (currently only used by tests).
-
-namespace content {
-
-// Fetch the sample rate of the default audio output end point device.
-// Must be called from RenderThreadImpl::current().
-CONTENT_EXPORT int GetAudioOutputSampleRate();
-
-// Fetch the sample rate of the default audio input end point device.
-// Must be called from RenderThreadImpl::current().
-CONTENT_EXPORT int GetAudioInputSampleRate();
-
-// Fetch the buffer size we use for the default output device.
-// Must be called from RenderThreadImpl::current().
-// Must be used in conjunction with AUDIO_PCM_LOW_LATENCY.
-CONTENT_EXPORT size_t GetAudioOutputBufferSize();
-
-// Fetch the audio channel layout for the default input device.
-// Must be called from RenderThreadImpl::current().
-CONTENT_EXPORT media::ChannelLayout GetAudioInputChannelLayout();
-
-// Forces the next call to any of the Get functions to query the hardware
-// and repopulate the cache.
-CONTENT_EXPORT void ResetAudioCache();
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_AUDIO_HARDWARE_H_
diff --git a/content/renderer/media/audio_message_filter.cc b/content/renderer/media/audio_message_filter.cc
index 22915c5..4eef36c 100644
--- a/content/renderer/media/audio_message_filter.cc
+++ b/content/renderer/media/audio_message_filter.cc
@@ -23,21 +23,22 @@ AudioMessageFilter* AudioMessageFilter::Get() {
AudioMessageFilter::AudioMessageFilter()
: next_stream_id_(1),
- channel_(NULL) {
+ channel_(NULL),
+ audio_hardware_config_(NULL) {
DVLOG(1) << "AudioMessageFilter::AudioMessageFilter()";
DCHECK(!filter_);
filter_ = this;
}
int AudioMessageFilter::AddDelegate(media::AudioOutputIPCDelegate* delegate) {
- base::AutoLock guard(delegates_lock_);
+ base::AutoLock auto_lock(lock_);
const int id = next_stream_id_++;
delegates_.insert(std::make_pair(id, delegate));
return id;
}
void AudioMessageFilter::RemoveDelegate(int id) {
- base::AutoLock guard(delegates_lock_);
+ base::AutoLock auto_lock(lock_);
delegates_.erase(id);
}
@@ -96,6 +97,7 @@ bool AudioMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(AudioMessageFilter, message)
IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamCreated, OnStreamCreated)
IPC_MESSAGE_HANDLER(AudioMsg_NotifyStreamStateChanged, OnStreamStateChanged)
+ IPC_MESSAGE_HANDLER(AudioMsg_NotifyDeviceChanged, OnOutputDeviceChanged)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -115,7 +117,7 @@ void AudioMessageFilter::OnChannelClosing() {
DelegateMap zombies;
{
- base::AutoLock guard(delegates_lock_);
+ base::AutoLock auto_lock(lock_);
delegates_.swap(zombies);
}
@@ -153,7 +155,7 @@ void AudioMessageFilter::OnStreamCreated(
#endif
{
- base::AutoLock guard(delegates_lock_);
+ base::AutoLock auto_lock(lock_);
DelegateMap::const_iterator it = delegates_.find(stream_id);
if (it != delegates_.end()) {
it->second->OnStreamCreated(handle, socket_handle, length);
@@ -169,7 +171,7 @@ void AudioMessageFilter::OnStreamCreated(
void AudioMessageFilter::OnStreamStateChanged(
int stream_id, media::AudioOutputIPCDelegate::State state) {
- base::AutoLock guard(delegates_lock_);
+ base::AutoLock auto_lock(lock_);
DelegateMap::const_iterator it = delegates_.find(stream_id);
DLOG_IF(WARNING, it == delegates_.end())
<< "No delegate found for state change. " << state;
@@ -177,4 +179,24 @@ void AudioMessageFilter::OnStreamStateChanged(
it->second->OnStateChanged(state);
}
+void AudioMessageFilter::OnOutputDeviceChanged(int stream_id,
+ int new_buffer_size,
+ int new_sample_rate) {
+ base::AutoLock auto_lock(lock_);
+
+ // Ignore the message if an audio hardware config hasn't been created; this
+ // can occur if the renderer is using the high latency audio path.
+ // TODO(dalecurtis): After http://crbug.com/173435 is fixed, convert to CHECK.
+ if (!audio_hardware_config_)
+ return;
+
+ audio_hardware_config_->UpdateOutputConfig(new_buffer_size, new_sample_rate);
+}
+
+void AudioMessageFilter::SetAudioHardwareConfig(
+ media::AudioHardwareConfig* config) {
+ base::AutoLock auto_lock(lock_);
+ audio_hardware_config_ = config;
+}
+
} // namespace content
diff --git a/content/renderer/media/audio_message_filter.h b/content/renderer/media/audio_message_filter.h
index de746d5..1172607 100644
--- a/content/renderer/media/audio_message_filter.h
+++ b/content/renderer/media/audio_message_filter.h
@@ -19,6 +19,7 @@
#include "ipc/ipc_channel_proxy.h"
#include "media/audio/audio_buffers_state.h"
#include "media/audio/audio_output_ipc.h"
+#include "media/base/audio_hardware_config.h"
namespace content {
@@ -37,8 +38,8 @@ class CONTENT_EXPORT AudioMessageFilter
// media::AudioOutputIPC implementation.
virtual int AddDelegate(media::AudioOutputIPCDelegate* delegate) OVERRIDE;
virtual void RemoveDelegate(int id) OVERRIDE;
- virtual void CreateStream(int stream_id,
- const media::AudioParameters& params, int input_channels) OVERRIDE;
+ virtual void CreateStream(int stream_id, const media::AudioParameters& params,
+ int input_channels) OVERRIDE;
virtual void PlayStream(int stream_id) OVERRIDE;
virtual void PauseStream(int stream_id) OVERRIDE;
virtual void FlushStream(int stream_id) OVERRIDE;
@@ -51,6 +52,11 @@ class CONTENT_EXPORT AudioMessageFilter
virtual void OnFilterRemoved() OVERRIDE;
virtual void OnChannelClosing() OVERRIDE;
+ // When set, AudioMessageFilter will update the AudioHardwareConfig with new
+ // configuration values as recieved by OnOutputDeviceChanged(). The provided
+ // |config| must outlive AudioMessageFilter.
+ void SetAudioHardwareConfig(media::AudioHardwareConfig* config);
+
protected:
virtual ~AudioMessageFilter();
@@ -75,21 +81,26 @@ class CONTENT_EXPORT AudioMessageFilter
void OnStreamStateChanged(int stream_id,
media::AudioOutputIPCDelegate::State state);
+ // Received when the browser process detects an output device change.
+ void OnOutputDeviceChanged(int stream_id, int new_buffer_size,
+ int new_sample_rate);
+
// The singleton instance for this filter.
static AudioMessageFilter* filter_;
- // Guards delegates_ since AddDelegate() and RemoveDelegate() are called from
- // threads other than the IO thread.
- base::Lock delegates_lock_;
+ // Unique ID to use for next added delegate.
+ int next_stream_id_;
+ IPC::Channel* channel_;
+
+ // Guards all variables below which are accessed from multiple threads.
+ base::Lock lock_;
// A map of stream ids to delegates.
typedef base::hash_map<int, media::AudioOutputIPCDelegate*> DelegateMap;
DelegateMap delegates_;
- // Unique ID to use for next added delegate.
- int next_stream_id_;
-
- IPC::Channel* channel_;
+ // Audio hardware configuration to update when OnOutputDeviceChanged() fires.
+ media::AudioHardwareConfig* audio_hardware_config_;
DISALLOW_COPY_AND_ASSIGN(AudioMessageFilter);
};
diff --git a/content/renderer/media/audio_renderer_mixer_manager.cc b/content/renderer/media/audio_renderer_mixer_manager.cc
index 71fafcb..d6e88c8 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -8,15 +8,15 @@
#include "base/bind_helpers.h"
#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/media/renderer_audio_output_device.h"
+#include "media/base/audio_hardware_config.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
namespace content {
-AudioRendererMixerManager::AudioRendererMixerManager(int hardware_sample_rate,
- int hardware_buffer_size)
- : hardware_sample_rate_(hardware_sample_rate),
- hardware_buffer_size_(hardware_buffer_size),
+AudioRendererMixerManager::AudioRendererMixerManager(
+ media::AudioHardwareConfig* hardware_config)
+ : hardware_config_(hardware_config),
sink_for_testing_(NULL) {
}
@@ -57,7 +57,7 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
#if defined(OS_LINUX)
int sample_rate = params.sample_rate();
#else
- int sample_rate = hardware_sample_rate_;
+ int sample_rate = hardware_config_->GetOutputSampleRate();
#endif
// Create output parameters based on the audio hardware configuration for
@@ -65,7 +65,7 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
// know that works well for WebAudio and WebRTC.
media::AudioParameters output_params(
media::AudioParameters::AUDIO_PCM_LOW_LATENCY, params.channel_layout(),
- sample_rate, 16, hardware_buffer_size_);
+ sample_rate, 16, hardware_config_->GetOutputBufferSize());
// If we've created invalid output parameters, simply pass on the input params
// and let the browser side handle automatic fallback.
diff --git a/content/renderer/media/audio_renderer_mixer_manager.h b/content/renderer/media/audio_renderer_mixer_manager.h
index 20afcb8..dd2575b 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.h
+++ b/content/renderer/media/audio_renderer_mixer_manager.h
@@ -13,6 +13,7 @@
#include "media/audio/audio_parameters.h"
namespace media {
+class AudioHardwareConfig;
class AudioRendererMixer;
class AudioRendererMixerInput;
class AudioRendererSink;
@@ -35,8 +36,11 @@ namespace content {
// via the shared memory. See http://crbug.com/114700.
class CONTENT_EXPORT AudioRendererMixerManager {
public:
- // Construct an instance using the given audio hardware configuration.
- AudioRendererMixerManager(int hardware_sample_rate, int hardware_buffer_size);
+ // Construct an instance using the given audio hardware configuration. The
+ // provided |hardware_config| is not owned by AudioRendererMixerManager and
+ // must outlive it.
+ explicit AudioRendererMixerManager(
+ media::AudioHardwareConfig* hardware_config);
~AudioRendererMixerManager();
// Creates an AudioRendererMixerInput with the proper callbacks necessary to
@@ -82,8 +86,7 @@ class CONTENT_EXPORT AudioRendererMixerManager {
// Audio hardware configuration. Used to construct output AudioParameters for
// each AudioRendererMixer instance.
- int hardware_sample_rate_;
- int hardware_buffer_size_;
+ media::AudioHardwareConfig* const hardware_config_;
media::AudioRendererSink* sink_for_testing_;
diff --git a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
index 46e78f3..0d00942 100644
--- a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "content/renderer/media/audio_renderer_mixer_manager.h"
+#include "media/base/audio_hardware_config.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
#include "media/base/fake_audio_render_callback.h"
@@ -24,8 +26,9 @@ static const int kAnotherRenderViewId = 456;
class AudioRendererMixerManagerTest : public testing::Test {
public:
- AudioRendererMixerManagerTest() {
- manager_.reset(new AudioRendererMixerManager(kSampleRate, kBufferSize));
+ AudioRendererMixerManagerTest()
+ : fake_config_(kBufferSize, kSampleRate, 0, media::CHANNEL_LAYOUT_NONE) {
+ manager_.reset(new AudioRendererMixerManager(&fake_config_));
// We don't want to deal with instantiating a real AudioOutputDevice since
// it's not important to our testing, so we inject a mock.
@@ -49,6 +52,7 @@ class AudioRendererMixerManagerTest : public testing::Test {
}
protected:
+ media::AudioHardwareConfig fake_config_;
scoped_ptr<AudioRendererMixerManager> manager_;
scoped_refptr<media::MockAudioRendererSink> mock_sink_;
diff --git a/content/renderer/media/webrtc_audio_capturer.cc b/content/renderer/media/webrtc_audio_capturer.cc
index 16836f2a..a3c6ebf 100644
--- a/content/renderer/media/webrtc_audio_capturer.cc
+++ b/content/renderer/media/webrtc_audio_capturer.cc
@@ -10,7 +10,6 @@
#include "base/string_util.h"
#include "content/common/child_process.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/media/webrtc_local_audio_renderer.h"
#include "media/audio/audio_util.h"
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc
index 21fc788..32a5e49 100644
--- a/content/renderer/media/webrtc_audio_device_impl.cc
+++ b/content/renderer/media/webrtc_audio_device_impl.cc
@@ -8,7 +8,6 @@
#include "base/metrics/histogram.h"
#include "base/string_util.h"
#include "base/win/windows_version.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_audio_renderer.h"
#include "content/renderer/render_thread_impl.h"
diff --git a/content/renderer/media/webrtc_audio_device_unittest.cc b/content/renderer/media/webrtc_audio_device_unittest.cc
index 30157b0..e988aa2 100644
--- a/content/renderer/media/webrtc_audio_device_unittest.cc
+++ b/content/renderer/media/webrtc_audio_device_unittest.cc
@@ -4,13 +4,14 @@
#include "base/environment.h"
#include "base/test/test_timeouts.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/media/webrtc_audio_renderer.h"
+#include "content/renderer/render_thread_impl.h"
#include "content/test/webrtc_audio_device_test.h"
-#include "media/audio/audio_manager.h"
+#include "media/audio/audio_manager_base.h"
#include "media/audio/audio_util.h"
+#include "media/base/audio_hardware_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/webrtc/voice_engine/include/voe_audio_processing.h"
#include "third_party/webrtc/voice_engine/include/voe_base.h"
@@ -30,52 +31,14 @@ namespace {
const int kRenderViewId = 1;
-class AudioUtil : public AudioUtilInterface {
- public:
- AudioUtil() {}
-
- virtual int GetAudioHardwareSampleRate() OVERRIDE {
- return media::GetAudioHardwareSampleRate();
- }
- virtual int GetAudioInputHardwareSampleRate(
- const std::string& device_id) OVERRIDE {
- return media::GetAudioInputHardwareSampleRate(device_id);
- }
- virtual media::ChannelLayout GetAudioInputHardwareChannelLayout(
- const std::string& device_id) OVERRIDE {
- return media::GetAudioInputHardwareChannelLayout(device_id);
- }
- private:
- DISALLOW_COPY_AND_ASSIGN(AudioUtil);
-};
-
-class AudioUtilNoHardware : public AudioUtilInterface {
- public:
- AudioUtilNoHardware(int output_rate, int input_rate,
- media::ChannelLayout input_channel_layout)
- : output_rate_(output_rate),
- input_rate_(input_rate),
- input_channel_layout_(input_channel_layout) {
- }
-
- virtual int GetAudioHardwareSampleRate() OVERRIDE {
- return output_rate_;
- }
- virtual int GetAudioInputHardwareSampleRate(
- const std::string& device_id) OVERRIDE {
- return input_rate_;
- }
- virtual media::ChannelLayout GetAudioInputHardwareChannelLayout(
- const std::string& device_id) OVERRIDE {
- return input_channel_layout_;
- }
-
- private:
- int output_rate_;
- int input_rate_;
- media::ChannelLayout input_channel_layout_;
- DISALLOW_COPY_AND_ASSIGN(AudioUtilNoHardware);
-};
+scoped_ptr<media::AudioHardwareConfig> CreateRealHardwareConfig() {
+ return make_scoped_ptr(new media::AudioHardwareConfig(
+ media::GetAudioHardwareBufferSize(), media::GetAudioHardwareSampleRate(),
+ media::GetAudioInputHardwareSampleRate(
+ media::AudioManagerBase::kDefaultDeviceId),
+ media::GetAudioInputHardwareChannelLayout(
+ media::AudioManagerBase::kDefaultDeviceId)));
+}
// Return true if at least one element in the array matches |value|.
bool FindElementInArray(int* array, int size, int value) {
@@ -95,8 +58,11 @@ bool HardwareSampleRatesAreValid() {
int valid_input_rates[] = {16000, 32000, 44100, 48000, 96000};
int valid_output_rates[] = {44100, 48000, 96000};
+ media::AudioHardwareConfig* hardware_config =
+ RenderThreadImpl::current()->GetAudioHardwareConfig();
+
// Verify the input sample rate.
- int input_sample_rate = GetAudioInputSampleRate();
+ int input_sample_rate = hardware_config->GetInputSampleRate();
if (!FindElementInArray(valid_input_rates, arraysize(valid_input_rates),
input_sample_rate)) {
@@ -105,7 +71,7 @@ bool HardwareSampleRatesAreValid() {
}
// Given that the input rate was OK, verify the output rate as well.
- int output_sample_rate = GetAudioOutputSampleRate();
+ int output_sample_rate = hardware_config->GetOutputSampleRate();
if (!FindElementInArray(valid_output_rates, arraysize(valid_output_rates),
output_sample_rate)) {
LOG(WARNING) << "Non-supported output sample rate detected.";
@@ -124,10 +90,14 @@ bool InitializeCapturer(WebRtcAudioDeviceImpl* webrtc_audio_device) {
if (!capturer)
return false;
+ media::AudioHardwareConfig* hardware_config =
+ RenderThreadImpl::current()->GetAudioHardwareConfig();
+
// Use native capture sample rate and channel configuration to get some
// action in this test.
- int sample_rate = GetAudioInputSampleRate();
- media::ChannelLayout channel_layout = GetAudioInputChannelLayout();
+ int sample_rate = hardware_config->GetInputSampleRate();
+ media::ChannelLayout channel_layout =
+ hardware_config->GetInputChannelLayout();
if (!capturer->Initialize(channel_layout, sample_rate))
return false;
@@ -246,8 +216,9 @@ TEST_F(WebRTCAudioDeviceTest, TestValidOutputRates) {
// Basic test that instantiates and initializes an instance of
// WebRtcAudioDeviceImpl.
TEST_F(WebRTCAudioDeviceTest, Construct) {
- AudioUtilNoHardware audio_util(48000, 48000, media::CHANNEL_LAYOUT_MONO);
- SetAudioUtilCallback(&audio_util);
+ media::AudioHardwareConfig audio_config(
+ 480, 48000, 48000, media::CHANNEL_LAYOUT_MONO);
+ SetAudioHardwareConfig(&audio_config);
scoped_refptr<WebRtcAudioDeviceImpl> webrtc_audio_device(
new WebRtcAudioDeviceImpl());
@@ -279,8 +250,8 @@ TEST_F(WebRTCAudioDeviceTest, DISABLED_StartPlayout) {
return;
}
- AudioUtil audio_util;
- SetAudioUtilCallback(&audio_util);
+ scoped_ptr<media::AudioHardwareConfig> config = CreateRealHardwareConfig();
+ SetAudioHardwareConfig(config.get());
if (!HardwareSampleRatesAreValid())
return;
@@ -357,8 +328,8 @@ TEST_F(WebRTCAudioDeviceTest, StartRecording) {
return;
}
- AudioUtil audio_util;
- SetAudioUtilCallback(&audio_util);
+ scoped_ptr<media::AudioHardwareConfig> config = CreateRealHardwareConfig();
+ SetAudioHardwareConfig(config.get());
if (!HardwareSampleRatesAreValid())
return;
@@ -430,8 +401,8 @@ TEST_F(WebRTCAudioDeviceTest, DISABLED_PlayLocalFile) {
std::string file_path(
GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm")));
- AudioUtil audio_util;
- SetAudioUtilCallback(&audio_util);
+ scoped_ptr<media::AudioHardwareConfig> config = CreateRealHardwareConfig();
+ SetAudioHardwareConfig(config.get());
if (!HardwareSampleRatesAreValid())
return;
@@ -501,8 +472,8 @@ TEST_F(WebRTCAudioDeviceTest, FullDuplexAudioWithAGC) {
return;
}
- AudioUtil audio_util;
- SetAudioUtilCallback(&audio_util);
+ scoped_ptr<media::AudioHardwareConfig> config = CreateRealHardwareConfig();
+ SetAudioHardwareConfig(config.get());
if (!HardwareSampleRatesAreValid())
return;
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc
index c21c662..0d33713 100644
--- a/content/renderer/media/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc_audio_renderer.cc
@@ -8,11 +8,13 @@
#include "base/metrics/histogram.h"
#include "base/string_util.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
+#include "content/renderer/render_thread_impl.h"
#include "media/audio/audio_util.h"
#include "media/audio/sample_rates.h"
+#include "media/base/audio_hardware_config.h"
+
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#include "media/audio/win/core_audio_util_win.h"
@@ -24,10 +26,10 @@ namespace {
// Supported hardware sample rates for output sides.
#if defined(OS_WIN) || defined(OS_MACOSX)
-// media::GetAudioOutputHardwareSampleRate() asks the audio layer
-// for its current sample rate (set by the user) on Windows and Mac OS X.
-// The listed rates below adds restrictions and Initialize()
-// will fail if the user selects any rate outside these ranges.
+// AudioHardwareConfig::GetOutputSampleRate() asks the audio layer for its
+// current sample rate (set by the user) on Windows and Mac OS X. The listed
+// rates below adds restrictions and Initialize() will fail if the user selects
+// any rate outside these ranges.
int kValidOutputRates[] = {96000, 48000, 44100};
#elif defined(OS_LINUX) || defined(OS_OPENBSD)
int kValidOutputRates[] = {48000, 44100};
@@ -104,9 +106,10 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
sink_ = AudioDeviceFactory::NewOutputDevice();
DCHECK(sink_);
- // Ask the browser for the default audio output hardware sample-rate.
- // This request is based on a synchronous IPC message.
- int sample_rate = GetAudioOutputSampleRate();
+ // Ask the renderer for the default audio output hardware sample-rate.
+ media::AudioHardwareConfig* hardware_config =
+ RenderThreadImpl::current()->GetAudioHardwareConfig();
+ int sample_rate = hardware_config->GetOutputSampleRate();
DVLOG(1) << "Audio output hardware sample rate: " << sample_rate;
UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioOutputSampleRate",
sample_rate, media::kUnexpectedAudioSampleRate);
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.cc b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
index 6681d0a..2a6dbf6 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
@@ -11,9 +11,9 @@
#include "build/build_config.h"
#include "content/common/child_process.h"
#include "content/common/media/audio_messages.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/audio_message_filter.h"
#include "content/renderer/render_thread_impl.h"
+#include "media/base/audio_hardware_config.h"
#include "media/base/media_switches.h"
namespace content {
@@ -125,14 +125,17 @@ bool PepperPlatformAudioOutputImpl::Initialize(
media::AudioParameters::Format format;
const int kMaxFramesForLowLatency = 2047;
+ media::AudioHardwareConfig* hardware_config =
+ RenderThreadImpl::current()->GetAudioHardwareConfig();
+
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
if (!cmd_line->HasSwitch(switches::kDisableAudioOutputResampler)) {
// Rely on AudioOutputResampler to handle any inconsistencies between the
// hardware params required for low latency and the requested params.
format = media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
- } else if (sample_rate == GetAudioOutputSampleRate() &&
+ } else if (sample_rate == hardware_config->GetOutputSampleRate() &&
frames_per_buffer <= kMaxFramesForLowLatency &&
- frames_per_buffer % content::GetAudioOutputBufferSize() == 0) {
+ frames_per_buffer % hardware_config->GetOutputBufferSize() == 0) {
// Use the low latency back end if the client request is compatible, and
// the sample count is low enough to justify using AUDIO_PCM_LOW_LATENCY.
format = media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
index 8c6eb0d..5fdd139 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
@@ -35,7 +35,6 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/public/renderer/renderer_restrict_dispatch_group.h"
#include "content/renderer/gamepad_shared_memory_reader.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/pepper_platform_video_decoder_impl.h"
#include "content/renderer/p2p/socket_dispatcher.h"
@@ -57,6 +56,7 @@
#include "content/renderer/webplugin_delegate_proxy.h"
#include "googleurl/src/gurl.h"
#include "ipc/ipc_channel_handle.h"
+#include "media/base/audio_hardware_config.h"
#include "media/video/capture/video_capture_proxy.h"
#include "ppapi/c/dev/pp_video_dev.h"
#include "ppapi/c/pp_errors.h"
@@ -864,11 +864,13 @@ void PepperPluginDelegateImpl::SelectedFindResultChanged(int identifier,
}
uint32_t PepperPluginDelegateImpl::GetAudioHardwareOutputSampleRate() {
- return static_cast<uint32_t>(GetAudioOutputSampleRate());
+ RenderThreadImpl* thread = RenderThreadImpl::current();
+ return thread->GetAudioHardwareConfig()->GetOutputSampleRate();
}
uint32_t PepperPluginDelegateImpl::GetAudioHardwareOutputBufferSize() {
- return static_cast<uint32_t>(GetAudioOutputBufferSize());
+ RenderThreadImpl* thread = RenderThreadImpl::current();
+ return thread->GetAudioHardwareConfig()->GetOutputBufferSize();
}
webkit::ppapi::PluginDelegate::PlatformAudioOutput*
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 5cc42cd..7dd13c2 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -55,7 +55,6 @@
#include "content/renderer/gpu/compositor_thread.h"
#include "content/renderer/gpu/compositor_output_surface.h"
#include "content/renderer/gpu/gpu_benchmarking_extension.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/media/audio_message_filter.h"
#include "content/renderer/media/audio_renderer_mixer_manager.h"
@@ -73,6 +72,7 @@
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_forwarding_message_filter.h"
#include "ipc/ipc_platform_file.h"
+#include "media/base/audio_hardware_config.h"
#include "media/base/media.h"
#include "media/base/media_switches.h"
#include "net/base/net_errors.h"
@@ -904,13 +904,32 @@ RenderThreadImpl::GetGpuVDAContext3D() {
AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() {
if (!audio_renderer_mixer_manager_.get()) {
audio_renderer_mixer_manager_.reset(new AudioRendererMixerManager(
- GetAudioOutputSampleRate(),
- GetAudioOutputBufferSize()));
+ GetAudioHardwareConfig()));
}
return audio_renderer_mixer_manager_.get();
}
+media::AudioHardwareConfig* RenderThreadImpl::GetAudioHardwareConfig() {
+ if (!audio_hardware_config_) {
+ int output_buffer_size;
+ int output_sample_rate;
+ int input_sample_rate;
+ media::ChannelLayout input_channel_layout;
+
+ Send(new ViewHostMsg_GetAudioHardwareConfig(
+ &output_buffer_size, &output_sample_rate,
+ &input_sample_rate, &input_channel_layout));
+
+ audio_hardware_config_.reset(new media::AudioHardwareConfig(
+ output_buffer_size, output_sample_rate, input_sample_rate,
+ input_channel_layout));
+ audio_message_filter_->SetAudioHardwareConfig(audio_hardware_config_.get());
+ }
+
+ return audio_hardware_config_.get();
+}
+
#if defined(OS_WIN)
void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font,
const string16& str) {
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index a70be92..0ca7420 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -45,6 +45,10 @@ namespace IPC {
class ForwardingMessageFilter;
}
+namespace media {
+class AudioHardwareConfig;
+}
+
namespace v8 {
class Extension;
}
@@ -246,6 +250,11 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
// first call.
AudioRendererMixerManager* GetAudioRendererMixerManager();
+ // AudioHardwareConfig contains audio hardware configuration for
+ // renderer side clients. Creation requires a synchronous IPC call so it is
+ // lazily created on the first call.
+ media::AudioHardwareConfig* GetAudioHardwareConfig();
+
#if defined(OS_WIN)
void PreCacheFontCharacters(const LOGFONT& log_font, const string16& str);
#endif
@@ -381,6 +390,7 @@ class CONTENT_EXPORT RenderThreadImpl : public RenderThread,
scoped_ptr<WebGraphicsContext3DCommandBufferImpl> gpu_vda_context3d_;
scoped_ptr<AudioRendererMixerManager> audio_renderer_mixer_manager_;
+ scoped_ptr<media::AudioHardwareConfig> audio_hardware_config_;
HistogramCustomizer histogram_customizer_;
diff --git a/content/renderer/renderer_webkitplatformsupport_impl.cc b/content/renderer/renderer_webkitplatformsupport_impl.cc
index 4b05c99..685d642 100644
--- a/content/renderer/renderer_webkitplatformsupport_impl.cc
+++ b/content/renderer/renderer_webkitplatformsupport_impl.cc
@@ -27,7 +27,6 @@
#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
#include "content/renderer/gamepad_shared_memory_reader.h"
#include "content/renderer/hyphenator/hyphenator.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/media_stream_dependency_factory.h"
#include "content/renderer/media/renderer_webaudiodevice_impl.h"
#include "content/renderer/render_thread_impl.h"
@@ -36,6 +35,7 @@
#include "googleurl/src/gurl.h"
#include "ipc/ipc_sync_message_filter.h"
#include "media/audio/audio_output_device.h"
+#include "media/base/audio_hardware_config.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebBlobRegistry.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGamepads.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamCenter.h"
@@ -555,11 +555,13 @@ bool RendererWebKitPlatformSupportImpl::canAccelerate2dCanvas() {
}
double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() {
- return GetAudioOutputSampleRate();
+ RenderThreadImpl* thread = RenderThreadImpl::current();
+ return thread->GetAudioHardwareConfig()->GetOutputSampleRate();
}
size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() {
- return GetAudioOutputBufferSize();
+ RenderThreadImpl* thread = RenderThreadImpl::current();
+ return thread->GetAudioHardwareConfig()->GetOutputBufferSize();
}
// TODO(crogers): remove deprecated API as soon as WebKit calls new API.
diff --git a/content/test/webrtc_audio_device_test.cc b/content/test/webrtc_audio_device_test.cc
index 5191f9d..571c4a6 100644
--- a/content/test/webrtc_audio_device_test.cc
+++ b/content/test/webrtc_audio_device_test.cc
@@ -21,13 +21,13 @@
#include "content/public/common/content_paths.h"
#include "content/public/test/mock_resource_context.h"
#include "content/public/test/test_browser_thread.h"
-#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/media/audio_message_filter.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_webkitplatformsupport_impl.h"
+#include "media/base/audio_hardware_config.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -115,7 +115,7 @@ ACTION_P(QuitMessageLoop, loop_or_proxy) {
}
WebRTCAudioDeviceTest::WebRTCAudioDeviceTest()
- : render_thread_(NULL), audio_util_callback_(NULL),
+ : render_thread_(NULL), audio_hardware_config_(NULL),
has_input_devices_(false), has_output_devices_(false) {
}
@@ -147,7 +147,7 @@ void WebRTCAudioDeviceTest::SetUp() {
}
void WebRTCAudioDeviceTest::TearDown() {
- SetAudioUtilCallback(NULL);
+ SetAudioHardwareConfig(NULL);
// Run any pending cleanup tasks that may have been posted to the main thread.
ChildProcess::current()->main_thread()->message_loop()->RunUntilIdle();
@@ -183,11 +183,9 @@ bool WebRTCAudioDeviceTest::Send(IPC::Message* message) {
return channel_->Send(message);
}
-void WebRTCAudioDeviceTest::SetAudioUtilCallback(AudioUtilInterface* callback) {
- // Invalidate any potentially cached values since the new callback should
- // be used for those queries.
- ResetAudioCache();
- audio_util_callback_ = callback;
+void WebRTCAudioDeviceTest::SetAudioHardwareConfig(
+ media::AudioHardwareConfig* hardware_config) {
+ audio_hardware_config_ = hardware_config;
}
void WebRTCAudioDeviceTest::InitializeIOThread(const char* thread_name) {
@@ -261,25 +259,17 @@ void WebRTCAudioDeviceTest::DestroyChannel() {
audio_input_renderer_host_ = NULL;
}
-void WebRTCAudioDeviceTest::OnGetHardwareSampleRate(int* sample_rate) {
- EXPECT_TRUE(audio_util_callback_);
- *sample_rate = audio_util_callback_ ?
- audio_util_callback_->GetAudioHardwareSampleRate() : 0;
-}
+void WebRTCAudioDeviceTest::OnGetAudioHardwareConfig(
+ int* output_buffer_size, int* output_sample_rate, int* input_sample_rate,
+ media::ChannelLayout* input_channel_layout) {
+ ASSERT_TRUE(audio_hardware_config_);
-void WebRTCAudioDeviceTest::OnGetHardwareInputSampleRate(int* sample_rate) {
- EXPECT_TRUE(audio_util_callback_);
- *sample_rate = audio_util_callback_ ?
- audio_util_callback_->GetAudioInputHardwareSampleRate(
- media::AudioManagerBase::kDefaultDeviceId) : 0;
-}
+ *output_buffer_size = audio_hardware_config_->GetOutputBufferSize();
+ *output_sample_rate = audio_hardware_config_->GetOutputSampleRate();
-void WebRTCAudioDeviceTest::OnGetHardwareInputChannelLayout(
- media::ChannelLayout* layout) {
- EXPECT_TRUE(audio_util_callback_);
- *layout = !audio_util_callback_ ? media::CHANNEL_LAYOUT_NONE :
- audio_util_callback_->GetAudioInputHardwareChannelLayout(
- media::AudioManagerBase::kDefaultDeviceId);
+ // TODO(henrika): add support for all available input devices.
+ *input_sample_rate = audio_hardware_config_->GetInputSampleRate();
+ *input_channel_layout = audio_hardware_config_->GetInputChannelLayout();
}
// IPC::Listener implementation.
@@ -310,12 +300,8 @@ bool WebRTCAudioDeviceTest::OnMessageReceived(const IPC::Message& message) {
bool handled ALLOW_UNUSED = true;
bool message_is_ok = true;
IPC_BEGIN_MESSAGE_MAP_EX(WebRTCAudioDeviceTest, message, message_is_ok)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareSampleRate,
- OnGetHardwareSampleRate)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareInputSampleRate,
- OnGetHardwareInputSampleRate)
- IPC_MESSAGE_HANDLER(ViewHostMsg_GetHardwareInputChannelLayout,
- OnGetHardwareInputChannelLayout)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_GetAudioHardwareConfig,
+ OnGetAudioHardwareConfig)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
diff --git a/content/test/webrtc_audio_device_test.h b/content/test/webrtc_audio_device_test.h
index b2974c4..2e52e94b 100644
--- a/content/test/webrtc_audio_device_test.h
+++ b/content/test/webrtc_audio_device_test.h
@@ -14,6 +14,7 @@
#include "content/browser/renderer_host/media/mock_media_observer.h"
#include "content/public/renderer/content_renderer_client.h"
#include "ipc/ipc_listener.h"
+#include "media/base/audio_hardware_config.h"
#include "media/base/channel_layout.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/common_types.h"
@@ -109,18 +110,6 @@ class WebRTCAutoDelete {
T* ptr_;
};
-// Individual tests can provide an implementation (or mock) of this interface
-// when the audio code queries for hardware capabilities on the IO thread.
-class AudioUtilInterface {
- public:
- virtual ~AudioUtilInterface() {}
- virtual int GetAudioHardwareSampleRate() = 0;
- virtual int GetAudioInputHardwareSampleRate(
- const std::string& device_id) = 0;
- virtual media::ChannelLayout GetAudioInputHardwareChannelLayout(
- const std::string& device_id) = 0;
-};
-
// Implemented and defined in the cc file.
class ReplaceContentClientRenderer;
@@ -135,7 +124,7 @@ class WebRTCAudioDeviceTest : public ::testing::Test, public IPC::Listener {
// Sends an IPC message to the IO thread channel.
bool Send(IPC::Message* message);
- void SetAudioUtilCallback(AudioUtilInterface* callback);
+ void SetAudioHardwareConfig(media::AudioHardwareConfig* hardware_config);
protected:
void InitializeIOThread(const char* thread_name);
@@ -143,9 +132,9 @@ class WebRTCAudioDeviceTest : public ::testing::Test, public IPC::Listener {
void CreateChannel(const char* name);
void DestroyChannel();
- void OnGetHardwareSampleRate(int* sample_rate);
- void OnGetHardwareInputSampleRate(int* sample_rate);
- void OnGetHardwareInputChannelLayout(media::ChannelLayout* channels);
+ void OnGetAudioHardwareConfig(int* output_buffer_size,
+ int* output_sample_rate, int* input_sample_rate,
+ media::ChannelLayout* input_channel_layout);
// IPC::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
@@ -177,7 +166,7 @@ class WebRTCAudioDeviceTest : public ::testing::Test, public IPC::Listener {
scoped_refptr<AudioRendererHost> audio_render_host_;
scoped_refptr<AudioInputRendererHost> audio_input_renderer_host_;
- AudioUtilInterface* audio_util_callback_; // Weak reference.
+ media::AudioHardwareConfig* audio_hardware_config_; // Weak reference.
// Initialized on the main test thread that we mark as the UI thread.
scoped_ptr<TestBrowserThread> ui_thread_;
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index f48cf7f..9990389 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -10,6 +10,7 @@
#include "base/threading/platform_thread.h"
#include "base/time.h"
#include "build/build_config.h"
+#include "media/audio/audio_util.h"
#include "media/audio/shared_memory_util.h"
using base::Time;
@@ -323,6 +324,10 @@ void AudioOutputController::DoStopCloseAndClearStream() {
void AudioOutputController::OnDeviceChange() {
DCHECK(message_loop_->BelongsToCurrentThread());
+ // TODO(dalecurtis): Notify the renderer side that a device change has
+ // occurred. Currently querying the hardware information here will lead to
+ // crashes on OSX. See http://crbug.com/158170.
+
// Recreate the stream (DoCreate() will first shut down an existing stream).
// Exit if we ran into an error.
const State original_state = state_;
diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h
index be6d68c..e8fae22 100644
--- a/media/audio/audio_output_controller.h
+++ b/media/audio/audio_output_controller.h
@@ -71,6 +71,8 @@ class MEDIA_EXPORT AudioOutputController
virtual void OnPlaying(AudioOutputController* controller) = 0;
virtual void OnPaused(AudioOutputController* controller) = 0;
virtual void OnError(AudioOutputController* controller, int error_code) = 0;
+ virtual void OnDeviceChange(AudioOutputController* controller,
+ int new_buffer_size, int new_sample_rate) = 0;
protected:
virtual ~EventHandler() {}
diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc
index 746bc45..944d661 100644
--- a/media/audio/audio_output_controller_unittest.cc
+++ b/media/audio/audio_output_controller_unittest.cc
@@ -43,7 +43,8 @@ class MockAudioOutputControllerEventHandler
MOCK_METHOD1(OnPaused, void(AudioOutputController* controller));
MOCK_METHOD2(OnError, void(AudioOutputController* controller,
int error_code));
-
+ MOCK_METHOD3(OnDeviceChange, void(AudioOutputController* controller,
+ int new_buffer_size, int new_sample_rate));
private:
DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerEventHandler);
};
diff --git a/media/base/audio_hardware_config.cc b/media/base/audio_hardware_config.cc
new file mode 100644
index 0000000..eaacc69
--- /dev/null
+++ b/media/base/audio_hardware_config.cc
@@ -0,0 +1,53 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/base/audio_hardware_config.h"
+
+namespace media {
+
+AudioHardwareConfig::AudioHardwareConfig(
+ int output_buffer_size, int output_sample_rate,
+ int input_sample_rate, ChannelLayout input_channel_layout)
+ : output_buffer_size_(output_buffer_size),
+ output_sample_rate_(output_sample_rate),
+ input_sample_rate_(input_sample_rate),
+ input_channel_layout_(input_channel_layout) {
+}
+
+AudioHardwareConfig::~AudioHardwareConfig() {}
+
+int AudioHardwareConfig::GetOutputBufferSize() {
+ base::AutoLock auto_lock(config_lock_);
+ return output_buffer_size_;
+}
+
+int AudioHardwareConfig::GetOutputSampleRate() {
+ base::AutoLock auto_lock(config_lock_);
+ return output_sample_rate_;
+}
+
+int AudioHardwareConfig::GetInputSampleRate() {
+ base::AutoLock auto_lock(config_lock_);
+ return input_sample_rate_;
+}
+
+ChannelLayout AudioHardwareConfig::GetInputChannelLayout() {
+ base::AutoLock auto_lock(config_lock_);
+ return input_channel_layout_;
+}
+
+void AudioHardwareConfig::UpdateInputConfig(
+ int sample_rate, media::ChannelLayout channel_layout) {
+ base::AutoLock auto_lock(config_lock_);
+ input_sample_rate_ = sample_rate;
+ input_channel_layout_ = channel_layout;
+}
+
+void AudioHardwareConfig::UpdateOutputConfig(int buffer_size, int sample_rate) {
+ base::AutoLock auto_lock(config_lock_);
+ output_buffer_size_ = buffer_size;
+ output_sample_rate_ = sample_rate;
+}
+
+} // namespace media
diff --git a/media/base/audio_hardware_config.h b/media/base/audio_hardware_config.h
new file mode 100644
index 0000000..e61d9ba
--- /dev/null
+++ b/media/base/audio_hardware_config.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MEDIA_BASE_AUDIO_HARDWARE_CONFIG_H_
+#define MEDIA_BASE_AUDIO_HARDWARE_CONFIG_H_
+
+#include "base/compiler_specific.h"
+#include "base/synchronization/lock.h"
+#include "media/base/channel_layout.h"
+#include "media/base/media_export.h"
+
+namespace media {
+
+// Provides thread safe access to the audio hardware configuration.
+class MEDIA_EXPORT AudioHardwareConfig {
+ public:
+ AudioHardwareConfig(int output_buffer_size, int output_sample_rate,
+ int input_sample_rate,
+ ChannelLayout input_channel_layout);
+ virtual ~AudioHardwareConfig();
+
+ // Accessors for the currently cached hardware configuration. Safe to call
+ // from any thread.
+ int GetOutputBufferSize();
+ int GetOutputSampleRate();
+ int GetInputSampleRate();
+ ChannelLayout GetInputChannelLayout();
+
+ // Allows callers to update the cached values for either input or output. The
+ // values are paired under the assumption that these values will only be set
+ // after an input or output device change respectively. Safe to call from
+ // any thread.
+ void UpdateInputConfig(int sample_rate, media::ChannelLayout channel_layout);
+ void UpdateOutputConfig(int buffer_size, int sample_rate);
+
+ private:
+ // Cached values; access is protected by |config_lock_|.
+ base::Lock config_lock_;
+ int output_buffer_size_;
+ int output_sample_rate_;
+ int input_sample_rate_;
+ ChannelLayout input_channel_layout_;
+
+ DISALLOW_COPY_AND_ASSIGN(AudioHardwareConfig);
+};
+
+} // namespace media
+
+#endif // MEDIA_BASE_AUDIO_HARDWARE_CONFIG_H_
diff --git a/media/base/audio_hardware_config_unittest.cc b/media/base/audio_hardware_config_unittest.cc
new file mode 100644
index 0000000..afa2e0d
--- /dev/null
+++ b/media/base/audio_hardware_config_unittest.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/base/audio_hardware_config.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+static const int kOutputBufferSize = 2048;
+static const int kOutputSampleRate = 48000;
+static const int kInputSampleRate = 44100;
+static const ChannelLayout kInputChannelLayout = CHANNEL_LAYOUT_STEREO;
+
+TEST(AudioHardwareConfig, Getters) {
+ AudioHardwareConfig fake_config(
+ kOutputBufferSize, kOutputSampleRate, kInputSampleRate,
+ kInputChannelLayout);
+
+ EXPECT_EQ(kOutputBufferSize, fake_config.GetOutputBufferSize());
+ EXPECT_EQ(kOutputSampleRate, fake_config.GetOutputSampleRate());
+ EXPECT_EQ(kInputSampleRate, fake_config.GetInputSampleRate());
+ EXPECT_EQ(kInputChannelLayout, fake_config.GetInputChannelLayout());
+}
+
+TEST(AudioHardwareConfig, Setters) {
+ AudioHardwareConfig fake_config(
+ kOutputBufferSize, kOutputSampleRate, kInputSampleRate,
+ kInputChannelLayout);
+
+ // Verify output parameters.
+ const int kNewOutputBufferSize = kOutputBufferSize * 2;
+ const int kNewOutputSampleRate = kOutputSampleRate * 2;
+ EXPECT_NE(kNewOutputBufferSize, fake_config.GetOutputBufferSize());
+ EXPECT_NE(kNewOutputSampleRate, fake_config.GetOutputSampleRate());
+ fake_config.UpdateOutputConfig(kNewOutputBufferSize, kNewOutputSampleRate);
+ EXPECT_EQ(kNewOutputBufferSize, fake_config.GetOutputBufferSize());
+ EXPECT_EQ(kNewOutputSampleRate, fake_config.GetOutputSampleRate());
+
+ // Verify input parameters.
+ const int kNewInputSampleRate = kInputSampleRate * 2;
+ const ChannelLayout kNewInputChannelLayout = CHANNEL_LAYOUT_MONO;
+ EXPECT_NE(kNewInputSampleRate, fake_config.GetInputSampleRate());
+ EXPECT_NE(kNewInputChannelLayout, fake_config.GetInputChannelLayout());
+ fake_config.UpdateInputConfig(kNewInputSampleRate, kNewInputChannelLayout);
+ EXPECT_EQ(kNewInputSampleRate, fake_config.GetInputSampleRate());
+ EXPECT_EQ(kNewInputChannelLayout, fake_config.GetInputChannelLayout());
+}
+
+} // namespace content
diff --git a/media/media.gyp b/media/media.gyp
index 82a297a..cc8be41 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -186,6 +186,8 @@
'base/audio_decoder_config.h',
'base/audio_fifo.cc',
'base/audio_fifo.h',
+ 'base/audio_hardware_config.cc',
+ 'base/audio_hardware_config.h',
'base/audio_pull_fifo.cc',
'base/audio_pull_fifo.h',
'base/audio_renderer.cc',
@@ -771,6 +773,7 @@
'base/audio_bus_unittest.cc',
'base/audio_converter_unittest.cc',
'base/audio_fifo_unittest.cc',
+ 'base/audio_hardware_config_unittest.cc',
'base/audio_pull_fifo_unittest.cc',
'base/audio_renderer_mixer_input_unittest.cc',
'base/audio_renderer_mixer_unittest.cc',