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 @@
'renderer/load_progress_tracker.h',
'renderer/media/audio_device.cc',
'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.h',
'renderer/media/audio_input_message_filter.cc',
......
......@@ -233,25 +233,3 @@ void AudioDevice::FireRenderCallback() {
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
double sample_rate() const { return sample_rate_; }
size_t buffer_size() const { return buffer_size_; }
static double GetAudioHardwareSampleRate();
static size_t GetAudioHardwareBufferSize();
// Methods called on IO thread ----------------------------------------------
// AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
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 @@
#include "base/bind.h"
#include "base/string_util.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 "media/audio/audio_util.h"
static const int64 kMillisecondsBetweenProcessCalls = 5000;
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()
: ref_count_(0),
render_loop_(base::MessageLoopProxy::current()),
......@@ -290,12 +281,13 @@ int32_t WebRtcAudioDeviceImpl::Init() {
// Ask the browser for the default audio output hardware sample-rate.
// This request is based on a synchronous IPC message.
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;
// Ask the browser for the default audio input hardware sample-rate.
// 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;
int input_channels = 0;
......
......@@ -15,6 +15,7 @@
#include "third_party/webrtc/voice_engine/main/interface/voe_network.h"
using testing::_;
using testing::AnyNumber;
using testing::InvokeWithoutArgs;
using testing::Return;
using testing::StrEq;
......@@ -117,7 +118,7 @@ class WebRTCMediaProcessImpl : public webrtc::VoEMediaProcess {
// WebRtcAudioDeviceImpl.
TEST_F(WebRTCAudioDeviceTest, Construct) {
AudioUtilNoHardware audio_util(48000.0, 48000.0);
set_audio_util_callback(&audio_util);
SetAudioUtilCallback(&audio_util);
scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl());
audio_device->SetSessionId(1);
......@@ -142,7 +143,7 @@ TEST_F(WebRTCAudioDeviceTest, StartPlayout) {
return;
AudioUtil audio_util;
set_audio_util_callback(&audio_util);
SetAudioUtilCallback(&audio_util);
EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
......@@ -151,7 +152,7 @@ TEST_F(WebRTCAudioDeviceTest, StartPlayout) {
EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
EXPECT_CALL(media_observer(),
OnDeleteAudioStream(_, 1)).Times(1);
OnDeleteAudioStream(_, 1)).Times(AnyNumber());
scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl());
......@@ -211,7 +212,7 @@ TEST_F(WebRTCAudioDeviceTest, StartRecording) {
return;
AudioUtil audio_util;
set_audio_util_callback(&audio_util);
SetAudioUtilCallback(&audio_util);
// TODO(tommi): extend MediaObserver and MockMediaObserver with support
// for new interfaces, like OnSetAudioStreamRecording(). When done, add
......@@ -278,7 +279,7 @@ TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) {
GetTestDataPath(FILE_PATH_LITERAL("speechmusic_mono_16kHz.pcm")));
AudioUtil audio_util;
set_audio_util_callback(&audio_util);
SetAudioUtilCallback(&audio_util);
EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("created"))).Times(1);
......@@ -287,7 +288,7 @@ TEST_F(WebRTCAudioDeviceTest, PlayLocalFile) {
EXPECT_CALL(media_observer(),
OnSetAudioStreamStatus(_, 1, StrEq("closed"))).Times(1);
EXPECT_CALL(media_observer(),
OnDeleteAudioStream(_, 1)).Times(1);
OnDeleteAudioStream(_, 1)).Times(AnyNumber());
scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl());
......@@ -334,8 +335,15 @@ TEST_F(WebRTCAudioDeviceTest, FullDuplexAudio) {
if (IsRunningHeadless())
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;
set_audio_util_callback(&audio_util);
SetAudioUtilCallback(&audio_util);
scoped_refptr<WebRtcAudioDeviceImpl> audio_device(
new WebRtcAudioDeviceImpl());
......
......@@ -22,6 +22,7 @@
#include "content/public/renderer/content_renderer_client.h"
#include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.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/renderer_webaudiodevice_impl.h"
#include "content/renderer/renderer_webidbfactory_impl.h"
......@@ -564,11 +565,11 @@ RendererWebKitPlatformSupportImpl::createGraphicsContext3D() {
}
double RendererWebKitPlatformSupportImpl::audioHardwareSampleRate() {
return AudioDevice::GetAudioHardwareSampleRate();
return audio_hardware::GetOutputSampleRate();
}
size_t RendererWebKitPlatformSupportImpl::audioHardwareBufferSize() {
return AudioDevice::GetAudioHardwareBufferSize();
return audio_hardware::GetOutputBufferSize();
}
WebAudioDevice*
......
......@@ -19,6 +19,7 @@
#include "content/common/view_messages.h"
#include "content/public/browser/browser_thread.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/render_process.h"
#include "content/renderer/render_thread_impl.h"
......@@ -125,10 +126,13 @@ void WebRTCAudioDeviceTest::SetUp() {
}
void WebRTCAudioDeviceTest::TearDown() {
SetAudioUtilCallback(NULL);
ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE,
base::Bind(&SetupTask::UninitializeIOThread, new SetupTask(this)));
WaitForIOThreadCompletion();
EXPECT_TRUE(event_.TimedWait(
base::TimeDelta::FromMilliseconds(TestTimeouts::action_timeout_ms())));
mock_process_.reset();
}
......@@ -136,6 +140,13 @@ 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.
audio_hardware::ResetCache();
audio_util_callback_ = callback;
}
void WebRTCAudioDeviceTest::InitializeIOThread(const char* thread_name) {
// We initialize COM (STA) on our IO thread as is done in Chrome.
// See BrowserProcessSubThread::Init.
......@@ -160,6 +171,7 @@ void WebRTCAudioDeviceTest::UninitializeIOThread() {
media_stream_manager_.reset();
test_request_context_ = NULL;
initialize_com_.reset();
event_.Signal();
}
void WebRTCAudioDeviceTest::CreateChannel(
......@@ -182,7 +194,9 @@ void WebRTCAudioDeviceTest::CreateChannel(
void WebRTCAudioDeviceTest::DestroyChannel() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
audio_render_host_->OnChannelClosing();
audio_render_host_->OnFilterRemoved();
audio_input_renderer_host_->OnChannelClosing();
audio_input_renderer_host_->OnFilterRemoved();
channel_.reset();
audio_render_host_ = NULL;
audio_input_renderer_host_ = NULL;
......@@ -237,10 +251,6 @@ bool WebRTCAudioDeviceTest::OnMessageReceived(const IPC::Message& message) {
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;
}
......
......@@ -140,9 +140,7 @@ class WebRTCAudioDeviceTest
// Sends an IPC message to the IO thread channel.
bool Send(IPC::Message* message);
void set_audio_util_callback(AudioUtilInterface* callback) {
audio_util_callback_ = callback;
}
void SetAudioUtilCallback(AudioUtilInterface* callback);
protected:
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