summaryrefslogtreecommitdiffstats
path: root/content/renderer
diff options
context:
space:
mode:
authortommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-26 11:52:36 +0000
committertommi@chromium.org <tommi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-26 11:52:36 +0000
commit94bbdac2dcb4ab8a719e21fec1e255ad1cad59f0 (patch)
tree89a8514e469183bf2cde15a88d6173a74ce2a6b3 /content/renderer
parent58cddec2e966620674519cb1d0cc56861687b380 (diff)
downloadchromium_src-94bbdac2dcb4ab8a719e21fec1e255ad1cad59f0.zip
chromium_src-94bbdac2dcb4ab8a719e21fec1e255ad1cad59f0.tar.gz
chromium_src-94bbdac2dcb4ab8a719e21fec1e255ad1cad59f0.tar.bz2
First step towards moving AudioDevice and AudioInputDevice from content/ to media/audio. This cl introduces new IPC interface files in media/audio that have the definitions of an IPC layer for AudioDevice and AudioInputDevice.
AudioMessageFilter, AudionInputMessageFilter and others have been updated to use definitions from these file but in order to keep the diffs simple, I haven't actually moved the files over to media/audio. That will be the next step (and then no code changes should be needed). TEST=There should be no functional changes here. If there are problems, they should be caught by our existing unit tests or build errors. Review URL: https://chromiumcodereview.appspot.com/10790121 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148533 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer')
-rw-r--r--content/renderer/media/audio_device.cc52
-rw-r--r--content/renderer/media/audio_device.h47
-rw-r--r--content/renderer/media/audio_device_factory.cc26
-rw-r--r--content/renderer/media/audio_device_factory.h18
-rw-r--r--content/renderer/media/audio_device_unittest.cc57
-rw-r--r--content/renderer/media/audio_input_device.cc108
-rw-r--r--content/renderer/media/audio_input_device.h120
-rw-r--r--content/renderer/media/audio_input_message_filter.cc70
-rw-r--r--content/renderer/media/audio_input_message_filter.h58
-rw-r--r--content/renderer/media/audio_message_filter.cc55
-rw-r--r--content/renderer/media/audio_message_filter.h47
-rw-r--r--content/renderer/media/audio_message_filter_unittest.cc42
-rw-r--r--content/renderer/media/audio_renderer_mixer_manager.cc2
-rw-r--r--content/renderer/media/audio_renderer_mixer_manager_unittest.cc7
-rw-r--r--content/renderer/media/render_audiosourceprovider.cc2
-rw-r--r--content/renderer/media/renderer_webaudiodevice_impl.cc2
-rw-r--r--content/renderer/media/webrtc_audio_device_impl.cc8
-rw-r--r--content/renderer/pepper/pepper_platform_audio_input_impl.cc34
-rw-r--r--content/renderer/pepper/pepper_platform_audio_input_impl.h16
-rw-r--r--content/renderer/pepper/pepper_platform_audio_output_impl.cc31
-rw-r--r--content/renderer/pepper/pepper_platform_audio_output_impl.h16
21 files changed, 427 insertions, 391 deletions
diff --git a/content/renderer/media/audio_device.cc b/content/renderer/media/audio_device.cc
index 9936ebd..db1e592 100644
--- a/content/renderer/media/audio_device.cc
+++ b/content/renderer/media/audio_device.cc
@@ -8,8 +8,6 @@
#include "base/message_loop.h"
#include "base/threading/thread_restrictions.h"
#include "base/time.h"
-#include "content/common/media/audio_messages.h"
-#include "content/common/view_messages.h"
#include "media/audio/audio_output_controller.h"
#include "media/audio/audio_util.h"
@@ -38,15 +36,15 @@ class AudioDevice::AudioThreadCallback
};
AudioDevice::AudioDevice(
+ media::AudioOutputIPC* ipc,
const scoped_refptr<base::MessageLoopProxy>& io_loop)
: ScopedLoopObserver(io_loop),
callback_(NULL),
+ ipc_(ipc),
stream_id_(0),
play_on_start_(true),
is_started_(false) {
- // Use the filter instance already created on the main render thread.
- CHECK(AudioMessageFilter::Get()) << "Invalid audio message filter.";
- filter_ = AudioMessageFilter::Get();
+ CHECK(ipc_);
}
void AudioDevice::Initialize(const media::AudioParameters& params,
@@ -112,14 +110,14 @@ void AudioDevice::CreateStreamOnIOThread(const media::AudioParameters& params) {
if (stream_id_)
return;
- stream_id_ = filter_->AddDelegate(this);
- Send(new AudioHostMsg_CreateStream(stream_id_, params));
+ stream_id_ = ipc_->AddDelegate(this);
+ ipc_->CreateStream(stream_id_, params);
}
void AudioDevice::PlayOnIOThread() {
DCHECK(message_loop()->BelongsToCurrentThread());
if (stream_id_ && is_started_)
- Send(new AudioHostMsg_PlayStream(stream_id_));
+ ipc_->PlayStream(stream_id_);
else
play_on_start_ = true;
}
@@ -127,9 +125,9 @@ void AudioDevice::PlayOnIOThread() {
void AudioDevice::PauseOnIOThread(bool flush) {
DCHECK(message_loop()->BelongsToCurrentThread());
if (stream_id_ && is_started_) {
- Send(new AudioHostMsg_PauseStream(stream_id_));
+ ipc_->PauseStream(stream_id_);
if (flush)
- Send(new AudioHostMsg_FlushStream(stream_id_));
+ ipc_->FlushStream(stream_id_);
} else {
// Note that |flush| isn't relevant here since this is the case where
// the stream is first starting.
@@ -144,8 +142,8 @@ void AudioDevice::ShutDownOnIOThread() {
if (stream_id_) {
is_started_ = false;
- filter_->RemoveDelegate(stream_id_);
- Send(new AudioHostMsg_CloseStream(stream_id_));
+ ipc_->CloseStream(stream_id_);
+ ipc_->RemoveDelegate(stream_id_);
stream_id_ = 0;
}
@@ -164,17 +162,17 @@ void AudioDevice::ShutDownOnIOThread() {
void AudioDevice::SetVolumeOnIOThread(double volume) {
DCHECK(message_loop()->BelongsToCurrentThread());
if (stream_id_)
- Send(new AudioHostMsg_SetVolume(stream_id_, volume));
+ ipc_->SetVolume(stream_id_, volume);
}
-void AudioDevice::OnStateChanged(AudioStreamState state) {
+void AudioDevice::OnStateChanged(media::AudioOutputIPCDelegate::State state) {
DCHECK(message_loop()->BelongsToCurrentThread());
// Do nothing if the stream has been closed.
if (!stream_id_)
return;
- if (state == kAudioStreamError) {
+ if (state == media::AudioOutputIPCDelegate::kError) {
DLOG(WARNING) << "AudioDevice::OnStateChanged(kError)";
// Don't dereference the callback object if the audio thread
// is stopped or stopping. That could mean that the callback
@@ -190,10 +188,9 @@ void AudioDevice::OnStateChanged(AudioStreamState state) {
void AudioDevice::OnStreamCreated(
base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) {
+ int length) {
DCHECK(message_loop()->BelongsToCurrentThread());
- // TODO(vrk): Remove cast when |length| is int instead of uint32.
- DCHECK_GE(length, static_cast<uint32>(audio_parameters_.GetBytesPerBuffer()));
+ DCHECK_GE(length, audio_parameters_.GetBytesPerBuffer());
#if defined(OS_WIN)
DCHECK(handle);
DCHECK(socket_handle);
@@ -202,15 +199,14 @@ void AudioDevice::OnStreamCreated(
DCHECK_GE(socket_handle, 0);
#endif
- base::AutoLock auto_lock(audio_thread_lock_);
+ // We should only get this callback if stream_id_ is valid. If it is not,
+ // the IPC layer should have closed the shared memory and socket handles
+ // for us and not invoked the callback. The basic assertion is that when
+ // stream_id_ is 0 the AudioDevice instance is not registered as a delegate
+ // and hence it should not receive callbacks.
+ DCHECK(stream_id_);
- // Takes care of the case when Stop() is called before OnStreamCreated().
- if (!stream_id_) {
- base::SharedMemory::CloseHandle(handle);
- // Close the socket handler.
- base::SyncSocket socket(socket_handle);
- return;
- }
+ base::AutoLock auto_lock(audio_thread_lock_);
DCHECK(audio_thread_.IsStopped());
audio_callback_.reset(new AudioDevice::AudioThreadCallback(audio_parameters_,
@@ -224,8 +220,8 @@ void AudioDevice::OnStreamCreated(
PlayOnIOThread();
}
-void AudioDevice::Send(IPC::Message* message) {
- filter_->Send(message);
+void AudioDevice::OnIPCClosed() {
+ ipc_ = NULL;
}
void AudioDevice::WillDestroyCurrentMessageLoop() {
diff --git a/content/renderer/media/audio_device.h b/content/renderer/media/audio_device.h
index 1eee2c3..56c2c86 100644
--- a/content/renderer/media/audio_device.h
+++ b/content/renderer/media/audio_device.h
@@ -23,19 +23,19 @@
//
// Task [IO thread] IPC [IO thread]
//
-// Start -> CreateStreamOnIOThread -----> AudioHostMsg_CreateStream ------>
+// Start -> CreateStreamOnIOThread -----> CreateStream ------>
// <- OnStreamCreated <- AudioMsg_NotifyStreamCreated <-
-// ---> PlayOnIOThread -----------> AudioHostMsg_PlayStream -------->
+// ---> PlayOnIOThread -----------> PlayStream -------->
//
// Optionally Play() / Pause() sequences may occur:
-// Play -> PlayOnIOThread --------------> AudioHostMsg_PlayStream --------->
-// Pause -> PauseOnIOThread ------------> AudioHostMsg_PauseStream -------->
+// Play -> PlayOnIOThread --------------> PlayStream --------->
+// Pause -> PauseOnIOThread ------------> PauseStream -------->
// (note that Play() / Pause() sequences before OnStreamCreated are
// deferred until OnStreamCreated, with the last valid state being used)
//
// AudioDevice::Render => audio transport on audio thread =>
// |
-// Stop --> ShutDownOnIOThread --------> AudioHostMsg_CloseStream -> Close
+// Stop --> ShutDownOnIOThread --------> CloseStream -> Close
//
// This class utilizes several threads during its lifetime, namely:
// 1. Creating thread.
@@ -70,8 +70,8 @@
#include "base/shared_memory.h"
#include "content/common/content_export.h"
#include "content/renderer/media/audio_device_thread.h"
-#include "content/renderer/media/audio_message_filter.h"
#include "content/renderer/media/scoped_loop_observer.h"
+#include "media/audio/audio_output_ipc.h"
#include "media/audio/audio_parameters.h"
#include "media/base/audio_renderer_sink.h"
@@ -79,13 +79,9 @@ namespace media {
class AudioParameters;
}
-namespace content {
-class AudioDeviceFactory;
-}
-
class CONTENT_EXPORT AudioDevice
: NON_EXPORTED_BASE(public media::AudioRendererSink),
- public AudioMessageFilter::Delegate,
+ public media::AudioOutputIPCDelegate,
NON_EXPORTED_BASE(public ScopedLoopObserver) {
public:
// Methods called on main render thread -------------------------------------
@@ -100,24 +96,22 @@ class CONTENT_EXPORT AudioDevice
virtual bool SetVolume(double volume) OVERRIDE;
// Methods called on IO thread ----------------------------------------------
- // AudioMessageFilter::Delegate methods, called by AudioMessageFilter.
- virtual void OnStateChanged(AudioStreamState state) OVERRIDE;
+ // AudioOutputIPCDelegate methods.
+ virtual void OnStateChanged(
+ media::AudioOutputIPCDelegate::State state) OVERRIDE;
virtual void OnStreamCreated(base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) OVERRIDE;
-
- protected:
- friend class content::AudioDeviceFactory;
+ int length) OVERRIDE;
+ virtual void OnIPCClosed() OVERRIDE;
// Creates an uninitialized AudioDevice. Clients must call Initialize()
- // before using. The constructor is protected to ensure that the
- // AudioDeviceFactory is always used for construction in Chrome.
- // Tests should use a test class that inherits from AudioDevice to gain
- // access to the constructor.
+ // before using.
// TODO(tommi): When all dependencies on |content| have been removed
// from AudioDevice, move this class over to media/audio.
- explicit AudioDevice(const scoped_refptr<base::MessageLoopProxy>& io_loop);
+ AudioDevice(media::AudioOutputIPC* ipc,
+ const scoped_refptr<base::MessageLoopProxy>& io_loop);
+ protected:
// Magic required by ref_counted.h to avoid any code deleting the object
// accidentally while there are references to it.
friend class base::RefCountedThreadSafe<AudioDevice>;
@@ -134,8 +128,6 @@ class CONTENT_EXPORT AudioDevice
void ShutDownOnIOThread();
void SetVolumeOnIOThread(double volume);
- void Send(IPC::Message* message);
-
// MessageLoop::DestructionObserver implementation for the IO loop.
// If the IO loop dies before we do, we shut down the audio thread from here.
virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
@@ -144,12 +136,13 @@ class CONTENT_EXPORT AudioDevice
RenderCallback* callback_;
- // Cached audio message filter (lives on the main render thread).
- scoped_refptr<AudioMessageFilter> filter_;
+ // A pointer to the IPC layer that takes care of sending requests over to
+ // the AudioRendererHost.
+ media::AudioOutputIPC* ipc_;
// Our stream ID on the message filter. Only accessed on the IO thread.
// Must only be modified on the IO thread.
- int32 stream_id_;
+ int stream_id_;
// State of Play() / Pause() calls before OnStreamCreated() is called.
bool play_on_start_;
diff --git a/content/renderer/media/audio_device_factory.cc b/content/renderer/media/audio_device_factory.cc
index ee7906f..e200b0a 100644
--- a/content/renderer/media/audio_device_factory.cc
+++ b/content/renderer/media/audio_device_factory.cc
@@ -7,6 +7,9 @@
#include "base/logging.h"
#include "content/common/child_process.h"
#include "content/renderer/media/audio_device.h"
+#include "content/renderer/media/audio_input_device.h"
+#include "content/renderer/media/audio_input_message_filter.h"
+#include "content/renderer/media/audio_message_filter.h"
namespace content {
@@ -14,11 +17,24 @@ namespace content {
AudioDeviceFactory* AudioDeviceFactory::factory_ = NULL;
// static
-media::AudioRendererSink* AudioDeviceFactory::Create() {
- if (factory_) {
- return factory_->CreateAudioDevice();
- }
- return new AudioDevice(
+media::AudioRendererSink* AudioDeviceFactory::NewOutputDevice() {
+ media::AudioRendererSink* device = NULL;
+ if (factory_)
+ device = factory_->CreateOutputDevice();
+
+ return device ? device : new AudioDevice(
+ AudioMessageFilter::Get(),
+ ChildProcess::current()->io_message_loop()->message_loop_proxy());
+}
+
+// static
+AudioInputDevice* AudioDeviceFactory::NewInputDevice() {
+ AudioInputDevice* device = NULL;
+ if (factory_)
+ device = factory_->CreateInputDevice();
+
+ return device ? device : new AudioInputDevice(
+ AudioInputMessageFilter::Get(),
ChildProcess::current()->io_message_loop()->message_loop_proxy());
}
diff --git a/content/renderer/media/audio_device_factory.h b/content/renderer/media/audio_device_factory.h
index b15e967..14433ce 100644
--- a/content/renderer/media/audio_device_factory.h
+++ b/content/renderer/media/audio_device_factory.h
@@ -12,6 +12,8 @@ namespace media {
class AudioRendererSink;
}
+class AudioInputDevice;
+
namespace content {
// A factory for creating AudioRendererSinks. There is a global factory
@@ -23,15 +25,23 @@ class CONTENT_EXPORT AudioDeviceFactory {
// Creates an AudioRendererSink using the currently registered factory,
// or the default one if no factory is registered. Ownership of the returned
// pointer will be passed to the caller.
- static media::AudioRendererSink* Create();
+ static media::AudioRendererSink* NewOutputDevice();
+
+ // TODO(henrika): Update AudioInputDevice to inherit from an interface
+ // similar to AudioRendererSink, but for input. Same for the callback
+ // interfaces.
+ static AudioInputDevice* NewInputDevice();
protected:
AudioDeviceFactory();
virtual ~AudioDeviceFactory();
- // You can derive from this class and specify an implementation for this
- // function to create a different kind of AudioRendererSink for testing.
- virtual media::AudioRendererSink* CreateAudioDevice() = 0;
+ // You can derive from this class and specify an implementation for these
+ // functions to provide alternate audio device implementations.
+ // If the return value of either of these function is NULL, we fall back
+ // on the default implementation.
+ virtual media::AudioRendererSink* CreateOutputDevice() = 0;
+ virtual AudioInputDevice* CreateInputDevice() = 0;
private:
// The current globally registered factory. This is NULL when we should
diff --git a/content/renderer/media/audio_device_unittest.cc b/content/renderer/media/audio_device_unittest.cc
index 4612ec7..996e354 100644
--- a/content/renderer/media/audio_device_unittest.cc
+++ b/content/renderer/media/audio_device_unittest.cc
@@ -30,16 +30,6 @@ using testing::WithArgs;
namespace {
-// Derived from AudioDevice to gain access to the protected constructor.
-class TestAudioDevice : public AudioDevice {
- public:
- explicit TestAudioDevice(const scoped_refptr<base::MessageLoopProxy>& io_loop)
- : AudioDevice(io_loop) {}
-
- protected:
- virtual ~TestAudioDevice() {}
-};
-
class MockRenderCallback : public media::AudioRendererSink::RenderCallback {
public:
MockRenderCallback() {}
@@ -55,29 +45,13 @@ class MockAudioMessageFilter : public AudioMessageFilter {
public:
MockAudioMessageFilter() {}
- virtual bool Send(IPC::Message* message) OVERRIDE {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(MockAudioMessageFilter, *message)
- IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream)
- IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream)
- IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream)
- IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
- IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
- IPC_MESSAGE_HANDLER(AudioHostMsg_FlushStream, OnFlushStream)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- EXPECT_TRUE(handled);
- delete message;
- return true;
- }
-
- MOCK_METHOD2(OnCreateStream,
+ MOCK_METHOD2(CreateStream,
void(int stream_id, const media::AudioParameters& params));
- MOCK_METHOD1(OnPlayStream, void(int stream_id));
- MOCK_METHOD1(OnCloseStream, void(int stream_id));
- MOCK_METHOD2(OnSetVolume, void(int stream_id, double volume));
- MOCK_METHOD1(OnPauseStream, void(int stream_id));
- MOCK_METHOD1(OnFlushStream, void(int stream_id));
+ MOCK_METHOD1(PlayStream, void(int stream_id));
+ MOCK_METHOD1(CloseStream, void(int stream_id));
+ MOCK_METHOD2(SetVolume, void(int stream_id, double volume));
+ MOCK_METHOD1(PauseStream, void(int stream_id));
+ MOCK_METHOD1(FlushStream, void(int stream_id));
protected:
virtual ~MockAudioMessageFilter() {}
@@ -145,7 +119,8 @@ class AudioDeviceTest : public testing::Test {
}
AudioDevice* CreateAudioDevice() {
- return new TestAudioDevice(io_loop_.message_loop_proxy());
+ return new AudioDevice(
+ audio_message_filter_, io_loop_.message_loop_proxy());
}
void set_stream_id(int stream_id) { stream_id_ = stream_id; }
@@ -162,8 +137,7 @@ class AudioDeviceTest : public testing::Test {
};
// The simplest test for AudioDevice. Used to test construction of AudioDevice
-// and that the runtime environment is set up correctly (e.g. ChildProcess and
-// AudioMessageFilter global pointers).
+// and that the runtime environment is set up correctly.
TEST_F(AudioDeviceTest, Initialize) {
scoped_refptr<AudioDevice> audio_device(CreateAudioDevice());
audio_device->Initialize(default_audio_parameters_, &callback_);
@@ -179,8 +153,8 @@ TEST_F(AudioDeviceTest, StartStop) {
audio_device->Start();
audio_device->Stop();
- EXPECT_CALL(*audio_message_filter_, OnCreateStream(_, _));
- EXPECT_CALL(*audio_message_filter_, OnCloseStream(_));
+ EXPECT_CALL(*audio_message_filter_, CreateStream(_, _));
+ EXPECT_CALL(*audio_message_filter_, CloseStream(_));
io_loop_.RunAllPending();
}
@@ -194,11 +168,12 @@ TEST_F(AudioDeviceTest, CreateStream) {
audio_device->Start();
- EXPECT_CALL(*audio_message_filter_, OnCreateStream(_, _))
+ EXPECT_CALL(*audio_message_filter_, CreateStream(_, _))
.WillOnce(WithArgs<0>(Invoke(this, &AudioDeviceTest::set_stream_id)));
EXPECT_EQ(stream_id_, -1);
io_loop_.RunAllPending();
+
// OnCreateStream() must have been called and we should have a valid
// stream id.
ASSERT_NE(stream_id_, -1);
@@ -211,7 +186,6 @@ TEST_F(AudioDeviceTest, CreateStream) {
default_audio_parameters_.GetBytesPerBuffer());
SharedMemory shared_memory;
ASSERT_TRUE(shared_memory.CreateAndMapAnonymous(memory_size));
- // Initialize the memory.
memset(shared_memory.memory(), 0xff, memory_size);
CancelableSyncSocket browser_socket, renderer_socket;
@@ -231,7 +205,7 @@ TEST_F(AudioDeviceTest, CreateStream) {
// Respond by asking for some audio data. This should ask our callback
// to provide some audio data that AudioDevice then writes into the shared
// memory section.
- EXPECT_CALL(*audio_message_filter_, OnPlayStream(stream_id_))
+ EXPECT_CALL(*audio_message_filter_, PlayStream(stream_id_))
.WillOnce(SendPendingBytes(&browser_socket, memory_size));
// We expect calls to our audio renderer callback, which returns the number
@@ -268,8 +242,7 @@ TEST_F(AudioDeviceTest, CreateStream) {
io_loop_.Run();
// Close the stream sequence.
-
- EXPECT_CALL(*audio_message_filter_, OnCloseStream(stream_id_));
+ EXPECT_CALL(*audio_message_filter_, CloseStream(stream_id_));
audio_device->Stop();
io_loop_.RunAllPending();
diff --git a/content/renderer/media/audio_input_device.cc b/content/renderer/media/audio_input_device.cc
index 6d85143..2f521a8 100644
--- a/content/renderer/media/audio_input_device.cc
+++ b/content/renderer/media/audio_input_device.cc
@@ -8,10 +8,6 @@
#include "base/message_loop.h"
#include "base/threading/thread_restrictions.h"
#include "base/time.h"
-#include "content/common/child_process.h"
-#include "content/common/media/audio_messages.h"
-#include "content/common/view_messages.h"
-#include "content/renderer/render_thread_impl.h"
#include "media/audio/audio_manager_base.h"
#include "media/audio/audio_util.h"
@@ -37,20 +33,28 @@ class AudioInputDevice::AudioThreadCallback
DISALLOW_COPY_AND_ASSIGN(AudioThreadCallback);
};
-AudioInputDevice::AudioInputDevice(const media::AudioParameters& params,
- CaptureCallback* callback,
- CaptureEventHandler* event_handler)
- : ScopedLoopObserver(
- ChildProcess::current()->io_message_loop()->message_loop_proxy()),
- audio_parameters_(params),
- callback_(callback),
- event_handler_(event_handler),
- volume_(1.0),
+AudioInputDevice::AudioInputDevice(
+ media::AudioInputIPC* ipc,
+ const scoped_refptr<base::MessageLoopProxy>& io_loop)
+ : ScopedLoopObserver(io_loop),
+ callback_(NULL),
+ event_handler_(NULL),
+ ipc_(ipc),
stream_id_(0),
session_id_(0),
pending_device_ready_(false),
agc_is_enabled_(false) {
- filter_ = RenderThreadImpl::current()->audio_input_message_filter();
+ CHECK(ipc_);
+}
+
+void AudioInputDevice::Initialize(const media::AudioParameters& params,
+ CaptureCallback* callback,
+ CaptureEventHandler* event_handler) {
+ DCHECK(!callback_);
+ DCHECK(!event_handler_);
+ audio_parameters_ = params;
+ callback_ = callback;
+ event_handler_ = event_handler;
}
void AudioInputDevice::SetDevice(int session_id) {
@@ -77,14 +81,14 @@ void AudioInputDevice::Stop() {
base::Bind(&AudioInputDevice::ShutDownOnIOThread, this));
}
-bool AudioInputDevice::SetVolume(double volume) {
- if (volume < 0 || volume > 1.0)
- return false;
+void AudioInputDevice::SetVolume(double volume) {
+ if (volume < 0 || volume > 1.0) {
+ DLOG(ERROR) << "Invalid volume value specified";
+ return;
+ }
message_loop()->PostTask(FROM_HERE,
base::Bind(&AudioInputDevice::SetVolumeOnIOThread, this, volume));
-
- return true;
}
void AudioInputDevice::SetAutomaticGainControl(bool enabled) {
@@ -97,7 +101,7 @@ void AudioInputDevice::SetAutomaticGainControl(bool enabled) {
void AudioInputDevice::OnStreamCreated(
base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) {
+ int length) {
DCHECK(message_loop()->BelongsToCurrentThread());
#if defined(OS_WIN)
DCHECK(handle);
@@ -109,15 +113,14 @@ void AudioInputDevice::OnStreamCreated(
DCHECK(length);
DVLOG(1) << "OnStreamCreated (stream_id=" << stream_id_ << ")";
- base::AutoLock auto_lock(audio_thread_lock_);
+ // We should only get this callback if stream_id_ is valid. If it is not,
+ // the IPC layer should have closed the shared memory and socket handles
+ // for us and not invoked the callback. The basic assertion is that when
+ // stream_id_ is 0 the AudioInputDevice instance is not registered as a
+ // delegate and hence it should not receive callbacks.
+ DCHECK(stream_id_);
- // Takes care of the case when Stop() is called before OnStreamCreated().
- if (!stream_id_) {
- base::SharedMemory::CloseHandle(handle);
- // Close the socket handler.
- base::SyncSocket socket(socket_handle);
- return;
- }
+ base::AutoLock auto_lock(audio_thread_lock_);
DCHECK(audio_thread_.IsStopped());
audio_callback_.reset(
@@ -133,7 +136,8 @@ void AudioInputDevice::OnVolume(double volume) {
NOTIMPLEMENTED();
}
-void AudioInputDevice::OnStateChanged(AudioStreamState state) {
+void AudioInputDevice::OnStateChanged(
+ media::AudioInputIPCDelegate::State state) {
DCHECK(message_loop()->BelongsToCurrentThread());
// Do nothing if the stream has been closed.
@@ -141,11 +145,9 @@ void AudioInputDevice::OnStateChanged(AudioStreamState state) {
return;
switch (state) {
- // TODO(xians): This should really be kAudioStreamStopped since the stream
- // has been closed at this point.
- case kAudioStreamPaused:
+ case media::AudioInputIPCDelegate::kStopped:
// TODO(xians): Should we just call ShutDownOnIOThread here instead?
- filter_->RemoveDelegate(stream_id_);
+ ipc_->RemoveDelegate(stream_id_);
audio_thread_.Stop(MessageLoop::current());
audio_callback_.reset();
@@ -156,10 +158,10 @@ void AudioInputDevice::OnStateChanged(AudioStreamState state) {
stream_id_ = 0;
pending_device_ready_ = false;
break;
- case kAudioStreamPlaying:
+ case media::AudioInputIPCDelegate::kRecording:
NOTIMPLEMENTED();
break;
- case kAudioStreamError:
+ case media::AudioInputIPCDelegate::kError:
DLOG(WARNING) << "AudioInputDevice::OnStateChanged(kError)";
// Don't dereference the callback object if the audio thread
// is stopped or stopping. That could mean that the callback
@@ -187,11 +189,11 @@ void AudioInputDevice::OnDeviceReady(const std::string& device_id) {
// If AudioInputDeviceManager returns an empty string, it means no device
// is ready for start.
if (device_id.empty()) {
- filter_->RemoveDelegate(stream_id_);
+ ipc_->RemoveDelegate(stream_id_);
stream_id_ = 0;
} else {
- Send(new AudioInputHostMsg_CreateStream(stream_id_, audio_parameters_,
- device_id, agc_is_enabled_));
+ ipc_->CreateStream(stream_id_, audio_parameters_, device_id,
+ agc_is_enabled_);
}
pending_device_ready_ = false;
@@ -200,6 +202,10 @@ void AudioInputDevice::OnDeviceReady(const std::string& device_id) {
event_handler_->OnDeviceStarted(device_id);
}
+void AudioInputDevice::OnIPCClosed() {
+ ipc_ = NULL;
+}
+
AudioInputDevice::~AudioInputDevice() {
// TODO(henrika): The current design requires that the user calls
// Stop before deleting this class.
@@ -213,17 +219,15 @@ void AudioInputDevice::InitializeOnIOThread() {
if (stream_id_)
return;
- stream_id_ = filter_->AddDelegate(this);
+ stream_id_ = ipc_->AddDelegate(this);
// If |session_id_| is not specified, it will directly create the stream;
// otherwise it will send a AudioInputHostMsg_StartDevice msg to the browser
// and create the stream when getting a OnDeviceReady() callback.
if (!session_id_) {
- Send(new AudioInputHostMsg_CreateStream(
- stream_id_, audio_parameters_,
- media::AudioManagerBase::kDefaultDeviceId,
- agc_is_enabled_));
+ ipc_->CreateStream(stream_id_, audio_parameters_,
+ media::AudioManagerBase::kDefaultDeviceId, agc_is_enabled_);
} else {
- Send(new AudioInputHostMsg_StartDevice(stream_id_, session_id_));
+ ipc_->StartDevice(stream_id_, session_id_);
pending_device_ready_ = true;
}
}
@@ -236,7 +240,7 @@ void AudioInputDevice::SetSessionIdOnIOThread(int session_id) {
void AudioInputDevice::StartOnIOThread() {
DCHECK(message_loop()->BelongsToCurrentThread());
if (stream_id_)
- Send(new AudioInputHostMsg_RecordStream(stream_id_));
+ ipc_->RecordStream(stream_id_);
}
void AudioInputDevice::ShutDownOnIOThread() {
@@ -244,8 +248,8 @@ void AudioInputDevice::ShutDownOnIOThread() {
// NOTE: |completion| may be NULL.
// Make sure we don't call shutdown more than once.
if (stream_id_) {
- filter_->RemoveDelegate(stream_id_);
- Send(new AudioInputHostMsg_CloseStream(stream_id_));
+ ipc_->CloseStream(stream_id_);
+ ipc_->RemoveDelegate(stream_id_);
stream_id_ = 0;
session_id_ = 0;
@@ -268,7 +272,7 @@ void AudioInputDevice::ShutDownOnIOThread() {
void AudioInputDevice::SetVolumeOnIOThread(double volume) {
DCHECK(message_loop()->BelongsToCurrentThread());
if (stream_id_)
- Send(new AudioInputHostMsg_SetVolume(stream_id_, volume));
+ ipc_->SetVolume(stream_id_, volume);
}
void AudioInputDevice::SetAutomaticGainControlOnIOThread(bool enabled) {
@@ -283,10 +287,6 @@ void AudioInputDevice::SetAutomaticGainControlOnIOThread(bool enabled) {
agc_is_enabled_ = enabled;
}
-void AudioInputDevice::Send(IPC::Message* message) {
- filter_->Send(message);
-}
-
void AudioInputDevice::WillDestroyCurrentMessageLoop() {
LOG(ERROR) << "IO loop going away before the input device has been stopped";
ShutDownOnIOThread();
@@ -315,8 +315,8 @@ void AudioInputDevice::AudioThreadCallback::Process(int pending_data) {
// structure and parse out parameters and the data area.
media::AudioInputBuffer* buffer =
reinterpret_cast<media::AudioInputBuffer*>(shared_memory_.memory());
- uint32 size = buffer->params.size;
- DCHECK_EQ(size, memory_length_ - sizeof(media::AudioInputBufferParameters));
+ DCHECK_EQ(buffer->params.size,
+ memory_length_ - sizeof(media::AudioInputBufferParameters));
double volume = buffer->params.volume;
int audio_delay_milliseconds = pending_data / bytes_per_ms_;
diff --git a/content/renderer/media/audio_input_device.h b/content/renderer/media/audio_input_device.h
index 8ef72b7..6351182 100644
--- a/content/renderer/media/audio_input_device.h
+++ b/content/renderer/media/audio_input_device.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Low-latency audio capturing unit utilizing audio input stream provided
-// by browser process through IPC.
+// Low-latency audio capturing class utilizing audio input stream provided
+// by a server (browser) process by use of an IPC interface.
//
// Relationship of classes:
//
@@ -11,58 +11,51 @@
// ^ ^
// | |
// v IPC v
-// AudioInputRendererHost <---------> AudioInputMessageFilter
-// ^
+// AudioInputRendererHost <---------> media::AudioInputIPCDelegate
+// ^ (impl in AudioInputMessageFilter)
// |
// v
// AudioInputDeviceManager
//
// Transportation of audio samples from the browser to the render process
-// is done by using shared memory in combination with a sync socket pair
-// to generate a low latency transport. The AudioInputDevice user registers
-// an AudioInputDevice::CaptureCallback at construction and will be called
-// by the AudioInputDevice with recorded audio from the underlying audio layers.
+// is done by using shared memory in combination with a SyncSocket.
+// The AudioInputDevice user registers an AudioInputDevice::CaptureCallback by
+// calling Initialize(). The callback will be called with recorded audio from
+// the underlying audio layers.
// The session ID is used by the AudioInputRendererHost to start the device
// referenced by this ID.
//
// State sequences:
//
-// Task [IO thread] IPC [IO thread]
-//
// Sequence where session_id has not been set using SetDevice():
-// Start -> InitializeOnIOThread -----> AudioInputHostMsg_CreateStream ------->
-// <- OnLowLatencyCreated <- AudioInputMsg_NotifyLowLatencyStreamCreated <-
-// ---> StartOnIOThread ---------> AudioInputHostMsg_PlayStream -------->
+// ('<-' signifies callbacks, -> signifies calls made by AudioInputDevice)
+// Start -> InitializeOnIOThread -> CreateStream ->
+// <- OnStreamCreated <-
+// -> StartOnIOThread -> PlayStream ->
//
// Sequence where session_id has been set using SetDevice():
-// Start -> InitializeOnIOThread --> AudioInputHostMsg_StartDevice --->
-// <---- OnStarted <-------------- AudioInputMsg_NotifyDeviceStarted <----
-// -> OnDeviceReady ------------> AudioInputHostMsg_CreateStream ------->
-// <- OnLowLatencyCreated <- AudioInputMsg_NotifyLowLatencyStreamCreated <-
-// ---> StartOnIOThread ---------> AudioInputHostMsg_PlayStream -------->
+// Start -> InitializeOnIOThread -> StartDevice ->
+// <- OnDeviceReady <-
+// -> CreateStream ->
+// <- OnStreamCreated <-
+// -> StartOnIOThread -> PlayStream ->
//
// AudioInputDevice::Capture => low latency audio transport on audio thread =>
// |
-// Stop --> ShutDownOnIOThread ------> AudioInputHostMsg_CloseStream -> Close
+// Stop --> ShutDownOnIOThread ------> CloseStream -> Close
//
-// This class utilizes three threads during its lifetime, namely:
+// This class depends on two threads to function:
//
-// 1. Creating thread.
-// Must be the main render thread. Start and Stop should be called on
-// this thread.
-// 2. IO thread.
-// The thread within which this class receives all the IPC messages and
-// IPC communications can only happen in this thread.
-// 3. Audio transport thread.
-// Responsible for calling the CaptrureCallback and feed audio samples from
-// the audio layer in the browser process using sync sockets and shared
-// memory.
+// 1. An IO thread.
+// This thread is used to asynchronously process Start/Stop etc operations
+// that are available via the public interface. The public methods are
+// asynchronous and simply post a task to the IO thread to actually perform
+// the work.
+// 2. Audio transport thread.
+// Responsible for calling the CaptureCallback and feed audio samples from
+// the server side audio layer using a socket and shared memory.
//
// Implementation notes:
-//
-// - Start() is asynchronous/non-blocking.
-// - Stop() is synchronous/blocking.
-// - SetDevice() is asynchronous/non-blocking.
// - The user must call Stop() before deleting the class instance.
#ifndef CONTENT_RENDERER_MEDIA_AUDIO_INPUT_DEVICE_H_
@@ -87,7 +80,7 @@
// OnCaptureStopped etc.) and ensure that we can deliver these notifications
// to any clients using this class.
class CONTENT_EXPORT AudioInputDevice
- : public AudioInputMessageFilter::Delegate,
+ : NON_EXPORTED_BASE(public media::AudioInputIPCDelegate),
NON_EXPORTED_BASE(public ScopedLoopObserver),
public base::RefCountedThreadSafe<AudioInputDevice> {
public:
@@ -116,60 +109,52 @@ class CONTENT_EXPORT AudioInputDevice
virtual ~CaptureEventHandler() {}
};
- // Methods called on main render thread -------------------------------------
- AudioInputDevice(const media::AudioParameters& params,
- CaptureCallback* callback,
- CaptureEventHandler* event_handler);
+ AudioInputDevice(media::AudioInputIPC* ipc,
+ const scoped_refptr<base::MessageLoopProxy>& io_loop);
- // Specify the |session_id| to query which device to use. This method is
- // asynchronous/non-blocking.
+ // Initializes the AudioInputDevice. This method must be called before
+ // any other methods can be used.
+ void Initialize(const media::AudioParameters& params,
+ CaptureCallback* callback,
+ CaptureEventHandler* event_handler);
+
+ // Specify the |session_id| to query which device to use.
// Start() will use the second sequence if this method is called before.
void SetDevice(int session_id);
- // Starts audio capturing. This method is asynchronous/non-blocking.
+ // Starts audio capturing.
// TODO(henrika): add support for notification when recording has started.
void Start();
- // Stops audio capturing. This method is synchronous/blocking.
+ // Stops audio capturing.
// TODO(henrika): add support for notification when recording has stopped.
void Stop();
// Sets the capture volume scaling, with range [0.0, 1.0] inclusive.
// Returns |true| on success.
- bool SetVolume(double volume);
-
- // Gets the capture volume scaling, with range [0.0, 1.0] inclusive.
- // Returns |true| on success.
- bool GetVolume(double* volume);
-
- double sample_rate() const {
- return audio_parameters_.sample_rate();
- }
-
- int buffer_size() const {
- return audio_parameters_.frames_per_buffer();
- }
+ void SetVolume(double volume);
// Sets the Automatic Gain Control state to on or off.
// This method must be called before Start(). It will not have any effect
// if it is called while capturing has already started.
void SetAutomaticGainControl(bool enabled);
+ protected:
// Methods called on IO thread ----------------------------------------------
- // AudioInputMessageFilter::Delegate impl., called by AudioInputMessageFilter.
+ // media::AudioInputIPCDelegate implementation.
virtual void OnStreamCreated(base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) OVERRIDE;
+ int length) OVERRIDE;
virtual void OnVolume(double volume) OVERRIDE;
- virtual void OnStateChanged(AudioStreamState state) OVERRIDE;
+ virtual void OnStateChanged(
+ media::AudioInputIPCDelegate::State state) OVERRIDE;
virtual void OnDeviceReady(const std::string& device_id) OVERRIDE;
+ virtual void OnIPCClosed() OVERRIDE;
- protected:
+ friend class base::RefCountedThreadSafe<AudioInputDevice>;
virtual ~AudioInputDevice();
private:
- friend class base::RefCountedThreadSafe<AudioInputDevice>;
-
// Methods called on IO thread ----------------------------------------------
// The following methods are tasks posted on the IO thread that needs to
// be executed on that thread. They interact with AudioInputMessageFilter and
@@ -181,26 +166,19 @@ class CONTENT_EXPORT AudioInputDevice
void SetVolumeOnIOThread(double volume);
void SetAutomaticGainControlOnIOThread(bool enabled);
- void Send(IPC::Message* message);
-
// MessageLoop::DestructionObserver implementation for the IO loop.
// If the IO loop dies before we do, we shut down the audio thread from here.
virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
- // Format
media::AudioParameters audio_parameters_;
CaptureCallback* callback_;
CaptureEventHandler* event_handler_;
- // The current volume scaling [0.0, 1.0] of the audio stream.
- double volume_;
-
- // Cached audio input message filter (lives on the main render thread).
- scoped_refptr<AudioInputMessageFilter> filter_;
+ media::AudioInputIPC* ipc_;
// Our stream ID on the message filter. Only modified on the IO thread.
- int32 stream_id_;
+ int stream_id_;
// The media session ID used to identify which input device to be started.
// Only modified on the IO thread.
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc
index 30e4b01..b523ac6 100644
--- a/content/renderer/media/audio_input_message_filter.cc
+++ b/content/renderer/media/audio_input_message_filter.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// 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.
@@ -11,13 +11,24 @@
#include "content/common/media/audio_messages.h"
#include "ipc/ipc_logging.h"
+AudioInputMessageFilter* AudioInputMessageFilter::filter_ = NULL;
+
AudioInputMessageFilter::AudioInputMessageFilter()
: channel_(NULL) {
- VLOG(1) << "AudioInputMessageFilter()";
+ DVLOG(1) << "AudioInputMessageFilter()";
+ DCHECK(!filter_);
+ filter_ = this;
}
AudioInputMessageFilter::~AudioInputMessageFilter() {
- VLOG(1) << "AudioInputMessageFilter::~AudioInputMessageFilter()";
+ DVLOG(1) << "AudioInputMessageFilter::~AudioInputMessageFilter()";
+ DCHECK_EQ(filter_, this);
+ filter_ = NULL;
+}
+
+// static.
+AudioInputMessageFilter* AudioInputMessageFilter::Get() {
+ return filter_;
}
bool AudioInputMessageFilter::Send(IPC::Message* message) {
@@ -55,7 +66,7 @@ bool AudioInputMessageFilter::OnMessageReceived(const IPC::Message& message) {
}
void AudioInputMessageFilter::OnFilterAdded(IPC::Channel* channel) {
- VLOG(1) << "AudioInputMessageFilter::OnFilterAdded()";
+ DVLOG(1) << "AudioInputMessageFilter::OnFilterAdded()";
// Captures the channel for IPC.
channel_ = channel;
}
@@ -66,6 +77,14 @@ void AudioInputMessageFilter::OnFilterRemoved() {
void AudioInputMessageFilter::OnChannelClosing() {
channel_ = NULL;
+ LOG_IF(WARNING, !delegates_.IsEmpty())
+ << "Not all audio devices have been closed.";
+
+ IDMap<media::AudioInputIPCDelegate>::iterator it(&delegates_);
+ while (!it.IsAtEnd()) {
+ it.GetCurrentValue()->OnIPCClosed();
+ it.Advance();
+ }
}
void AudioInputMessageFilter::OnStreamCreated(
@@ -80,7 +99,7 @@ void AudioInputMessageFilter::OnStreamCreated(
#if !defined(OS_WIN)
base::SyncSocket::Handle socket_handle = socket_descriptor.fd;
#endif
- Delegate* delegate = delegates_.Lookup(stream_id);
+ media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
if (!delegate) {
DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
" audio capturer (stream_id=" << stream_id << ").";
@@ -93,7 +112,7 @@ void AudioInputMessageFilter::OnStreamCreated(
}
void AudioInputMessageFilter::OnStreamVolume(int stream_id, double volume) {
- Delegate* delegate = delegates_.Lookup(stream_id);
+ media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
if (!delegate) {
DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
" audio capturer.";
@@ -103,8 +122,8 @@ void AudioInputMessageFilter::OnStreamVolume(int stream_id, double volume) {
}
void AudioInputMessageFilter::OnStreamStateChanged(
- int stream_id, AudioStreamState state) {
- Delegate* delegate = delegates_.Lookup(stream_id);
+ int stream_id, media::AudioInputIPCDelegate::State state) {
+ media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
if (!delegate) {
DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
" audio renderer.";
@@ -115,20 +134,43 @@ void AudioInputMessageFilter::OnStreamStateChanged(
void AudioInputMessageFilter::OnDeviceStarted(int stream_id,
const std::string& device_id) {
- Delegate* delegate = delegates_.Lookup(stream_id);
+ media::AudioInputIPCDelegate* delegate = delegates_.Lookup(stream_id);
if (!delegate) {
- DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
- " audio renderer.";
+ NOTREACHED();
return;
}
delegate->OnDeviceReady(device_id);
}
-int32 AudioInputMessageFilter::AddDelegate(Delegate* delegate) {
+int AudioInputMessageFilter::AddDelegate(
+ media::AudioInputIPCDelegate* delegate) {
return delegates_.Add(delegate);
}
-void AudioInputMessageFilter::RemoveDelegate(int32 id) {
- VLOG(1) << "AudioInputMessageFilter::RemoveDelegate(id=" << id << ")";
+void AudioInputMessageFilter::RemoveDelegate(int id) {
+ DVLOG(1) << "AudioInputMessageFilter::RemoveDelegate(id=" << id << ")";
delegates_.Remove(id);
}
+
+void AudioInputMessageFilter::CreateStream(int stream_id,
+ const media::AudioParameters& params, const std::string& device_id,
+ bool automatic_gain_control) {
+ Send(new AudioInputHostMsg_CreateStream(
+ stream_id, params, device_id, automatic_gain_control));
+}
+
+void AudioInputMessageFilter::StartDevice(int stream_id, int session_id) {
+ Send(new AudioInputHostMsg_StartDevice(stream_id, session_id));
+}
+
+void AudioInputMessageFilter::RecordStream(int stream_id) {
+ Send(new AudioInputHostMsg_RecordStream(stream_id));
+}
+
+void AudioInputMessageFilter::CloseStream(int stream_id) {
+ Send(new AudioInputHostMsg_CloseStream(stream_id));
+}
+
+void AudioInputMessageFilter::SetVolume(int stream_id, double volume) {
+ Send(new AudioInputHostMsg_SetVolume(stream_id, volume));
+}
diff --git a/content/renderer/media/audio_input_message_filter.h b/content/renderer/media/audio_input_message_filter.h
index ba5e9de..ee99900 100644
--- a/content/renderer/media/audio_input_message_filter.h
+++ b/content/renderer/media/audio_input_message_filter.h
@@ -14,50 +14,36 @@
#include "base/shared_memory.h"
#include "base/sync_socket.h"
#include "content/common/content_export.h"
-#include "content/common/media/audio_stream_state.h"
#include "ipc/ipc_channel_proxy.h"
#include "media/audio/audio_buffers_state.h"
+#include "media/audio/audio_input_ipc.h"
class CONTENT_EXPORT AudioInputMessageFilter
- : public IPC::ChannelProxy::MessageFilter {
+ : public IPC::ChannelProxy::MessageFilter,
+ public NON_EXPORTED_BASE(media::AudioInputIPC) {
public:
- class CONTENT_EXPORT Delegate {
- public:
- // Called when an audio input stream has been created in the browser
- // process.
- virtual void OnStreamCreated(base::SharedMemoryHandle handle,
- base::SyncSocket::Handle socket_handle,
- uint32 length) = 0;
-
- // Called when notification of input stream volume is received from the
- // browser process.
- virtual void OnVolume(double volume) = 0;
-
- // Called when state of an input stream has changed in the browser process.
- virtual void OnStateChanged(AudioStreamState state) = 0;
-
- // Called when the device referenced by the index has been started in
- // the browswer process.
- virtual void OnDeviceReady(const std::string& device_id) = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
AudioInputMessageFilter();
- // Add a delegate to the map and return id of the entry.
- int32 AddDelegate(Delegate* delegate);
-
- // Remove a delegate referenced by |id| from the map.
- void RemoveDelegate(int32 id);
+ // Getter for the one AudioInputMessageFilter object.
+ static AudioInputMessageFilter* Get();
- // Sends an IPC message using |channel_|.
- bool Send(IPC::Message* message);
+ // Implementation of AudioInputIPC.
+ virtual int AddDelegate(
+ media::AudioInputIPCDelegate* delegate) OVERRIDE;
+ virtual void RemoveDelegate(int id) OVERRIDE;
+ virtual void CreateStream(int stream_id, const media::AudioParameters& params,
+ const std::string& device_id, bool automatic_gain_control) OVERRIDE;
+ virtual void StartDevice(int stream_id, int session_id) OVERRIDE;
+ virtual void RecordStream(int stream_id) OVERRIDE;
+ virtual void CloseStream(int stream_id) OVERRIDE;
+ virtual void SetVolume(int stream_id, double volume) OVERRIDE;
private:
virtual ~AudioInputMessageFilter();
+ // Sends an IPC message using |channel_|.
+ bool Send(IPC::Message* message);
+
// IPC::ChannelProxy::MessageFilter override. Called on IO thread.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
@@ -78,16 +64,20 @@ class CONTENT_EXPORT AudioInputMessageFilter
// Received when internal state of browser process' audio input stream has
// changed.
- void OnStreamStateChanged(int stream_id, AudioStreamState state);
+ void OnStreamStateChanged(int stream_id,
+ media::AudioInputIPCDelegate::State state);
// Notification of the opened device of an audio session.
void OnDeviceStarted(int stream_id, const std::string& device_id);
// A map of stream ids to delegates.
- IDMap<Delegate> delegates_;
+ IDMap<media::AudioInputIPCDelegate> delegates_;
IPC::Channel* channel_;
+ // The singleton instance for this filter.
+ static AudioInputMessageFilter* filter_;
+
DISALLOW_COPY_AND_ASSIGN(AudioInputMessageFilter);
};
diff --git a/content/renderer/media/audio_message_filter.cc b/content/renderer/media/audio_message_filter.cc
index 8168992..ef3bd80 100644
--- a/content/renderer/media/audio_message_filter.cc
+++ b/content/renderer/media/audio_message_filter.cc
@@ -21,19 +21,44 @@ AudioMessageFilter* AudioMessageFilter::Get() {
AudioMessageFilter::AudioMessageFilter()
: channel_(NULL) {
- VLOG(1) << "AudioMessageFilter::AudioMessageFilter()";
+ DVLOG(1) << "AudioMessageFilter::AudioMessageFilter()";
DCHECK(!filter_);
filter_ = this;
}
-int32 AudioMessageFilter::AddDelegate(Delegate* delegate) {
+int AudioMessageFilter::AddDelegate(media::AudioOutputIPCDelegate* delegate) {
return delegates_.Add(delegate);
}
-void AudioMessageFilter::RemoveDelegate(int32 id) {
+void AudioMessageFilter::RemoveDelegate(int id) {
delegates_.Remove(id);
}
+void AudioMessageFilter::CreateStream(int stream_id,
+ const media::AudioParameters& params) {
+ Send(new AudioHostMsg_CreateStream(stream_id, params));
+}
+
+void AudioMessageFilter::PlayStream(int stream_id) {
+ Send(new AudioHostMsg_PlayStream(stream_id));
+}
+
+void AudioMessageFilter::PauseStream(int stream_id) {
+ Send(new AudioHostMsg_PauseStream(stream_id));
+}
+
+void AudioMessageFilter::FlushStream(int stream_id) {
+ Send(new AudioHostMsg_FlushStream(stream_id));
+}
+
+void AudioMessageFilter::CloseStream(int stream_id) {
+ Send(new AudioHostMsg_CloseStream(stream_id));
+}
+
+void AudioMessageFilter::SetVolume(int stream_id, double volume) {
+ Send(new AudioHostMsg_SetVolume(stream_id, volume));
+}
+
bool AudioMessageFilter::Send(IPC::Message* message) {
if (!channel_) {
delete message;
@@ -64,8 +89,7 @@ bool AudioMessageFilter::OnMessageReceived(const IPC::Message& message) {
}
void AudioMessageFilter::OnFilterAdded(IPC::Channel* channel) {
- VLOG(1) << "AudioMessageFilter::OnFilterAdded()";
- // Captures the channel for IPC.
+ DVLOG(1) << "AudioMessageFilter::OnFilterAdded()";
channel_ = channel;
}
@@ -75,10 +99,18 @@ void AudioMessageFilter::OnFilterRemoved() {
void AudioMessageFilter::OnChannelClosing() {
channel_ = NULL;
+ LOG_IF(WARNING, !delegates_.IsEmpty())
+ << "Not all audio devices have been closed.";
+
+ IDMap<media::AudioOutputIPCDelegate>::iterator it(&delegates_);
+ while (!it.IsAtEnd()) {
+ it.GetCurrentValue()->OnIPCClosed();
+ it.Advance();
+ }
}
AudioMessageFilter::~AudioMessageFilter() {
- VLOG(1) << "AudioMessageFilter::~AudioMessageFilter()";
+ DVLOG(1) << "AudioMessageFilter::~AudioMessageFilter()";
DCHECK(filter_);
filter_ = NULL;
}
@@ -95,10 +127,10 @@ void AudioMessageFilter::OnStreamCreated(
#if !defined(OS_WIN)
base::SyncSocket::Handle socket_handle = socket_descriptor.fd;
#endif
- Delegate* delegate = delegates_.Lookup(stream_id);
+ media::AudioOutputIPCDelegate* delegate = delegates_.Lookup(stream_id);
if (!delegate) {
DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
- " audio renderer. (stream_id=" << stream_id << ").";
+ " audio renderer. (stream_id=" << stream_id << ").";
base::SharedMemory::CloseHandle(handle);
base::SyncSocket socket(socket_handle);
return;
@@ -107,11 +139,10 @@ void AudioMessageFilter::OnStreamCreated(
}
void AudioMessageFilter::OnStreamStateChanged(
- int stream_id, AudioStreamState state) {
- Delegate* delegate = delegates_.Lookup(stream_id);
+ int stream_id, media::AudioOutputIPCDelegate::State state) {
+ media::AudioOutputIPCDelegate* delegate = delegates_.Lookup(stream_id);
if (!delegate) {
- DLOG(WARNING) << "Got audio stream event for a non-existent or removed"
- " audio renderer.";
+ DLOG(WARNING) << "No delegate found for state change. " << state;
return;
}
delegate->OnStateChanged(state);
diff --git a/content/renderer/media/audio_message_filter.h b/content/renderer/media/audio_message_filter.h
index efc80a7..c50dca4 100644
--- a/content/renderer/media/audio_message_filter.h
+++ b/content/renderer/media/audio_message_filter.h
@@ -14,42 +14,30 @@
#include "base/id_map.h"
#include "base/shared_memory.h"
#include "base/sync_socket.h"
-#include "content/common/media/audio_stream_state.h"
#include "content/common/content_export.h"
#include "ipc/ipc_channel_proxy.h"
#include "media/audio/audio_buffers_state.h"
+#include "media/audio/audio_output_ipc.h"
class CONTENT_EXPORT AudioMessageFilter
- : public IPC::ChannelProxy::MessageFilter {
+ : public IPC::ChannelProxy::MessageFilter,
+ public NON_EXPORTED_BASE(media::AudioOutputIPC) {
public:
- class CONTENT_EXPORT Delegate {
- public:
- // Called when state of an audio stream has changed in the browser process.
- virtual void OnStateChanged(AudioStreamState state) = 0;
-
- // Called when an audio stream has been created in the browser process.
- virtual void OnStreamCreated(base::SharedMemoryHandle handle,
- base::SyncSocket::Handle socket_handle,
- uint32 length) = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
AudioMessageFilter();
// Getter for the one AudioMessageFilter object.
static AudioMessageFilter* Get();
- // Add a delegate to the map and return id of the entry.
- int32 AddDelegate(Delegate* delegate);
-
- // Remove a delegate referenced by |id| from the map.
- void RemoveDelegate(int32 id);
-
- // Sends an IPC message using |channel_|.
- // This method is virtual so that it can be overridden in tests.
- virtual bool Send(IPC::Message* message);
+ // media::AudioOutputIPCDelegate implementation.
+ virtual int AddDelegate(media::AudioOutputIPCDelegate* delegate) OVERRIDE;
+ virtual void RemoveDelegate(int id) OVERRIDE;
+ virtual void CreateStream(int stream_id,
+ const media::AudioParameters& params) OVERRIDE;
+ virtual void PlayStream(int stream_id) OVERRIDE;
+ virtual void PauseStream(int stream_id) OVERRIDE;
+ virtual void FlushStream(int stream_id) OVERRIDE;
+ virtual void CloseStream(int stream_id) OVERRIDE;
+ virtual void SetVolume(int stream_id, double volume) OVERRIDE;
// IPC::ChannelProxy::MessageFilter override. Called on IO thread.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
@@ -64,6 +52,9 @@ class CONTENT_EXPORT AudioMessageFilter
FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Basic);
FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Delegates);
+ // Sends an IPC message using |channel_|.
+ bool Send(IPC::Message* message);
+
// Received when browser process has created an audio output stream.
void OnStreamCreated(int stream_id, base::SharedMemoryHandle handle,
#if defined(OS_WIN)
@@ -73,16 +64,16 @@ class CONTENT_EXPORT AudioMessageFilter
#endif
uint32 length);
-
// Received when internal state of browser process' audio output device has
// changed.
- void OnStreamStateChanged(int stream_id, AudioStreamState state);
+ void OnStreamStateChanged(int stream_id,
+ media::AudioOutputIPCDelegate::State state);
// The singleton instance for this filter.
static AudioMessageFilter* filter_;
// A map of stream ids to delegates.
- IDMap<Delegate> delegates_;
+ IDMap<media::AudioOutputIPCDelegate> delegates_;
IPC::Channel* channel_;
diff --git a/content/renderer/media/audio_message_filter_unittest.cc b/content/renderer/media/audio_message_filter_unittest.cc
index 2031213..26a6247 100644
--- a/content/renderer/media/audio_message_filter_unittest.cc
+++ b/content/renderer/media/audio_message_filter_unittest.cc
@@ -5,29 +5,33 @@
#include "base/message_loop.h"
#include "content/common/media/audio_messages.h"
#include "content/renderer/media/audio_message_filter.h"
+#include "media/audio/audio_output_ipc.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
-class MockAudioDelegate : public AudioMessageFilter::Delegate {
+class MockAudioDelegate : public media::AudioOutputIPCDelegate {
public:
MockAudioDelegate() {
Reset();
}
- virtual void OnStateChanged(AudioStreamState state) {
+ virtual void OnStateChanged(
+ media::AudioOutputIPCDelegate::State state) OVERRIDE {
state_changed_received_ = true;
state_ = state;
}
virtual void OnStreamCreated(base::SharedMemoryHandle handle,
base::SyncSocket::Handle,
- uint32 length) {
+ int length) OVERRIDE {
created_received_ = true;
handle_ = handle;
length_ = length;
}
+ virtual void OnIPCClosed() OVERRIDE {}
+
virtual void OnVolume(double volume) {
volume_received_ = true;
volume_ = volume;
@@ -35,7 +39,7 @@ class MockAudioDelegate : public AudioMessageFilter::Delegate {
void Reset() {
state_changed_received_ = false;
- state_ = kAudioStreamError;
+ state_ = media::AudioOutputIPCDelegate::kError;
created_received_ = false;
handle_ = base::SharedMemory::NULLHandle();
@@ -46,7 +50,7 @@ class MockAudioDelegate : public AudioMessageFilter::Delegate {
}
bool state_changed_received() { return state_changed_received_; }
- AudioStreamState state() { return state_; }
+ media::AudioOutputIPCDelegate::State state() { return state_; }
bool created_received() { return created_received_; }
base::SharedMemoryHandle handle() { return handle_; }
@@ -57,11 +61,11 @@ class MockAudioDelegate : public AudioMessageFilter::Delegate {
private:
bool state_changed_received_;
- AudioStreamState state_;
+ media::AudioOutputIPCDelegate::State state_;
bool created_received_;
base::SharedMemoryHandle handle_;
- uint32 length_;
+ int length_;
bool volume_received_;
double volume_;
@@ -99,9 +103,10 @@ TEST(AudioMessageFilterTest, Basic) {
// AudioMsg_NotifyStreamStateChanged
EXPECT_FALSE(delegate.state_changed_received());
filter->OnMessageReceived(
- AudioMsg_NotifyStreamStateChanged(stream_id, kAudioStreamPlaying));
+ AudioMsg_NotifyStreamStateChanged(
+ stream_id, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_TRUE(delegate.state_changed_received());
- EXPECT_TRUE(kAudioStreamPlaying == delegate.state());
+ EXPECT_EQ(media::AudioOutputIPCDelegate::kPlaying, delegate.state());
delegate.Reset();
message_loop.RunAllPending();
@@ -122,7 +127,8 @@ TEST(AudioMessageFilterTest, Delegates) {
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
filter->OnMessageReceived(
- AudioMsg_NotifyStreamStateChanged(stream_id1, kAudioStreamPlaying));
+ AudioMsg_NotifyStreamStateChanged(
+ stream_id1, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_TRUE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
delegate1.Reset();
@@ -130,23 +136,11 @@ TEST(AudioMessageFilterTest, Delegates) {
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
filter->OnMessageReceived(
- AudioMsg_NotifyStreamStateChanged(stream_id2, kAudioStreamPlaying));
+ AudioMsg_NotifyStreamStateChanged(
+ stream_id2, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_TRUE(delegate2.state_changed_received());
delegate2.Reset();
- // Remove the delegates. Make sure they won't get called.
- filter->RemoveDelegate(stream_id1);
- EXPECT_FALSE(delegate1.state_changed_received());
- filter->OnMessageReceived(
- AudioMsg_NotifyStreamStateChanged(stream_id1, kAudioStreamPlaying));
- EXPECT_FALSE(delegate1.state_changed_received());
-
- filter->RemoveDelegate(stream_id2);
- EXPECT_FALSE(delegate2.state_changed_received());
- filter->OnMessageReceived(
- AudioMsg_NotifyStreamStateChanged(stream_id2, kAudioStreamPlaying));
- EXPECT_FALSE(delegate2.state_changed_received());
-
message_loop.RunAllPending();
}
diff --git a/content/renderer/media/audio_renderer_mixer_manager.cc b/content/renderer/media/audio_renderer_mixer_manager.cc
index 03e638e..411ae8b4 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -48,7 +48,7 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
hardware_sample_rate_, 16, hardware_buffer_size_);
media::AudioRendererMixer* mixer = new media::AudioRendererMixer(
- params, output_params, AudioDeviceFactory::Create());
+ params, output_params, AudioDeviceFactory::NewOutputDevice());
AudioRendererMixerReference mixer_reference = { mixer, 1 };
mixers_[params] = mixer_reference;
diff --git a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
index 92a44d4..5eeae9b 100644
--- a/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager_unittest.cc
@@ -27,13 +27,18 @@ class MockAudioRenderSinkFactory : public AudioDeviceFactory {
virtual ~MockAudioRenderSinkFactory() {}
protected:
- virtual media::MockAudioRendererSink* CreateAudioDevice() {
+ virtual media::MockAudioRendererSink* CreateOutputDevice() OVERRIDE {
media::MockAudioRendererSink* sink = new media::MockAudioRendererSink();
EXPECT_CALL(*sink, Start());
EXPECT_CALL(*sink, Stop());
return sink;
}
+ virtual AudioInputDevice* CreateInputDevice() OVERRIDE {
+ ADD_FAILURE();
+ return NULL;
+ }
+
DISALLOW_COPY_AND_ASSIGN(MockAudioRenderSinkFactory);
};
diff --git a/content/renderer/media/render_audiosourceprovider.cc b/content/renderer/media/render_audiosourceprovider.cc
index da1e341..f879a47 100644
--- a/content/renderer/media/render_audiosourceprovider.cc
+++ b/content/renderer/media/render_audiosourceprovider.cc
@@ -35,7 +35,7 @@ RenderAudioSourceProvider::RenderAudioSourceProvider()
default_sink_ = RenderThreadImpl::current()->
GetAudioRendererMixerManager()->CreateInput();
} else {
- default_sink_ = AudioDeviceFactory::Create();
+ default_sink_ = AudioDeviceFactory::NewOutputDevice();
}
}
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc
index f67c282..0ac56e8 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -16,7 +16,7 @@ RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl(
WebAudioDevice::RenderCallback* callback)
: is_running_(false),
client_callback_(callback) {
- audio_device_ = AudioDeviceFactory::Create();
+ audio_device_ = AudioDeviceFactory::NewOutputDevice();
audio_device_->Initialize(params, this);
}
diff --git a/content/renderer/media/webrtc_audio_device_impl.cc b/content/renderer/media/webrtc_audio_device_impl.cc
index d1bbb1c..d2657d6 100644
--- a/content/renderer/media/webrtc_audio_device_impl.cc
+++ b/content/renderer/media/webrtc_audio_device_impl.cc
@@ -147,7 +147,7 @@ WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
// input side as well.
DCHECK(RenderThreadImpl::current()) <<
"WebRtcAudioDeviceImpl must be constructed on the render thread";
- audio_output_device_ = AudioDeviceFactory::Create();
+ audio_output_device_ = AudioDeviceFactory::NewOutputDevice();
DCHECK(audio_output_device_);
}
@@ -398,6 +398,8 @@ int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback(
int32_t WebRtcAudioDeviceImpl::Init() {
DVLOG(1) << "Init()";
+ // TODO(henrika): After switching to using the AudioDeviceFactory for
+ // instantiating the input device, maybe this isn't a requirement anymore?
if (!render_loop_->BelongsToCurrentThread()) {
int32_t error = 0;
base::WaitableEvent event(false, false);
@@ -578,8 +580,8 @@ int32_t WebRtcAudioDeviceImpl::Init() {
16, in_buffer_size);
// Create and configure the audio capturing client.
- audio_input_device_ = new AudioInputDevice(
- input_audio_parameters_, this, this);
+ audio_input_device_ = AudioDeviceFactory::NewInputDevice();
+ audio_input_device_->Initialize(input_audio_parameters_, this, this);
UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioOutputChannelLayout",
out_channel_layout, CHANNEL_LAYOUT_MAX);
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.cc b/content/renderer/pepper/pepper_platform_audio_input_impl.cc
index effcf2a..61b8804 100644
--- a/content/renderer/pepper/pepper_platform_audio_input_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input_impl.cc
@@ -24,7 +24,7 @@ PepperPlatformAudioInputImpl* PepperPlatformAudioInputImpl::Create(
int frames_per_buffer,
webkit::ppapi::PluginDelegate::PlatformAudioInputClient* client) {
scoped_refptr<PepperPlatformAudioInputImpl> audio_input(
- new PepperPlatformAudioInputImpl);
+ new PepperPlatformAudioInputImpl());
if (audio_input->Initialize(plugin_delegate, device_id, sample_rate,
frames_per_buffer, client)) {
// Balanced by Release invoked in
@@ -64,7 +64,7 @@ void PepperPlatformAudioInputImpl::ShutDown() {
void PepperPlatformAudioInputImpl::OnStreamCreated(
base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) {
+ int length) {
#if defined(OS_WIN)
DCHECK(handle);
DCHECK(socket_handle);
@@ -97,7 +97,9 @@ void PepperPlatformAudioInputImpl::OnStreamCreated(
void PepperPlatformAudioInputImpl::OnVolume(double volume) {}
-void PepperPlatformAudioInputImpl::OnStateChanged(AudioStreamState state) {}
+void PepperPlatformAudioInputImpl::OnStateChanged(
+ media::AudioInputIPCDelegate::State state) {
+}
void PepperPlatformAudioInputImpl::OnDeviceReady(const std::string& device_id) {
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
@@ -113,11 +115,14 @@ void PepperPlatformAudioInputImpl::OnDeviceReady(const std::string& device_id) {
this));
} else {
// We will be notified by OnStreamCreated().
- filter_->Send(new AudioInputHostMsg_CreateStream(stream_id_, params_,
- device_id, false));
+ ipc_->CreateStream(stream_id_, params_, device_id, false);
}
}
+void PepperPlatformAudioInputImpl::OnIPCClosed() {
+ ipc_ = NULL;
+}
+
PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() {
// Make sure we have been shut down. Warning: this may happen on the I/O
// thread!
@@ -135,7 +140,7 @@ PepperPlatformAudioInputImpl::PepperPlatformAudioInputImpl()
stream_id_(0),
main_message_loop_proxy_(base::MessageLoopProxy::current()),
shutdown_called_(false) {
- filter_ = RenderThreadImpl::current()->audio_input_message_filter();
+ ipc_ = RenderThreadImpl::current()->audio_input_message_filter();
}
bool PepperPlatformAudioInputImpl::Initialize(
@@ -180,17 +185,16 @@ void PepperPlatformAudioInputImpl::InitializeOnIOThread(int session_id) {
// Make sure we don't call init more than once.
DCHECK_EQ(0, stream_id_);
- stream_id_ = filter_->AddDelegate(this);
+ stream_id_ = ipc_->AddDelegate(this);
DCHECK_NE(0, stream_id_);
if (!session_id) {
// We will be notified by OnStreamCreated().
- filter_->Send(new AudioInputHostMsg_CreateStream(
- stream_id_, params_,
- media::AudioManagerBase::kDefaultDeviceId, false));
+ ipc_->CreateStream(stream_id_, params_,
+ media::AudioManagerBase::kDefaultDeviceId, false);
} else {
// We will be notified by OnDeviceReady().
- filter_->Send(new AudioInputHostMsg_StartDevice(stream_id_, session_id));
+ ipc_->StartDevice(stream_id_, session_id);
}
}
@@ -199,7 +203,7 @@ void PepperPlatformAudioInputImpl::StartCaptureOnIOThread() {
BelongsToCurrentThread());
if (stream_id_)
- filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_));
+ ipc_->RecordStream(stream_id_);
}
void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() {
@@ -208,7 +212,7 @@ void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() {
// TODO(yzshen): We cannot re-start capturing if the stream is closed.
if (stream_id_)
- filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
+ ipc_->CloseStream(stream_id_);
}
void PepperPlatformAudioInputImpl::ShutDownOnIOThread() {
@@ -221,8 +225,8 @@ void PepperPlatformAudioInputImpl::ShutDownOnIOThread() {
shutdown_called_ = true;
if (stream_id_) {
- filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
- filter_->RemoveDelegate(stream_id_);
+ ipc_->CloseStream(stream_id_);
+ ipc_->RemoveDelegate(stream_id_);
stream_id_ = 0;
}
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.h b/content/renderer/pepper/pepper_platform_audio_input_impl.h
index d83a12e..864afa1 100644
--- a/content/renderer/pepper/pepper_platform_audio_input_impl.h
+++ b/content/renderer/pepper/pepper_platform_audio_input_impl.h
@@ -28,12 +28,12 @@ class PepperPluginDelegateImpl;
// except the destructor, must be called on the main thread. The notifications
// to the users of this class (via the PlatformAudioInputClient interface) are
// also sent on the main thread. Internally, this class sends audio input IPC
-// messages and receives AudioInputMessageFilter::Delegate notifications on the
+// messages and receives media::AudioInputIPCDelegate notifications on the
// I/O thread.
class PepperPlatformAudioInputImpl
: public webkit::ppapi::PluginDelegate::PlatformAudioInput,
- public AudioInputMessageFilter::Delegate,
+ public media::AudioInputIPCDelegate,
public base::RefCountedThreadSafe<PepperPlatformAudioInputImpl> {
public:
// Factory function, returns NULL on failure. StreamCreated() will be called
@@ -50,13 +50,15 @@ class PepperPlatformAudioInputImpl
virtual void StopCapture() OVERRIDE;
virtual void ShutDown() OVERRIDE;
- // AudioInputMessageFilter::Delegate.
+ // media::AudioInputIPCDelegate.
virtual void OnStreamCreated(base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) OVERRIDE;
+ int length) OVERRIDE;
virtual void OnVolume(double volume) OVERRIDE;
- virtual void OnStateChanged(AudioStreamState state) OVERRIDE;
+ virtual void OnStateChanged(
+ media::AudioInputIPCDelegate::State state) OVERRIDE;
virtual void OnDeviceReady(const std::string&) OVERRIDE;
+ virtual void OnIPCClosed() OVERRIDE;
protected:
virtual ~PepperPlatformAudioInputImpl();
@@ -89,9 +91,9 @@ class PepperPlatformAudioInputImpl
// ACCESSED ON THE MAIN THREAD.
webkit::ppapi::PluginDelegate::PlatformAudioInputClient* client_;
- // MessageFilter used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
+ // Used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
// I/O thread except to send messages and get the message loop.
- scoped_refptr<AudioInputMessageFilter> filter_;
+ media::AudioInputIPC* ipc_;
// Our ID on the MessageFilter. THIS MUST ONLY BE ACCESSED ON THE I/O THREAD
// or else you could race with the initialize function which sets it.
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.cc b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
index f964b07..5f1f57d 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
@@ -11,6 +11,7 @@
#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"
namespace content {
@@ -21,7 +22,7 @@ PepperPlatformAudioOutputImpl* PepperPlatformAudioOutputImpl::Create(
int frames_per_buffer,
webkit::ppapi::PluginDelegate::PlatformAudioOutputClient* client) {
scoped_refptr<PepperPlatformAudioOutputImpl> audio_output(
- new PepperPlatformAudioOutputImpl);
+ new PepperPlatformAudioOutputImpl());
if (audio_output->Initialize(sample_rate, frames_per_buffer, client)) {
// Balanced by Release invoked in
// PepperPlatformAudioOutputImpl::ShutDownOnIOThread().
@@ -31,7 +32,7 @@ PepperPlatformAudioOutputImpl* PepperPlatformAudioOutputImpl::Create(
}
bool PepperPlatformAudioOutputImpl::StartPlayback() {
- if (filter_) {
+ if (ipc_) {
ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread,
@@ -42,7 +43,7 @@ bool PepperPlatformAudioOutputImpl::StartPlayback() {
}
bool PepperPlatformAudioOutputImpl::StopPlayback() {
- if (filter_) {
+ if (ipc_) {
ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread,
@@ -61,12 +62,14 @@ void PepperPlatformAudioOutputImpl::ShutDown() {
base::Bind(&PepperPlatformAudioOutputImpl::ShutDownOnIOThread, this));
}
-void PepperPlatformAudioOutputImpl::OnStateChanged(AudioStreamState state) {}
+void PepperPlatformAudioOutputImpl::OnStateChanged(
+ media::AudioOutputIPCDelegate::State state) {
+}
void PepperPlatformAudioOutputImpl::OnStreamCreated(
base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) {
+ int length) {
#if defined(OS_WIN)
DCHECK(handle);
DCHECK(socket_handle);
@@ -88,6 +91,10 @@ void PepperPlatformAudioOutputImpl::OnStreamCreated(
}
}
+void PepperPlatformAudioOutputImpl::OnIPCClosed() {
+ ipc_ = NULL;
+}
+
PepperPlatformAudioOutputImpl::~PepperPlatformAudioOutputImpl() {
// Make sure we have been shut down. Warning: this will usually happen on
// the I/O thread!
@@ -99,7 +106,7 @@ PepperPlatformAudioOutputImpl::PepperPlatformAudioOutputImpl()
: client_(NULL),
stream_id_(0),
main_message_loop_proxy_(base::MessageLoopProxy::current()) {
- filter_ = RenderThreadImpl::current()->audio_message_filter();
+ ipc_ = RenderThreadImpl::current()->audio_message_filter();
}
bool PepperPlatformAudioOutputImpl::Initialize(
@@ -136,18 +143,18 @@ bool PepperPlatformAudioOutputImpl::Initialize(
void PepperPlatformAudioOutputImpl::InitializeOnIOThread(
const media::AudioParameters& params) {
- stream_id_ = filter_->AddDelegate(this);
- filter_->Send(new AudioHostMsg_CreateStream(stream_id_, params));
+ stream_id_ = ipc_->AddDelegate(this);
+ ipc_->CreateStream(stream_id_, params);
}
void PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread() {
if (stream_id_)
- filter_->Send(new AudioHostMsg_PlayStream(stream_id_));
+ ipc_->PlayStream(stream_id_);
}
void PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread() {
if (stream_id_)
- filter_->Send(new AudioHostMsg_PauseStream(stream_id_));
+ ipc_->PauseStream(stream_id_);
}
void PepperPlatformAudioOutputImpl::ShutDownOnIOThread() {
@@ -155,8 +162,8 @@ void PepperPlatformAudioOutputImpl::ShutDownOnIOThread() {
if (!stream_id_)
return;
- filter_->Send(new AudioHostMsg_CloseStream(stream_id_));
- filter_->RemoveDelegate(stream_id_);
+ ipc_->CloseStream(stream_id_);
+ ipc_->RemoveDelegate(stream_id_);
stream_id_ = 0;
Release(); // Release for the delegate, balances out the reference taken in
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.h b/content/renderer/pepper/pepper_platform_audio_output_impl.h
index 3b426ad..414a3cd 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.h
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.h
@@ -7,7 +7,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
-#include "content/renderer/media/audio_message_filter.h"
+#include "media/audio/audio_output_ipc.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
namespace media{
@@ -22,7 +22,7 @@ namespace content {
class PepperPlatformAudioOutputImpl
: public webkit::ppapi::PluginDelegate::PlatformAudioOutput,
- public AudioMessageFilter::Delegate,
+ public media::AudioOutputIPCDelegate,
public base::RefCountedThreadSafe<PepperPlatformAudioOutputImpl> {
public:
// Factory function, returns NULL on failure. StreamCreated() will be called
@@ -37,11 +37,13 @@ class PepperPlatformAudioOutputImpl
virtual bool StopPlayback() OVERRIDE;
virtual void ShutDown() OVERRIDE;
- // AudioMessageFilter::Delegate.
- virtual void OnStateChanged(AudioStreamState state) OVERRIDE;
+ // media::AudioOutputIPCDelegate implementation.
+ virtual void OnStateChanged(
+ media::AudioOutputIPCDelegate::State state) OVERRIDE;
virtual void OnStreamCreated(base::SharedMemoryHandle handle,
base::SyncSocket::Handle socket_handle,
- uint32 length) OVERRIDE;
+ int length) OVERRIDE;
+ virtual void OnIPCClosed() OVERRIDE;
protected:
virtual ~PepperPlatformAudioOutputImpl();
@@ -66,9 +68,9 @@ class PepperPlatformAudioOutputImpl
// ACCESSED ON THE MAIN THREAD.
webkit::ppapi::PluginDelegate::PlatformAudioOutputClient* client_;
- // MessageFilter used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
+ // Used to send/receive IPC. THIS MUST ONLY BE ACCESSED ON THE
// I/O thread except to send messages and get the message loop.
- scoped_refptr<AudioMessageFilter> filter_;
+ media::AudioOutputIPC* ipc_;
// Our ID on the MessageFilter. THIS MUST ONLY BE ACCESSED ON THE I/O THREAD
// or else you could race with the initialize function which sets it.