Commit 0e4ee3f2 authored by tommi@chromium.org's avatar tommi@chromium.org

Refactor the Get*Hardware* routines a bit.

These methods currently all have a static variable that caches the queried value.
This causes a problem in unit tests where values can change between tests.
I moved them outside of the AudioDevice class and grouped in their own namespace
which owns the globally cached state and allows the cache to be invalidated.

R=henrika
TEST=Run *WebRTC* tests in content.
Review URL: http://codereview.chromium.org/8588030

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110695 0039d316-1c4b-4281-b951-d872f2087c98
parent bc7bad85
...@@ -81,6 +81,8 @@ ...@@ -81,6 +81,8 @@
'renderer/load_progress_tracker.h', 'renderer/load_progress_tracker.h',
'renderer/media/audio_device.cc', 'renderer/media/audio_device.cc',
'renderer/media/audio_device.h', 'renderer/media/audio_device.h',
'renderer/media/audio_hardware.cc',
'renderer/media/audio_hardware.h',
'renderer/media/audio_input_device.cc', 'renderer/media/audio_input_device.cc',
'renderer/media/audio_input_device.h', 'renderer/media/audio_input_device.h',
'renderer/media/audio_input_message_filter.cc', 'renderer/media/audio_input_message_filter.cc',
......
...@@ -233,25 +233,3 @@ void AudioDevice::FireRenderCallback() { ...@@ -233,25 +233,3 @@ void AudioDevice::FireRenderCallback() {
buffer_size_); buffer_size_);
} }
} }
double AudioDevice::GetAudioHardwareSampleRate() {
// Uses cached value if possible.
static double hardware_sample_rate = 0;
if (!hardware_sample_rate) {
RenderThreadImpl::current()->Send(
new ViewHostMsg_GetHardwareSampleRate(&hardware_sample_rate));
}
return hardware_sample_rate;
}
size_t AudioDevice::GetAudioHardwareBufferSize() {
// Uses cached value if possible.
static uint32 buffer_size = 0;
if (!buffer_size) {
RenderThreadImpl::current()->Send(
new ViewHostMsg_GetHardwareBufferSize(&buffer_size));
}
return static_cast<size_t>(buffer_size);
}
...@@ -101,9 +101,6 @@ class CONTENT_EXPORT AudioDevice ...@@ -101,9 +101,6 @@ class CONTENT_EXPORT AudioDevice
double sample_rate() const { return sample_rate_; } double sample_rate() const { return sample_rate_; }
size_t buffer_size() const { return buffer_size_; } size_t buffer_size() const { return buffer_size_; }
static double GetAudioHardwareSampleRate();
static size_t GetAudioHardwareBufferSize();
// Methods called on IO thread ---------------------------------------------- // Methods called on IO thread ----------------------------------------------
// AudioMessageFilter::Delegate methods, called by AudioMessageFilter. // AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
virtual void OnRequestPacket(AudioBuffersState buffers_state) OVERRIDE; virtual void OnRequestPacket(AudioBuffersState buffers_state) OVERRIDE;
......
// Copyright (c) 2011 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"
static double output_sample_rate = 0.0;
static double input_sample_rate = 0.0;
static size_t output_buffer_size = 0;
namespace audio_hardware {
double GetOutputSampleRate() {
DCHECK(RenderThreadImpl::current() != NULL);
if (!output_sample_rate) {
RenderThreadImpl::current()->Send(
new ViewHostMsg_GetHardwareSampleRate(&output_sample_rate));
}
return output_sample_rate;
}
double GetInputSampleRate() {
DCHECK(RenderThreadImpl::current() != NULL);
if (!input_sample_rate) {
RenderThreadImpl::current()->Send(
new ViewHostMsg_GetHardwareInputSampleRate(&input_sample_rate));
}
return input_sample_rate;
}
size_t GetOutputBufferSize() {
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;
}
void ResetCache() {
DCHECK(RenderThreadImpl::current() != NULL);
output_sample_rate = 0.0;
input_sample_rate = 0.0;
output_buffer_size = 0;
}
} // namespace audio_hardware
// Copyright (c) 2011 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_
#pragma once
#include "base/basictypes.h"
#include "content/common/content_export.h"
// Contains static methods to query 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 audio_hardware {
// Fetch the sample rate of the default audio output end point device.
// Must be called from RenderThreadImpl::current().
CONTENT_EXPORT double GetOutputSampleRate();
// Fetch the sample rate of the default audio input end point device.
// Must be called from RenderThreadImpl::current().
CONTENT_EXPORT double GetInputSampleRate();
// Fetch the buffer size we use for the default output device.
// Must be called from RenderThreadImpl::current().
CONTENT_EXPORT size_t GetOutputBufferSize();
// Forces the next call to any of the Get functions to query the hardware
// and repopulate the cache.
CONTENT_EXPORT void ResetCache();
} // namespace audio_hardware
#endif // CONTENT_RENDERER_MEDIA_AUDIO_HARDWARE_H_
...@@ -7,22 +7,13 @@ ...@@ -7,22 +7,13 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/string_util.h" #include "base/string_util.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "content/common/view_messages.h" #include "content/renderer/media/audio_hardware.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "media/audio/audio_util.h" #include "media/audio/audio_util.h"
static const int64 kMillisecondsBetweenProcessCalls = 5000; static const int64 kMillisecondsBetweenProcessCalls = 5000;
static const char kVersion[] = "WebRTC AudioDevice 1.0.0.Chrome"; static const char kVersion[] = "WebRTC AudioDevice 1.0.0.Chrome";
static int GetAudioInputHardwareSampleRate() {
static double input_sample_rate = 0;
if (!input_sample_rate) {
RenderThreadImpl::current()->Send(
new ViewHostMsg_GetHardwareInputSampleRate(&input_sample_rate));
}
return static_cast<int>(input_sample_rate);
}
WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl() WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
: ref_count_(0), : ref_count_(0),
render_loop_(base::MessageLoopProxy::current()), render_loop_(base::MessageLoopProxy::current()),
...@@ -290,12 +281,13 @@ int32_t WebRtcAudioDeviceImpl::Init() { ...@@ -290,12 +281,13 @@ int32_t WebRtcAudioDeviceImpl::Init() {
// Ask the browser for the default audio output hardware sample-rate. // Ask the browser for the default audio output hardware sample-rate.
// This request is based on a synchronous IPC message. // This request is based on a synchronous IPC message.
int output_sample_rate = int output_sample_rate =
static_cast<int>(AudioDevice::GetAudioHardwareSampleRate()); static_cast<int>(audio_hardware::GetOutputSampleRate());
DVLOG(1) << "Audio output hardware sample rate: " << output_sample_rate; DVLOG(1) << "Audio output hardware sample rate: " << output_sample_rate;
// Ask the browser for the default audio input hardware sample-rate. // Ask the browser for the default audio input hardware sample-rate.
// This request is based on a synchronous IPC message. // This request is based on a synchronous IPC message.
int input_sample_rate = GetAudioInputHardwareSampleRate(); int input_sample_rate =
static_cast<int>(audio_hardware::GetInputSampleRate());
DVLOG(1) << "Audio input hardware sample rate: " << input_sample_rate; DVLOG(1) << "Audio input hardware sample rate: " << input_sample_rate;
int input_channels = 0; int input_channels = 0;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "third_party/webrtc/voice_engine/main/interface/voe_network.h" #include "third_party/webrtc/voice_engine/main/interface/voe_network.h"
using testing::_; using testing::_;
using testing::AnyNumber;
using testing::InvokeWithoutArgs; using testing::InvokeWithoutArgs;
using testing::Return; using testing::Return;
using testing::StrEq; using testing::StrEq;
...@@ -117,7 +118,7 @@ class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess { ...@@ -117,7 +118,7 @@ class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess {
// WebRtcAudioDeviceImpl. // WebRtcAudioDeviceImpl.
TEST_F(WebRTCAudioDeviceTest, Construct) { TEST_F(WebRTCAudioDeviceTest, Construct) {
AudioUtilNoHardware audio_util(48000.0, 48000.0); AudioUtilNoHardware audio_util(48000.0, 48000.0);
set_audio_util_callback(&audio_util); SetAudioUtilCallback(&audio_util);
scoped_refptr<WebRtcAudioDeviceImpl> audio_device( scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl()); new WebRtcAudioDeviceImpl());
audio_device->SetSessionId(1); audio_device->SetSessionId(1);
...@@ -142,7 +143,7 @@ TEST_F(WebRTCAudioDeviceTest, StartPlayout) { ...@@ -142,7 +143,7 @@ TEST_F(WebRTCAudioDeviceTest, StartPlayout) {
return; return;
AudioUtil audio_util; AudioUtil audio_util;
set_audio_util_callback(&audio_util); SetAudioUtilCallback(&audio_util);
EXPECT_CALL(media_observer(), EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1); OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
...@@ -151,7 +152,7 @@ TEST_F(WebRTCAudioDeviceTest, StartPlayout) { ...@@ -151,7 +152,7 @@ TEST_F(WebRTCAudioDeviceTest, StartPlayout) {
EXPECT_CALL(media_observer(), EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1); OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
EXPECT_CALL(media_observer(), EXPECT_CALL(media_observer(),
OnDeleteAudioStream(_, 1)).Times(1); OnDeleteAudioStream(_, 1)).Times(AnyNumber());
scoped_refptr<WebRtcAudioDeviceImpl> audio_device( scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl()); new WebRtcAudioDeviceImpl());
...@@ -211,7 +212,7 @@ TEST_F(WebRTCAudioDeviceTest, StartRecording) { ...@@ -211,7 +212,7 @@ TEST_F(WebRTCAudioDeviceTest, StartRecording) {
return; return;
AudioUtil audio_util; AudioUtil audio_util;
set_audio_util_callback(&audio_util); SetAudioUtilCallback(&audio_util);
// TODO(tommi): extend MediaObserver and MockMediaObserver with support // TODO(tommi): extend MediaObserver and MockMediaObserver with support
// for new interfaces, like OnSetAudioStreamRecording(). When done, add // for new interfaces, like OnSetAudioStreamRecording(). When done, add
...@@ -278,7 +279,7 @@ TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) { ...@@ -278,7 +279,7 @@ TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) {
GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm"))); GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm")));
AudioUtil audio_util; AudioUtil audio_util;
set_audio_util_callback(&audio_util); SetAudioUtilCallback(&audio_util);
EXPECT_CALL(media_observer(), EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1); OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
...@@ -287,7 +288,7 @@ TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) { ...@@ -287,7 +288,7 @@ TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) {
EXPECT_CALL(media_observer(), EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1); OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
EXPECT_CALL(media_observer(), EXPECT_CALL(media_observer(),
OnDeleteAudioStream(_, 1)).Times(1); OnDeleteAudioStream(_, 1)).Times(AnyNumber());
scoped_refptr<WebRtcAudioDeviceImpl> audio_device( scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl()); new WebRtcAudioDeviceImpl());
...@@ -334,8 +335,15 @@ TEST_F(WebRTCAudioDeviceTest, FullDuplexAudio) { ...@@ -334,8 +335,15 @@ TEST_F(WebRTCAudioDeviceTest, FullDuplexAudio) {
if (IsRunningHeadless()) if (IsRunningHeadless())
return; return;
EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("created")));
EXPECT_CALL(media_observer(),
OnSetAudioStreamPlaying(_, 1, true));
EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("closed")));
AudioUtil audio_util; AudioUtil audio_util;
set_audio_util_callback(&audio_util); SetAudioUtilCallback(&audio_util);
scoped_refptr<WebRtcAudioDeviceImpl> audio_device( scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl()); new WebRtcAudioDeviceImpl());
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "content/public/renderer/content_renderer_client.h" #include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h"
#include "content/renderer/media/audio_device.h" #include "content/renderer/media/audio_device.h"
#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
#include "content/renderer/renderer_webaudiodevice_impl.h" #include "content/renderer/renderer_webaudiodevice_impl.h"
#include "content/renderer/renderer_webidbfactory_impl.h" #include "content/renderer/renderer_webidbfactory_impl.h"
...@@ -564,11 +565,11 @@ RendererWebKitPlatformSupportImpl::createGraphicsContext3D() { ...@@ -564,11 +565,11 @@ RendererWebKitPlatformSupportImpl::createGraphicsContext3D() {
} }
double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() { double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() {
return AudioDevice::GetAudioHardwareSampleRate(); return audio_hardware::GetOutputSampleRate();
} }
size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() { size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() {
return AudioDevice::GetAudioHardwareBufferSize(); return audio_hardware::GetOutputBufferSize();
} }
WebAudioDevice* WebAudioDevice*
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/common/content_paths.h" #include "content/public/common/content_paths.h"
#include "content/renderer/media/audio_hardware.h"
#include "content/renderer/media/webrtc_audio_device_impl.h" #include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/render_process.h" #include "content/renderer/render_process.h"
#include "content/renderer/render_thread_impl.h" #include "content/renderer/render_thread_impl.h"
...@@ -125,10 +126,13 @@ void WebRTCAudioDeviceTest::SetUp() { ...@@ -125,10 +126,13 @@ void WebRTCAudioDeviceTest::SetUp() {
} }
void WebRTCAudioDeviceTest::TearDown() { void WebRTCAudioDeviceTest::TearDown() {
SetAudioUtilCallback(NULL);
ChildProcess::current()->io_message_loop()->PostTask( ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&SetupTask::UninitializeIOThread, new SetupTask(this))); base::Bind(&SetupTask::UninitializeIOThread, new SetupTask(this)));
WaitForIOThreadCompletion(); EXPECT_TRUE(event_.TimedWait(
base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
mock_process_.reset(); mock_process_.reset();
} }
...@@ -136,6 +140,13 @@ bool WebRTCAudioDeviceTest::Send(IPC::Message* message) { ...@@ -136,6 +140,13 @@ bool WebRTCAudioDeviceTest::Send(IPC::Message* message) {
return channel_->Send(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.
audio_hardware::ResetCache();
audio_util_callback_ = callback;
}
void WebRTCAudioDeviceTest::InitializeIOThread(const char* thread_name) { void WebRTCAudioDeviceTest::InitializeIOThread(const char* thread_name) {
// We initialize COM (STA) on our IO thread as is done in Chrome. // We initialize COM (STA) on our IO thread as is done in Chrome.
// See BrowserProcessSubThread::Init. // See BrowserProcessSubThread::Init.
...@@ -160,6 +171,7 @@ void WebRTCAudioDeviceTest::UninitializeIOThread() { ...@@ -160,6 +171,7 @@ void WebRTCAudioDeviceTest::UninitializeIOThread() {
media_stream_manager_.reset(); media_stream_manager_.reset();
test_request_context_ = NULL; test_request_context_ = NULL;
initialize_com_.reset(); initialize_com_.reset();
event_.Signal();
} }
void WebRTCAudioDeviceTest::CreateChannel( void WebRTCAudioDeviceTest::CreateChannel(
...@@ -182,7 +194,9 @@ void WebRTCAudioDeviceTest::CreateChannel( ...@@ -182,7 +194,9 @@ void WebRTCAudioDeviceTest::CreateChannel(
void WebRTCAudioDeviceTest::DestroyChannel() { void WebRTCAudioDeviceTest::DestroyChannel() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
audio_render_host_->OnChannelClosing(); audio_render_host_->OnChannelClosing();
audio_render_host_->OnFilterRemoved();
audio_input_renderer_host_->OnChannelClosing(); audio_input_renderer_host_->OnChannelClosing();
audio_input_renderer_host_->OnFilterRemoved();
channel_.reset(); channel_.reset();
audio_render_host_ = NULL; audio_render_host_ = NULL;
audio_input_renderer_host_ = NULL; audio_input_renderer_host_ = NULL;
...@@ -237,10 +251,6 @@ bool WebRTCAudioDeviceTest::OnMessageReceived(const IPC::Message& message) { ...@@ -237,10 +251,6 @@ bool WebRTCAudioDeviceTest::OnMessageReceived(const IPC::Message& message) {
EXPECT_TRUE(message_is_ok); EXPECT_TRUE(message_is_ok);
// We leave a DLOG as a hint to the developer in case important IPC messages
// are being dropped.
DLOG_IF(WARNING, !handled) << "Unhandled IPC message";
return true; return true;
} }
......
...@@ -140,9 +140,7 @@ class WebRTCAudioDeviceTest ...@@ -140,9 +140,7 @@ class WebRTCAudioDeviceTest
// Sends an IPC message to the IO thread channel. // Sends an IPC message to the IO thread channel.
bool Send(IPC::Message* message); bool Send(IPC::Message* message);
void set_audio_util_callback(AudioUtilInterface* callback) { void SetAudioUtilCallback(AudioUtilInterface* callback);
audio_util_callback_ = callback;
}
protected: protected:
void InitializeIOThread(const char* thread_name); void InitializeIOThread(const char* thread_name);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment