summaryrefslogtreecommitdiffstats
path: root/content/renderer
diff options
context:
space:
mode:
authormiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-17 23:09:42 +0000
committermiu@chromium.org <miu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-17 23:09:42 +0000
commitf59611433c645e16dd9b61413ef1a1da19ee1921 (patch)
tree36d81dc6de6d8afef96d44a8a8580e73c1346e55 /content/renderer
parentfac11ee05e9b95d043df09627f560fec75411436 (diff)
downloadchromium_src-f59611433c645e16dd9b61413ef1a1da19ee1921.zip
chromium_src-f59611433c645e16dd9b61413ef1a1da19ee1921.tar.gz
chromium_src-f59611433c645e16dd9b61413ef1a1da19ee1921.tar.bz2
Merge AssociateStreamWithProducer message into CreateStream message for both audio output and input.
Also: 1. Removed RendererAudioOutputDevice class, since it's no longer necessary to manage asynchronously associating a render view with a stream. 2. Clean-ups: Applied several changes/bug fixes to bring the audio input classes/impls up-to-date w.r.t. the audio output classes/impls. Filed bug 179597 for follow-up. 3. Added missing plumbing for associating audio input devices created by WebRtcAudioCapturer to render views. 4. Updated unit tests. BUG=166779 TEST=media_unittests, content_unittests, TSAN, chrome/test/functional/webrtc_*.py, and manual testing described in http://codereview.chromium.org/11359196/ Review URL: https://codereview.chromium.org/12383016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194711 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer')
-rw-r--r--content/renderer/media/audio_device_factory.cc41
-rw-r--r--content/renderer/media/audio_device_factory.h29
-rw-r--r--content/renderer/media/audio_input_message_filter.cc106
-rw-r--r--content/renderer/media/audio_input_message_filter.h37
-rw-r--r--content/renderer/media/audio_message_filter.cc102
-rw-r--r--content/renderer/media/audio_message_filter.h46
-rw-r--r--content/renderer/media/audio_message_filter_unittest.cc42
-rw-r--r--content/renderer/media/audio_renderer_mixer_manager.cc9
-rw-r--r--content/renderer/media/media_stream_dependency_factory.cc7
-rw-r--r--content/renderer/media/media_stream_dependency_factory.h4
-rw-r--r--content/renderer/media/media_stream_dependency_factory_unittest.cc3
-rw-r--r--content/renderer/media/media_stream_impl.cc1
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.cc3
-rw-r--r--content/renderer/media/mock_media_stream_dependency_factory.h2
-rw-r--r--content/renderer/media/renderer_audio_output_device.cc66
-rw-r--r--content/renderer/media/renderer_audio_output_device.h58
-rw-r--r--content/renderer/media/renderer_webaudiodevice_impl.cc12
-rw-r--r--content/renderer/media/renderer_webaudiodevice_impl.h8
-rw-r--r--content/renderer/media/webrtc_audio_capturer.cc7
-rw-r--r--content/renderer/media/webrtc_audio_capturer.h9
-rw-r--r--content/renderer/media/webrtc_audio_device_unittest.cc2
-rw-r--r--content/renderer/media/webrtc_audio_renderer.cc7
-rw-r--r--content/renderer/media/webrtc_audio_renderer.h7
-rw-r--r--content/renderer/media/webrtc_local_audio_renderer.cc5
-rw-r--r--content/renderer/media/webrtc_local_audio_renderer.h4
-rw-r--r--content/renderer/pepper/pepper_platform_audio_input_impl.cc57
-rw-r--r--content/renderer/pepper/pepper_platform_audio_input_impl.h20
-rw-r--r--content/renderer/pepper/pepper_platform_audio_output_impl.cc50
-rw-r--r--content/renderer/pepper/pepper_platform_audio_output_impl.h12
-rw-r--r--content/renderer/render_view_impl.cc7
30 files changed, 359 insertions, 404 deletions
diff --git a/content/renderer/media/audio_device_factory.cc b/content/renderer/media/audio_device_factory.cc
index fae521e..927a85f 100644
--- a/content/renderer/media/audio_device_factory.cc
+++ b/content/renderer/media/audio_device_factory.cc
@@ -7,8 +7,8 @@
#include "base/logging.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/media/audio_message_filter.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "media/audio/audio_input_device.h"
+#include "media/audio/audio_output_device.h"
namespace content {
@@ -16,24 +16,33 @@ namespace content {
AudioDeviceFactory* AudioDeviceFactory::factory_ = NULL;
// static
-scoped_refptr<RendererAudioOutputDevice> AudioDeviceFactory::NewOutputDevice() {
- RendererAudioOutputDevice* device = NULL;
- if (factory_)
- device = factory_->CreateOutputDevice();
-
- return device ? device : new RendererAudioOutputDevice(
- AudioMessageFilter::Get(), AudioMessageFilter::Get()->io_message_loop());
+scoped_refptr<media::AudioOutputDevice> AudioDeviceFactory::NewOutputDevice(
+ int render_view_id) {
+ if (factory_) {
+ media::AudioOutputDevice* const device =
+ factory_->CreateOutputDevice(render_view_id);
+ if (device)
+ return device;
+ }
+
+ AudioMessageFilter* const filter = AudioMessageFilter::Get();
+ return new media::AudioOutputDevice(
+ filter->CreateAudioOutputIPC(render_view_id), filter->io_message_loop());
}
// static
-scoped_refptr<media::AudioInputDevice> AudioDeviceFactory::NewInputDevice() {
- media::AudioInputDevice* device = NULL;
- if (factory_)
- device = factory_->CreateInputDevice();
-
- return device ? device : new media::AudioInputDevice(
- AudioInputMessageFilter::Get(),
- AudioInputMessageFilter::Get()->io_message_loop());
+scoped_refptr<media::AudioInputDevice> AudioDeviceFactory::NewInputDevice(
+ int render_view_id) {
+ if (factory_) {
+ media::AudioInputDevice* const device =
+ factory_->CreateInputDevice(render_view_id);
+ if (device)
+ return device;
+ }
+
+ AudioInputMessageFilter* const filter = AudioInputMessageFilter::Get();
+ return new media::AudioInputDevice(
+ filter->CreateAudioInputIPC(render_view_id), filter->io_message_loop());
}
AudioDeviceFactory::AudioDeviceFactory() {
diff --git a/content/renderer/media/audio_device_factory.h b/content/renderer/media/audio_device_factory.h
index b06ace7..46bf5f9 100644
--- a/content/renderer/media/audio_device_factory.h
+++ b/content/renderer/media/audio_device_factory.h
@@ -10,22 +10,27 @@
namespace media {
class AudioInputDevice;
+class AudioOutputDevice;
}
namespace content {
-class RendererAudioOutputDevice;
-
-// A factory for creating RendererAudioOutputDevices. There is a global factory
-// function that can be installed for the purposes of testing to provide
-// a specialized AudioRendererSink class.
+// A factory for creating AudioOutputDevices and AudioInputDevices. There is a
+// global factory function that can be installed for the purposes of testing to
+// provide specialized implementations.
class AudioDeviceFactory {
public:
- // Creates a RendererAudioOutputDevice using the currently registered factory.
- static scoped_refptr<RendererAudioOutputDevice> NewOutputDevice();
-
- // Creates an AudioInputDevice using the currently registered factory,
- static scoped_refptr<media::AudioInputDevice> NewInputDevice();
+ // Creates an AudioOutputDevice using the currently registered factory.
+ // |render_view_id| refers to the render view containing the entity producing
+ // the audio.
+ static scoped_refptr<media::AudioOutputDevice> NewOutputDevice(
+ int render_view_id);
+
+ // Creates an AudioInputDevice using the currently registered factory.
+ // |render_view_id| refers to the render view containing the entity consuming
+ // the audio.
+ static scoped_refptr<media::AudioInputDevice> NewInputDevice(
+ int render_view_id);
protected:
AudioDeviceFactory();
@@ -35,8 +40,8 @@ class AudioDeviceFactory {
// 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 RendererAudioOutputDevice* CreateOutputDevice() = 0;
- virtual media::AudioInputDevice* CreateInputDevice() = 0;
+ virtual media::AudioOutputDevice* CreateOutputDevice(int render_view_id) = 0;
+ virtual media::AudioInputDevice* CreateInputDevice(int render_view_id) = 0;
private:
// The current globally registered factory. This is NULL when we should
diff --git a/content/renderer/media/audio_input_message_filter.cc b/content/renderer/media/audio_input_message_filter.cc
index 038edf3..2b78e2c 100644
--- a/content/renderer/media/audio_input_message_filter.cc
+++ b/content/renderer/media/audio_input_message_filter.cc
@@ -11,24 +11,51 @@
namespace content {
-AudioInputMessageFilter* AudioInputMessageFilter::filter_ = NULL;
+namespace {
+const int kStreamIDNotSet = -1;
+}
+
+class AudioInputMessageFilter::AudioInputIPCImpl
+ : public NON_EXPORTED_BASE(media::AudioInputIPC) {
+ public:
+ AudioInputIPCImpl(const scoped_refptr<AudioInputMessageFilter>& filter,
+ int render_view_id);
+ virtual ~AudioInputIPCImpl();
+
+ // media::AudioInputIPC implementation.
+ virtual void CreateStream(media::AudioInputIPCDelegate* delegate,
+ int session_id,
+ const media::AudioParameters& params,
+ bool automatic_gain_control,
+ uint32 total_segments) OVERRIDE;
+ virtual void RecordStream() OVERRIDE;
+ virtual void SetVolume(double volume) OVERRIDE;
+ virtual void CloseStream() OVERRIDE;
+
+ private:
+ const scoped_refptr<AudioInputMessageFilter> filter_;
+ const int render_view_id_;
+ int stream_id_;
+};
+
+AudioInputMessageFilter* AudioInputMessageFilter::g_filter = NULL;
AudioInputMessageFilter::AudioInputMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
: channel_(NULL),
io_message_loop_(io_message_loop) {
- DCHECK(!filter_);
- filter_ = this;
+ DCHECK(!g_filter);
+ g_filter = this;
}
AudioInputMessageFilter::~AudioInputMessageFilter() {
- DCHECK_EQ(filter_, this);
- filter_ = NULL;
+ DCHECK_EQ(g_filter, this);
+ g_filter = NULL;
}
-// static.
+// static
AudioInputMessageFilter* AudioInputMessageFilter::Get() {
- return filter_;
+ return g_filter;
}
void AudioInputMessageFilter::Send(IPC::Message* message) {
@@ -134,43 +161,56 @@ void AudioInputMessageFilter::OnStreamStateChanged(
delegate->OnStateChanged(state);
}
-int AudioInputMessageFilter::AddDelegate(
- media::AudioInputIPCDelegate* delegate) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- return delegates_.Add(delegate);
-}
+AudioInputMessageFilter::AudioInputIPCImpl::AudioInputIPCImpl(
+ const scoped_refptr<AudioInputMessageFilter>& filter, int render_view_id)
+ : filter_(filter),
+ render_view_id_(render_view_id),
+ stream_id_(kStreamIDNotSet) {}
-void AudioInputMessageFilter::RemoveDelegate(int id) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- delegates_.Remove(id);
+AudioInputMessageFilter::AudioInputIPCImpl::~AudioInputIPCImpl() {}
+
+scoped_ptr<media::AudioInputIPC> AudioInputMessageFilter::CreateAudioInputIPC(
+ int render_view_id) {
+ DCHECK_GT(render_view_id, 0);
+ return scoped_ptr<media::AudioInputIPC>(
+ new AudioInputIPCImpl(this, render_view_id));
}
-void AudioInputMessageFilter::CreateStream(int stream_id,
- int session_id,
- const media::AudioParameters& params,
- bool automatic_gain_control,
- uint32 total_segments) {
- Send(new AudioInputHostMsg_CreateStream(
- stream_id, session_id, params, automatic_gain_control, total_segments));
+void AudioInputMessageFilter::AudioInputIPCImpl::CreateStream(
+ media::AudioInputIPCDelegate* delegate,
+ int session_id,
+ const media::AudioParameters& params,
+ bool automatic_gain_control,
+ uint32 total_segments) {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK(delegate);
-}
+ stream_id_ = filter_->delegates_.Add(delegate);
-void AudioInputMessageFilter::AssociateStreamWithConsumer(int stream_id,
- int render_view_id) {
- Send(new AudioInputHostMsg_AssociateStreamWithConsumer(
- stream_id, render_view_id));
+ AudioInputHostMsg_CreateStream_Config config;
+ config.params = params;
+ config.automatic_gain_control = automatic_gain_control;
+ config.shared_memory_count = total_segments;
+ filter_->Send(new AudioInputHostMsg_CreateStream(
+ stream_id_, render_view_id_, session_id, config));
}
-void AudioInputMessageFilter::RecordStream(int stream_id) {
- Send(new AudioInputHostMsg_RecordStream(stream_id));
+void AudioInputMessageFilter::AudioInputIPCImpl::RecordStream() {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_));
}
-void AudioInputMessageFilter::CloseStream(int stream_id) {
- Send(new AudioInputHostMsg_CloseStream(stream_id));
+void AudioInputMessageFilter::AudioInputIPCImpl::SetVolume(double volume) {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioInputHostMsg_SetVolume(stream_id_, volume));
}
-void AudioInputMessageFilter::SetVolume(int stream_id, double volume) {
- Send(new AudioInputHostMsg_SetVolume(stream_id, volume));
+void AudioInputMessageFilter::AudioInputIPCImpl::CloseStream() {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_));
+ filter_->delegates_.Remove(stream_id_);
+ stream_id_ = kStreamIDNotSet;
}
} // namespace content
diff --git a/content/renderer/media/audio_input_message_filter.h b/content/renderer/media/audio_input_message_filter.h
index bd6a0e12..fcba0a7 100644
--- a/content/renderer/media/audio_input_message_filter.h
+++ b/content/renderer/media/audio_input_message_filter.h
@@ -6,6 +6,7 @@
#define CONTENT_RENDERER_MEDIA_AUDIO_INPUT_MESSAGE_FILTER_H_
#include "base/id_map.h"
+#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/sync_socket.h"
#include "content/common/content_export.h"
@@ -23,8 +24,7 @@ namespace content {
// IO thread (secondary thread of render process), it intercepts audio messages
// and process them on IO thread since these messages are time critical.
class CONTENT_EXPORT AudioInputMessageFilter
- : public IPC::ChannelProxy::MessageFilter,
- public NON_EXPORTED_BASE(media::AudioInputIPC) {
+ : public IPC::ChannelProxy::MessageFilter {
public:
explicit AudioInputMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
@@ -32,29 +32,22 @@ class CONTENT_EXPORT AudioInputMessageFilter
// Getter for the one AudioInputMessageFilter object.
static AudioInputMessageFilter* Get();
- // Associates |render_view_id| as the destination of audio for a stream.
- void AssociateStreamWithConsumer(int stream_id, int render_view_id);
-
- // Implementation of AudioInputIPC. All methods must be called on the
- // provided |io_message_loop|.
- virtual int AddDelegate(
- media::AudioInputIPCDelegate* delegate) OVERRIDE;
- virtual void RemoveDelegate(int id) OVERRIDE;
- virtual void CreateStream(
- int stream_id,
- int session_id,
- const media::AudioParameters& params,
- bool automatic_gain_control,
- uint32 total_segments) OVERRIDE;
- virtual void RecordStream(int stream_id) OVERRIDE;
- virtual void CloseStream(int stream_id) OVERRIDE;
- virtual void SetVolume(int stream_id, double volume) OVERRIDE;
+ // Create an AudioInputIPC to be owned by one delegate. |render_view_id| is
+ // the render view containing the entity consuming the audio.
+ //
+ // The returned object is not thread-safe, and must be used on
+ // |io_message_loop|.
+ scoped_ptr<media::AudioInputIPC> CreateAudioInputIPC(int render_view_id);
scoped_refptr<base::MessageLoopProxy> io_message_loop() const {
return io_message_loop_;
}
private:
+ // Implementation of media::AudioInputIPC which augments IPC calls with
+ // stream_id and the destination render_view_id.
+ class AudioInputIPCImpl;
+
virtual ~AudioInputMessageFilter();
// Sends an IPC message using |channel_|.
@@ -91,12 +84,12 @@ class CONTENT_EXPORT AudioInputMessageFilter
// IPC channel for Send(), must only be accesed on |io_message_loop_|.
IPC::Channel* channel_;
- // The singleton instance for this filter.
- static AudioInputMessageFilter* filter_;
-
// Message loop on which IPC calls are driven.
const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ // The singleton instance for this filter.
+ static AudioInputMessageFilter* g_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 a3bcf65..1cb5352 100644
--- a/content/renderer/media/audio_message_filter.cc
+++ b/content/renderer/media/audio_message_filter.cc
@@ -12,56 +12,99 @@
namespace content {
-AudioMessageFilter* AudioMessageFilter::filter_ = NULL;
-
-// static
-AudioMessageFilter* AudioMessageFilter::Get() {
- return filter_;
+namespace {
+const int kStreamIDNotSet = -1;
}
+class AudioMessageFilter::AudioOutputIPCImpl
+ : public NON_EXPORTED_BASE(media::AudioOutputIPC) {
+ public:
+ AudioOutputIPCImpl(const scoped_refptr<AudioMessageFilter>& filter,
+ int render_view_id);
+ virtual ~AudioOutputIPCImpl();
+
+ // media::AudioOutputIPC implementation.
+ virtual void CreateStream(media::AudioOutputIPCDelegate* delegate,
+ const media::AudioParameters& params) OVERRIDE;
+ virtual void PlayStream() OVERRIDE;
+ virtual void PauseStream() OVERRIDE;
+ virtual void CloseStream() OVERRIDE;
+ virtual void SetVolume(double volume) OVERRIDE;
+
+ private:
+ const scoped_refptr<AudioMessageFilter> filter_;
+ const int render_view_id_;
+ int stream_id_;
+};
+
+AudioMessageFilter* AudioMessageFilter::g_filter = NULL;
+
AudioMessageFilter::AudioMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop)
: channel_(NULL),
audio_hardware_config_(NULL),
io_message_loop_(io_message_loop) {
- DCHECK(!filter_);
- filter_ = this;
+ DCHECK(!g_filter);
+ g_filter = this;
}
-int AudioMessageFilter::AddDelegate(media::AudioOutputIPCDelegate* delegate) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- return delegates_.Add(delegate);
+AudioMessageFilter::~AudioMessageFilter() {
+ DCHECK_EQ(g_filter, this);
+ g_filter = NULL;
}
-void AudioMessageFilter::RemoveDelegate(int id) {
- DCHECK(io_message_loop_->BelongsToCurrentThread());
- delegates_.Remove(id);
+// static
+AudioMessageFilter* AudioMessageFilter::Get() {
+ return g_filter;
}
-void AudioMessageFilter::CreateStream(int stream_id,
- const media::AudioParameters& params) {
- Send(new AudioHostMsg_CreateStream(stream_id, params));
+AudioMessageFilter::AudioOutputIPCImpl::AudioOutputIPCImpl(
+ const scoped_refptr<AudioMessageFilter>& filter, int render_view_id)
+ : filter_(filter),
+ render_view_id_(render_view_id),
+ stream_id_(kStreamIDNotSet) {}
+
+AudioMessageFilter::AudioOutputIPCImpl::~AudioOutputIPCImpl() {}
+
+scoped_ptr<media::AudioOutputIPC> AudioMessageFilter::CreateAudioOutputIPC(
+ int render_view_id) {
+ DCHECK_GT(render_view_id, 0);
+ return scoped_ptr<media::AudioOutputIPC>(
+ new AudioOutputIPCImpl(this, render_view_id));
}
-void AudioMessageFilter::AssociateStreamWithProducer(int stream_id,
- int render_view_id) {
- Send(new AudioHostMsg_AssociateStreamWithProducer(stream_id, render_view_id));
+void AudioMessageFilter::AudioOutputIPCImpl::CreateStream(
+ media::AudioOutputIPCDelegate* delegate,
+ const media::AudioParameters& params) {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK(delegate);
+ DCHECK_EQ(stream_id_, kStreamIDNotSet);
+ stream_id_ = filter_->delegates_.Add(delegate);
+ filter_->Send(new AudioHostMsg_CreateStream(
+ stream_id_, render_view_id_, params));
}
-void AudioMessageFilter::PlayStream(int stream_id) {
- Send(new AudioHostMsg_PlayStream(stream_id));
+void AudioMessageFilter::AudioOutputIPCImpl::PlayStream() {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_PlayStream(stream_id_));
}
-void AudioMessageFilter::PauseStream(int stream_id) {
- Send(new AudioHostMsg_PauseStream(stream_id));
+void AudioMessageFilter::AudioOutputIPCImpl::PauseStream() {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_PauseStream(stream_id_));
}
-void AudioMessageFilter::CloseStream(int stream_id) {
- Send(new AudioHostMsg_CloseStream(stream_id));
+void AudioMessageFilter::AudioOutputIPCImpl::CloseStream() {
+ DCHECK(filter_->io_message_loop_->BelongsToCurrentThread());
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_CloseStream(stream_id_));
+ filter_->delegates_.Remove(stream_id_);
+ stream_id_ = kStreamIDNotSet;
}
-void AudioMessageFilter::SetVolume(int stream_id, double volume) {
- Send(new AudioHostMsg_SetVolume(stream_id, volume));
+void AudioMessageFilter::AudioOutputIPCImpl::SetVolume(double volume) {
+ DCHECK_NE(stream_id_, kStreamIDNotSet);
+ filter_->Send(new AudioHostMsg_SetVolume(stream_id_, volume));
}
void AudioMessageFilter::Send(IPC::Message* message) {
@@ -113,11 +156,6 @@ void AudioMessageFilter::OnChannelClosing() {
}
}
-AudioMessageFilter::~AudioMessageFilter() {
- DCHECK_EQ(filter_, this);
- filter_ = NULL;
-}
-
void AudioMessageFilter::OnStreamCreated(
int stream_id,
base::SharedMemoryHandle handle,
diff --git a/content/renderer/media/audio_message_filter.h b/content/renderer/media/audio_message_filter.h
index d60c80c..38deb80 100644
--- a/content/renderer/media/audio_message_filter.h
+++ b/content/renderer/media/audio_message_filter.h
@@ -7,6 +7,7 @@
#include "base/gtest_prod_util.h"
#include "base/id_map.h"
+#include "base/memory/scoped_ptr.h"
#include "base/shared_memory.h"
#include "base/sync_socket.h"
#include "base/synchronization/lock.h"
@@ -26,8 +27,7 @@ namespace content {
// IO thread (secondary thread of render process) it intercepts audio messages
// and process them on IO thread since these messages are time critical.
class CONTENT_EXPORT AudioMessageFilter
- : public IPC::ChannelProxy::MessageFilter,
- public NON_EXPORTED_BASE(media::AudioOutputIPC) {
+ : public IPC::ChannelProxy::MessageFilter {
public:
explicit AudioMessageFilter(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop);
@@ -35,26 +35,12 @@ class CONTENT_EXPORT AudioMessageFilter
// Getter for the one AudioMessageFilter object.
static AudioMessageFilter* Get();
- // Associates |render_view_id| as the source of audio rendered for a stream.
- void AssociateStreamWithProducer(int stream_id, int render_view_id);
-
- // media::AudioOutputIPC implementation.
- virtual int AddDelegate(media::AudioOutputIPCDelegate* delegate) OVERRIDE;
- virtual void RemoveDelegate(int id) OVERRIDE;
-
- // Methods below must be called on the provided |io_message_loop|.
- 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 CloseStream(int stream_id) OVERRIDE;
- virtual void SetVolume(int stream_id, double volume) OVERRIDE;
-
- // IPC::ChannelProxy::MessageFilter override. Called on |io_message_loop|.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
- virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
- virtual void OnFilterRemoved() OVERRIDE;
- virtual void OnChannelClosing() OVERRIDE;
+ // Create an AudioOutputIPC to be owned by one delegate. |render_view_id| is
+ // the render view containing the entity producing the audio.
+ //
+ // The returned object is not thread-safe, and must be used on
+ // |io_message_loop|.
+ scoped_ptr<media::AudioOutputIPC> CreateAudioOutputIPC(int render_view_id);
// When set, AudioMessageFilter will update the AudioHardwareConfig with new
// configuration values as recieved by OnOutputDeviceChanged(). The provided
@@ -73,9 +59,19 @@ class CONTENT_EXPORT AudioMessageFilter
FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Basic);
FRIEND_TEST_ALL_PREFIXES(AudioMessageFilterTest, Delegates);
+ // Implementation of media::AudioOutputIPC which augments IPC calls with
+ // stream_id and the source render_view_id.
+ class AudioOutputIPCImpl;
+
// Sends an IPC message using |channel_|.
void Send(IPC::Message* message);
+ // IPC::ChannelProxy::MessageFilter override. Called on |io_message_loop|.
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE;
+ virtual void OnFilterRemoved() OVERRIDE;
+ virtual void OnChannelClosing() OVERRIDE;
+
// Received when browser process has created an audio output stream.
void OnStreamCreated(int stream_id, base::SharedMemoryHandle handle,
#if defined(OS_WIN)
@@ -94,9 +90,6 @@ class CONTENT_EXPORT AudioMessageFilter
void OnOutputDeviceChanged(int stream_id, int new_buffer_size,
int new_sample_rate);
- // The singleton instance for this filter.
- static AudioMessageFilter* filter_;
-
// IPC channel for Send(); must only be accesed on |io_message_loop_|.
IPC::Channel* channel_;
@@ -112,6 +105,9 @@ class CONTENT_EXPORT AudioMessageFilter
// Message loop on which IPC calls are driven.
const scoped_refptr<base::MessageLoopProxy> io_message_loop_;
+ // The singleton instance for this filter.
+ static AudioMessageFilter* g_filter;
+
DISALLOW_COPY_AND_ASSIGN(AudioMessageFilter);
};
diff --git a/content/renderer/media/audio_message_filter_unittest.cc b/content/renderer/media/audio_message_filter_unittest.cc
index 4626a64..65ca209 100644
--- a/content/renderer/media/audio_message_filter_unittest.cc
+++ b/content/renderer/media/audio_message_filter_unittest.cc
@@ -11,6 +11,8 @@
namespace content {
namespace {
+const int kRenderViewId = 1;
+
class MockAudioDelegate : public media::AudioOutputIPCDelegate {
public:
MockAudioDelegate() {
@@ -75,7 +77,11 @@ TEST(AudioMessageFilterTest, Basic) {
message_loop.message_loop_proxy()));
MockAudioDelegate delegate;
- int stream_id = filter->AddDelegate(&delegate);
+ const scoped_ptr<media::AudioOutputIPC> ipc =
+ filter->CreateAudioOutputIPC(kRenderViewId);
+ ipc->CreateStream(&delegate, media::AudioParameters());
+ static const int kStreamId = 1;
+ EXPECT_EQ(&delegate, filter->delegates_.Lookup(kStreamId));
// AudioMsg_NotifyStreamCreated
#if defined(OS_WIN)
@@ -87,7 +93,7 @@ TEST(AudioMessageFilterTest, Basic) {
EXPECT_FALSE(delegate.created_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamCreated(
- stream_id, base::SharedMemory::NULLHandle(),
+ kStreamId, base::SharedMemory::NULLHandle(),
socket_handle, kLength));
EXPECT_TRUE(delegate.created_received());
EXPECT_FALSE(base::SharedMemory::IsHandleValid(delegate.handle()));
@@ -98,13 +104,16 @@ TEST(AudioMessageFilterTest, Basic) {
EXPECT_FALSE(delegate.state_changed_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamStateChanged(
- stream_id, media::AudioOutputIPCDelegate::kPlaying));
+ kStreamId, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_TRUE(delegate.state_changed_received());
EXPECT_EQ(media::AudioOutputIPCDelegate::kPlaying, delegate.state());
delegate.Reset();
message_loop.RunUntilIdle();
- filter->RemoveDelegate(stream_id);
+
+ ipc->CloseStream();
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ filter->delegates_.Lookup(kStreamId));
}
TEST(AudioMessageFilterTest, Delegates) {
@@ -115,16 +124,23 @@ TEST(AudioMessageFilterTest, Delegates) {
MockAudioDelegate delegate1;
MockAudioDelegate delegate2;
-
- int stream_id1 = filter->AddDelegate(&delegate1);
- int stream_id2 = filter->AddDelegate(&delegate2);
+ const scoped_ptr<media::AudioOutputIPC> ipc1 =
+ filter->CreateAudioOutputIPC(kRenderViewId);
+ const scoped_ptr<media::AudioOutputIPC> ipc2 =
+ filter->CreateAudioOutputIPC(kRenderViewId);
+ ipc1->CreateStream(&delegate1, media::AudioParameters());
+ ipc2->CreateStream(&delegate2, media::AudioParameters());
+ static const int kStreamId1 = 1;
+ static const int kStreamId2 = 2;
+ EXPECT_EQ(&delegate1, filter->delegates_.Lookup(kStreamId1));
+ EXPECT_EQ(&delegate2, filter->delegates_.Lookup(kStreamId2));
// Send an IPC message. Make sure the correct delegate gets called.
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamStateChanged(
- stream_id1, media::AudioOutputIPCDelegate::kPlaying));
+ kStreamId1, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_TRUE(delegate1.state_changed_received());
EXPECT_FALSE(delegate2.state_changed_received());
delegate1.Reset();
@@ -133,15 +149,19 @@ TEST(AudioMessageFilterTest, Delegates) {
EXPECT_FALSE(delegate2.state_changed_received());
filter->OnMessageReceived(
AudioMsg_NotifyStreamStateChanged(
- stream_id2, media::AudioOutputIPCDelegate::kPlaying));
+ kStreamId2, media::AudioOutputIPCDelegate::kPlaying));
EXPECT_FALSE(delegate1.state_changed_received());
EXPECT_TRUE(delegate2.state_changed_received());
delegate2.Reset();
message_loop.RunUntilIdle();
- filter->RemoveDelegate(stream_id1);
- filter->RemoveDelegate(stream_id2);
+ ipc1->CloseStream();
+ ipc2->CloseStream();
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ filter->delegates_.Lookup(kStreamId1));
+ EXPECT_EQ(static_cast<media::AudioOutputIPCDelegate*>(NULL),
+ filter->delegates_.Lookup(kStreamId2));
}
} // namespace content
diff --git a/content/renderer/media/audio_renderer_mixer_manager.cc b/content/renderer/media/audio_renderer_mixer_manager.cc
index 2f2433f..7db67d1 100644
--- a/content/renderer/media/audio_renderer_mixer_manager.cc
+++ b/content/renderer/media/audio_renderer_mixer_manager.cc
@@ -7,7 +7,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/audio_hardware_config.h"
#include "media/base/audio_renderer_mixer.h"
#include "media/base/audio_renderer_mixer_input.h"
@@ -77,10 +77,9 @@ media::AudioRendererMixer* AudioRendererMixerManager::GetMixer(
mixer = new media::AudioRendererMixer(
params, output_params, sink_for_testing_);
} else {
- scoped_refptr<RendererAudioOutputDevice> device =
- AudioDeviceFactory::NewOutputDevice();
- device->SetSourceRenderView(source_render_view_id);
- mixer = new media::AudioRendererMixer(params, output_params, device);
+ mixer = new media::AudioRendererMixer(
+ params, output_params, AudioDeviceFactory::NewOutputDevice(
+ source_render_view_id));
}
AudioRendererMixerReference mixer_reference = { mixer, 1 };
diff --git a/content/renderer/media/media_stream_dependency_factory.cc b/content/renderer/media/media_stream_dependency_factory.cc
index aa9b7dc..332c2b7 100644
--- a/content/renderer/media/media_stream_dependency_factory.cc
+++ b/content/renderer/media/media_stream_dependency_factory.cc
@@ -227,6 +227,7 @@ MediaStreamDependencyFactory::CreateRTCPeerConnectionHandler(
}
void MediaStreamDependencyFactory::CreateNativeMediaSources(
+ int render_view_id,
const WebKit::WebMediaConstraints& audio_constraints,
const WebKit::WebMediaConstraints& video_constraints,
WebKit::WebMediaStream* description,
@@ -284,7 +285,7 @@ void MediaStreamDependencyFactory::CreateNativeMediaSources(
const StreamDeviceInfo device_info = source_data->device_info();
if (IsAudioMediaType(device_info.device.type)) {
- if (!InitializeAudioSource(device_info)) {
+ if (!InitializeAudioSource(render_view_id, device_info)) {
DLOG(WARNING) << "Unsupported audio source";
sources_created.Run(description, false);
return;
@@ -486,7 +487,8 @@ MediaStreamDependencyFactory::CreateLocalVideoSource(
}
bool MediaStreamDependencyFactory::InitializeAudioSource(
- const StreamDeviceInfo& device_info) {
+ int render_view_id,
+ const StreamDeviceInfo& device_info) {
DVLOG(1) << "MediaStreamDependencyFactory::InitializeAudioSource()";
// TODO(henrika): the current design does not support a unique source
@@ -500,6 +502,7 @@ bool MediaStreamDependencyFactory::InitializeAudioSource(
// TODO(henrika): refactor \content\public\common\media_stream_request.h
// to allow dependency of media::ChannelLayout and avoid static_cast.
if (!capturer->Initialize(
+ render_view_id,
static_cast<media::ChannelLayout>(device_info.device.channel_layout),
device_info.device.sample_rate, device_info.session_id))
return false;
diff --git a/content/renderer/media/media_stream_dependency_factory.h b/content/renderer/media/media_stream_dependency_factory.h
index 2bdd8ff..de7c455 100644
--- a/content/renderer/media/media_stream_dependency_factory.h
+++ b/content/renderer/media/media_stream_dependency_factory.h
@@ -71,6 +71,7 @@ class CONTENT_EXPORT MediaStreamDependencyFactory
// WebMediaStreamSource.
// |audio_constraints| and |video_constraints| set parameters for the sources.
void CreateNativeMediaSources(
+ int render_view_id,
const WebKit::WebMediaConstraints& audio_constraints,
const WebKit::WebMediaConstraints& video_constraints,
WebKit::WebMediaStream* description,
@@ -147,7 +148,8 @@ class CONTENT_EXPORT MediaStreamDependencyFactory
// Initializes the source using audio parameters for the selected
// capture device and specifies which capture device to use as capture
// source.
- virtual bool InitializeAudioSource(const StreamDeviceInfo& device_info);
+ virtual bool InitializeAudioSource(int render_view_id,
+ const StreamDeviceInfo& device_info);
// Creates a media::AudioCapturerSource with an implementation that is
// specific for a WebAudio source. The created WebAudioCapturerSource
diff --git a/content/renderer/media/media_stream_dependency_factory_unittest.cc b/content/renderer/media/media_stream_dependency_factory_unittest.cc
index 879c425..948646d 100644
--- a/content/renderer/media/media_stream_dependency_factory_unittest.cc
+++ b/content/renderer/media/media_stream_dependency_factory_unittest.cc
@@ -86,9 +86,12 @@ class MediaStreamDependencyFactoryTest : public ::testing::Test {
}
void CreateNativeSources(WebKit::WebMediaStream* descriptor) {
+ static const int kRenderViewId = 1;
+
MediaSourceCreatedObserver observer;
WebKit::WebMediaConstraints audio_constraints;
dependency_factory_->CreateNativeMediaSources(
+ kRenderViewId,
WebKit::WebMediaConstraints(),
WebKit::WebMediaConstraints(),
descriptor,
diff --git a/content/renderer/media/media_stream_impl.cc b/content/renderer/media/media_stream_impl.cc
index 85c8fde..d107480 100644
--- a/content/renderer/media/media_stream_impl.cc
+++ b/content/renderer/media/media_stream_impl.cc
@@ -331,6 +331,7 @@ void MediaStreamImpl::OnStreamGenerated(
WebKit::WebMediaConstraints() : request->videoConstraints();
dependency_factory_->CreateNativeMediaSources(
+ RenderViewObserver::routing_id(),
audio_constraints, video_constraints, description,
base::Bind(&MediaStreamImpl::OnCreateNativeSourcesComplete, AsWeakPtr()));
}
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.cc b/content/renderer/media/mock_media_stream_dependency_factory.cc
index 3920a71..85a8d18 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.cc
+++ b/content/renderer/media/mock_media_stream_dependency_factory.cc
@@ -411,7 +411,8 @@ MockMediaStreamDependencyFactory::CreateLocalVideoSource(
}
bool MockMediaStreamDependencyFactory::InitializeAudioSource(
- const StreamDeviceInfo& device_info) {
+ int render_view_id,
+ const StreamDeviceInfo& device_info) {
return true;
}
diff --git a/content/renderer/media/mock_media_stream_dependency_factory.h b/content/renderer/media/mock_media_stream_dependency_factory.h
index 9809fab..db7e832 100644
--- a/content/renderer/media/mock_media_stream_dependency_factory.h
+++ b/content/renderer/media/mock_media_stream_dependency_factory.h
@@ -143,7 +143,7 @@ class MockMediaStreamDependencyFactory : public MediaStreamDependencyFactory {
bool is_screencast,
const webrtc::MediaConstraintsInterface* constraints) OVERRIDE;
virtual bool InitializeAudioSource(
- const StreamDeviceInfo& device_info) OVERRIDE;
+ int render_view_id, const StreamDeviceInfo& device_info) OVERRIDE;
virtual bool CreateWebAudioSource(
WebKit::WebMediaStreamSource* source) OVERRIDE;
virtual scoped_refptr<webrtc::MediaStreamInterface>
diff --git a/content/renderer/media/renderer_audio_output_device.cc b/content/renderer/media/renderer_audio_output_device.cc
deleted file mode 100644
index 678bbec..0000000
--- a/content/renderer/media/renderer_audio_output_device.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/media/renderer_audio_output_device.h"
-
-#include "base/bind.h"
-#include "base/message_loop_proxy.h"
-#include "content/renderer/media/audio_message_filter.h"
-
-namespace content {
-
-RendererAudioOutputDevice::RendererAudioOutputDevice(
- AudioMessageFilter* message_filter,
- const scoped_refptr<base::MessageLoopProxy>& io_loop)
- : AudioOutputDevice(message_filter, io_loop),
- source_render_view_id_(MSG_ROUTING_NONE),
- is_after_stream_created_(false) {
-}
-
-RendererAudioOutputDevice::~RendererAudioOutputDevice() {}
-
-void RendererAudioOutputDevice::Start() {
- AudioOutputDevice::Start();
- message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&RendererAudioOutputDevice::OnStart, this));
-}
-
-void RendererAudioOutputDevice::Stop() {
- AudioOutputDevice::Stop();
- message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&RendererAudioOutputDevice::OnStop, this));
-}
-
-void RendererAudioOutputDevice::SetSourceRenderView(int render_view_id) {
- message_loop()->PostTask(
- FROM_HERE,
- base::Bind(&RendererAudioOutputDevice::OnSourceChange, this,
- render_view_id));
-}
-
-void RendererAudioOutputDevice::OnStart() {
- DCHECK(message_loop()->BelongsToCurrentThread());
- is_after_stream_created_ = true;
- OnSourceChange(source_render_view_id_);
-}
-
-void RendererAudioOutputDevice::OnStop() {
- DCHECK(message_loop()->BelongsToCurrentThread());
- is_after_stream_created_ = false;
-}
-
-void RendererAudioOutputDevice::OnSourceChange(int render_view_id) {
- DCHECK(message_loop()->BelongsToCurrentThread());
- source_render_view_id_ = render_view_id;
- if (is_after_stream_created_ && source_render_view_id_ != MSG_ROUTING_NONE) {
- AudioMessageFilter* const filter =
- static_cast<AudioMessageFilter*>(audio_output_ipc());
- if (filter)
- filter->AssociateStreamWithProducer(stream_id(), source_render_view_id_);
- }
-}
-
-} // namespace content
diff --git a/content/renderer/media/renderer_audio_output_device.h b/content/renderer/media/renderer_audio_output_device.h
deleted file mode 100644
index 601cca5..0000000
--- a/content/renderer/media/renderer_audio_output_device.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_MEDIA_RENDERER_AUDIO_OUTPUT_DEVICE_H_
-#define CONTENT_RENDERER_MEDIA_RENDERER_AUDIO_OUTPUT_DEVICE_H_
-
-#include "base/memory/ref_counted.h"
-#include "media/audio/audio_output_device.h"
-
-namespace base {
-class MessageLoopProxy;
-}
-
-namespace content {
-
-class AudioDeviceFactory;
-class AudioMessageFilter;
-
-// Subclass of media::AudioOutputDevice to support additional concepts within
-// the content component. Use AudioDeviceFactory to instantiate this class.
-class RendererAudioOutputDevice
- : NON_EXPORTED_BASE(public media::AudioOutputDevice) {
- public:
- // Set the source of the rendered audio data to the RenderView specified by
- // |render_view_id|. Callers should keep in mind that the RenderView which
- // caused the instantiation of RendererAudioOutputDevice might not necessarily
- // be same as the RenderView which actually renders the audio data.
- void SetSourceRenderView(int render_view_id);
-
- virtual void Start() OVERRIDE;
- virtual void Stop() OVERRIDE;
-
- protected:
- friend class AudioDeviceFactory;
-
- // Creates an uninitialized RendererAudioOutputDevice. Clients must call
- // Initialize() before using.
- RendererAudioOutputDevice(
- AudioMessageFilter* message_filter,
- const scoped_refptr<base::MessageLoopProxy>& io_loop);
-
- private:
- virtual ~RendererAudioOutputDevice();
-
- void OnStart();
- void OnStop();
- void OnSourceChange(int render_view_id);
-
- int source_render_view_id_;
- bool is_after_stream_created_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(RendererAudioOutputDevice);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_MEDIA_RENDERER_AUDIO_OUTPUT_DEVICE_H_
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc
index ca32103..43a4a61 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -7,8 +7,8 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/render_view_impl.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/media_switches.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
@@ -38,9 +38,6 @@ void RendererWebAudioDeviceImpl::start() {
if (output_device_)
return; // Already started.
- output_device_ = AudioDeviceFactory::NewOutputDevice();
- output_device_->Initialize(params_, this);
-
// Assumption: This method is being invoked within a V8 call stack. CHECKs
// will fail in the call to frameForCurrentContext() otherwise.
//
@@ -52,10 +49,9 @@ void RendererWebAudioDeviceImpl::start() {
WebView* const web_view = web_frame ? web_frame->view() : NULL;
RenderViewImpl* const render_view =
web_view ? RenderViewImpl::FromWebView(web_view) : NULL;
- if (render_view) {
- output_device_->SetSourceRenderView(render_view->routing_id());
- }
-
+ output_device_ = AudioDeviceFactory::NewOutputDevice(
+ render_view ? render_view->routing_id() : MSG_ROUTING_NONE);
+ output_device_->Initialize(params_, this);
output_device_->Start();
// Note: Default behavior is to auto-play on start.
}
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.h b/content/renderer/media/renderer_webaudiodevice_impl.h
index ca19d074..09c35d8 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.h
+++ b/content/renderer/media/renderer_webaudiodevice_impl.h
@@ -12,9 +12,11 @@
#include "third_party/WebKit/Source/Platform/chromium/public/WebAudioDevice.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h"
-namespace content {
+namespace media {
+class AudioOutputDevice;
+}
-class RendererAudioOutputDevice;
+namespace content {
class RendererWebAudioDeviceImpl
: public WebKit::WebAudioDevice,
@@ -50,7 +52,7 @@ class RendererWebAudioDeviceImpl
base::ThreadChecker thread_checker_;
// When non-NULL, we are started. When NULL, we are stopped.
- scoped_refptr<RendererAudioOutputDevice> output_device_;
+ scoped_refptr<media::AudioOutputDevice> output_device_;
DISALLOW_COPY_AND_ASSIGN(RendererWebAudioDeviceImpl);
};
diff --git a/content/renderer/media/webrtc_audio_capturer.cc b/content/renderer/media/webrtc_audio_capturer.cc
index 35f25ee..b07f398 100644
--- a/content/renderer/media/webrtc_audio_capturer.cc
+++ b/content/renderer/media/webrtc_audio_capturer.cc
@@ -179,7 +179,7 @@ class WebRtcAudioCapturer::ConfiguredBuffer :
// static
scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer() {
- scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer();
+ scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer();
return capturer;
}
@@ -204,7 +204,8 @@ bool WebRtcAudioCapturer::Reconfigure(int sample_rate,
return true;
}
-bool WebRtcAudioCapturer::Initialize(media::ChannelLayout channel_layout,
+bool WebRtcAudioCapturer::Initialize(int render_view_id,
+ media::ChannelLayout channel_layout,
int sample_rate,
int session_id) {
DCHECK(thread_checker_.CalledOnValidThread());
@@ -245,7 +246,7 @@ bool WebRtcAudioCapturer::Initialize(media::ChannelLayout channel_layout,
// Create and configure the default audio capturing source. The |source_|
// will be overwritten if an external client later calls SetCapturerSource()
// providing an alternative media::AudioCapturerSource.
- SetCapturerSource(AudioDeviceFactory::NewInputDevice(),
+ SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id),
channel_layout,
static_cast<float>(sample_rate));
diff --git a/content/renderer/media/webrtc_audio_capturer.h b/content/renderer/media/webrtc_audio_capturer.h
index 5d35604..4709b5e 100644
--- a/content/renderer/media/webrtc_audio_capturer.h
+++ b/content/renderer/media/webrtc_audio_capturer.h
@@ -43,10 +43,11 @@ class CONTENT_EXPORT WebRtcAudioCapturer
static scoped_refptr<WebRtcAudioCapturer> CreateCapturer();
// Creates and configures the default audio capturing source using the
- // provided audio parameters, |session_id| is passed to the browser to
- // decide which device to use.
- // Called on the main render thread.
- bool Initialize(media::ChannelLayout channel_layout,
+ // provided audio parameters. |render_view_id| specifies the render view
+ // consuming audio for capture. |session_id| is passed to the browser to
+ // decide which device to use. Called on the main render thread.
+ bool Initialize(int render_view_id,
+ media::ChannelLayout channel_layout,
int sample_rate,
int session_id);
diff --git a/content/renderer/media/webrtc_audio_device_unittest.cc b/content/renderer/media/webrtc_audio_device_unittest.cc
index 4ca0195..5260738 100644
--- a/content/renderer/media/webrtc_audio_device_unittest.cc
+++ b/content/renderer/media/webrtc_audio_device_unittest.cc
@@ -104,7 +104,7 @@ bool InitializeCapturer(WebRtcAudioDeviceImpl* webrtc_audio_device) {
int sample_rate = hardware_config->GetInputSampleRate();
media::ChannelLayout channel_layout =
hardware_config->GetInputChannelLayout();
- if (!capturer->Initialize(channel_layout, sample_rate, 1))
+ if (!capturer->Initialize(kRenderViewId, channel_layout, sample_rate, 1))
return false;
return true;
diff --git a/content/renderer/media/webrtc_audio_renderer.cc b/content/renderer/media/webrtc_audio_renderer.cc
index d5591d0..f22b9cd 100644
--- a/content/renderer/media/webrtc_audio_renderer.cc
+++ b/content/renderer/media/webrtc_audio_renderer.cc
@@ -8,9 +8,9 @@
#include "base/metrics/histogram.h"
#include "base/string_util.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/webrtc_audio_device_impl.h"
#include "content/renderer/render_thread_impl.h"
+#include "media/audio/audio_output_device.h"
#include "media/audio/audio_parameters.h"
#include "media/audio/sample_rates.h"
#include "media/base/audio_hardware_config.h"
@@ -111,9 +111,6 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
DCHECK(!sink_);
DCHECK(!source_);
- sink_ = AudioDeviceFactory::NewOutputDevice();
- DCHECK(sink_);
-
// Use mono on all platforms but Windows for now.
// TODO(henrika): Tracking at http://crbug.com/166771.
media::ChannelLayout channel_layout = media::CHANNEL_LAYOUT_MONO;
@@ -208,8 +205,8 @@ bool WebRtcAudioRenderer::Initialize(WebRtcAudioRendererSource* source) {
source->SetRenderFormat(source_params);
// Configure the audio rendering client and start rendering.
+ sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_);
sink_->Initialize(sink_params, this);
- sink_->SetSourceRenderView(source_render_view_id_);
sink_->Start();
// User must call Play() before any audio can be heard.
diff --git a/content/renderer/media/webrtc_audio_renderer.h b/content/renderer/media/webrtc_audio_renderer.h
index af4bf38..eb1025684 100644
--- a/content/renderer/media/webrtc_audio_renderer.h
+++ b/content/renderer/media/webrtc_audio_renderer.h
@@ -14,9 +14,12 @@
#include "media/base/audio_renderer_sink.h"
#include "webkit/media/media_stream_audio_renderer.h"
+namespace media {
+class AudioOutputDevice;
+}
+
namespace content {
-class RendererAudioOutputDevice;
class WebRtcAudioRendererSource;
// This renderer handles calls from the pipeline and WebRtc ADM. It is used
@@ -71,7 +74,7 @@ class CONTENT_EXPORT WebRtcAudioRenderer
const int source_render_view_id_;
// The sink (destination) for rendered audio.
- scoped_refptr<RendererAudioOutputDevice> sink_;
+ scoped_refptr<media::AudioOutputDevice> sink_;
// Audio data source from the browser process.
WebRtcAudioRendererSource* source_;
diff --git a/content/renderer/media/webrtc_local_audio_renderer.cc b/content/renderer/media/webrtc_local_audio_renderer.cc
index cc5ba77..da68006 100644
--- a/content/renderer/media/webrtc_local_audio_renderer.cc
+++ b/content/renderer/media/webrtc_local_audio_renderer.cc
@@ -9,8 +9,8 @@
#include "base/message_loop_proxy.h"
#include "base/synchronization/lock.h"
#include "content/renderer/media/audio_device_factory.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/audio_bus.h"
namespace content {
@@ -158,12 +158,11 @@ void WebRtcLocalAudioRenderer::Start() {
source_params.sample_rate(),
source_params.bits_per_sample(),
2 * source_params.frames_per_buffer());
- sink_ = AudioDeviceFactory::NewOutputDevice();
+ sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_);
// TODO(henrika): we could utilize the unified audio here instead and do
// sink_->InitializeIO(sink_params, 2, callback_.get());
// It would then be possible to avoid using the WebRtcAudioCapturer.
sink_->Initialize(sink_params, this);
- sink_->SetSourceRenderView(source_render_view_id_);
// Start the capturer and local rendering. Note that, the capturer is owned
// by the WebRTC ADM and might already bee running.
diff --git a/content/renderer/media/webrtc_local_audio_renderer.h b/content/renderer/media/webrtc_local_audio_renderer.h
index 0bd310a..0bdb316 100644
--- a/content/renderer/media/webrtc_local_audio_renderer.h
+++ b/content/renderer/media/webrtc_local_audio_renderer.h
@@ -16,6 +16,7 @@
namespace media {
class AudioBus;
+class AudioOutputDevice;
class AudioParameters;
}
@@ -25,7 +26,6 @@ class AudioTrackInterface;
namespace content {
-class RendererAudioOutputDevice;
class WebRtcAudioCapturer;
// WebRtcLocalAudioRenderer is a webkit_media::MediaStreamAudioRenderer
@@ -105,7 +105,7 @@ class CONTENT_EXPORT WebRtcLocalAudioRenderer
const int source_render_view_id_;
// The sink (destination) for rendered audio.
- scoped_refptr<RendererAudioOutputDevice> sink_;
+ scoped_refptr<media::AudioOutputDevice> sink_;
// Used to DCHECK that we are called on the correct thread.
base::ThreadChecker thread_checker_;
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.cc b/content/renderer/pepper/pepper_platform_audio_input_impl.cc
index f71b642..76afa17 100644
--- a/content/renderer/pepper/pepper_platform_audio_input_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_input_impl.cc
@@ -9,7 +9,6 @@
#include "base/message_loop_proxy.h"
#include "build/build_config.h"
#include "content/common/child_process.h"
-#include "content/common/media/audio_messages.h"
#include "content/renderer/media/audio_input_message_filter.h"
#include "content/renderer/pepper/pepper_plugin_delegate_impl.h"
#include "content/renderer/render_thread_impl.h"
@@ -55,6 +54,10 @@ void PepperPlatformAudioInputImpl::StopCapture() {
void PepperPlatformAudioInputImpl::ShutDown() {
DCHECK(main_message_loop_proxy_->BelongsToCurrentThread());
+ // Make sure we don't call shutdown more than once.
+ if (!client_)
+ return;
+
// Called on the main thread to stop all audio callbacks. We must only change
// the client on the main thread, and the delegates from the I/O thread.
client_ = NULL;
@@ -80,9 +83,8 @@ void PepperPlatformAudioInputImpl::OnStreamCreated(
DCHECK_EQ(1, total_segments);
if (base::MessageLoopProxy::current() != main_message_loop_proxy_) {
- // No need to check |shutdown_called_| here. If shutdown has occurred,
- // |client_| will be NULL and the handles will be cleaned up on the main
- // thread.
+ // If shutdown has occurred, |client_| will be NULL and the handles will be
+ // cleaned up on the main thread.
main_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioInputImpl::OnStreamCreated, this,
@@ -107,7 +109,7 @@ void PepperPlatformAudioInputImpl::OnStateChanged(
}
void PepperPlatformAudioInputImpl::OnIPCClosed() {
- ipc_ = NULL;
+ ipc_.reset();
}
PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() {
@@ -116,19 +118,14 @@ PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() {
// Although these members should be accessed on a specific thread (either the
// main thread or the I/O thread), it should be fine to examine their value
// here.
- DCHECK_EQ(0, stream_id_);
+ DCHECK(!ipc_);
DCHECK(!client_);
DCHECK(label_.empty());
- DCHECK(shutdown_called_);
}
PepperPlatformAudioInputImpl::PepperPlatformAudioInputImpl()
: client_(NULL),
- stream_id_(0),
- render_view_id_(MSG_ROUTING_NONE),
- main_message_loop_proxy_(base::MessageLoopProxy::current()),
- shutdown_called_(false) {
- ipc_ = RenderThreadImpl::current()->audio_input_message_filter();
+ main_message_loop_proxy_(base::MessageLoopProxy::current()) {
}
bool PepperPlatformAudioInputImpl::Initialize(
@@ -142,8 +139,10 @@ bool PepperPlatformAudioInputImpl::Initialize(
if (!plugin_delegate || !client)
return false;
+ ipc_ = RenderThreadImpl::current()->audio_input_message_filter()->
+ CreateAudioInputIPC(plugin_delegate->GetRoutingID());
+
plugin_delegate_ = plugin_delegate;
- render_view_id_ = plugin_delegate_->GetRoutingID();
client_ = client;
params_.Reset(media::AudioParameters::AUDIO_PCM_LINEAR,
@@ -164,26 +163,19 @@ void PepperPlatformAudioInputImpl::InitializeOnIOThread(int session_id) {
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
BelongsToCurrentThread());
- if (shutdown_called_)
+ if (!ipc_)
return;
- // Make sure we don't call init more than once.
- DCHECK_EQ(0, stream_id_);
- stream_id_ = ipc_->AddDelegate(this);
- DCHECK_NE(0, stream_id_);
-
// We will be notified by OnStreamCreated().
- ipc_->CreateStream(stream_id_, session_id, params_, false, 1);
+ ipc_->CreateStream(this, session_id, params_, false, 1);
}
void PepperPlatformAudioInputImpl::StartCaptureOnIOThread() {
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
BelongsToCurrentThread());
- if (stream_id_) {
- ipc_->AssociateStreamWithConsumer(stream_id_, render_view_id_);
- ipc_->RecordStream(stream_id_);
- }
+ if (ipc_)
+ ipc_->RecordStream();
}
void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() {
@@ -191,24 +183,17 @@ void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() {
BelongsToCurrentThread());
// TODO(yzshen): We cannot re-start capturing if the stream is closed.
- if (stream_id_)
- ipc_->CloseStream(stream_id_);
+ if (ipc_) {
+ ipc_->CloseStream();
+ ipc_.reset();
+ }
}
void PepperPlatformAudioInputImpl::ShutDownOnIOThread() {
DCHECK(ChildProcess::current()->io_message_loop_proxy()->
BelongsToCurrentThread());
- // Make sure we don't call shutdown more than once.
- if (shutdown_called_)
- return;
- shutdown_called_ = true;
-
- if (stream_id_) {
- ipc_->CloseStream(stream_id_);
- ipc_->RemoveDelegate(stream_id_);
- stream_id_ = 0;
- }
+ StopCaptureOnIOThread();
main_message_loop_proxy_->PostTask(
FROM_HERE,
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.h b/content/renderer/pepper/pepper_platform_audio_input_impl.h
index 7d71347..0cfa92d 100644
--- a/content/renderer/pepper/pepper_platform_audio_input_impl.h
+++ b/content/renderer/pepper/pepper_platform_audio_input_impl.h
@@ -9,9 +9,9 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "content/renderer/media/audio_input_message_filter.h"
+#include "media/audio/audio_input_ipc.h"
#include "media/audio/audio_parameters.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
@@ -21,7 +21,6 @@ class AudioParameters;
namespace content {
-class AudioInputMessageFilter;
class PepperPluginDelegateImpl;
// PepperPlatformAudioInputImpl is operated on two threads: the main thread (the
@@ -93,15 +92,8 @@ class PepperPlatformAudioInputImpl
webkit::ppapi::PluginDelegate::PlatformAudioInputClient* client_;
// 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> 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.
- int32 stream_id_;
-
- // The render view into which the audio is sent.
- int render_view_id_;
+ // I/O THREAD.
+ scoped_ptr<media::AudioInputIPC> ipc_;
base::MessageLoopProxy* main_message_loop_proxy_;
@@ -112,10 +104,6 @@ class PepperPlatformAudioInputImpl
// THE MAIN THREAD.
std::string label_;
- // Whether ShutDownOnIOThread() has been called. THIS MUST ONLY BE ACCESSED ON
- // THE I/O THREAD.
- bool shutdown_called_;
-
// Initialized on the main thread and accessed on the I/O thread afterwards.
media::AudioParameters params_;
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.cc b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
index 90ec7eb..8b8c470 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.cc
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.cc
@@ -97,21 +97,19 @@ void PepperPlatformAudioOutputImpl::OnStreamCreated(
}
void PepperPlatformAudioOutputImpl::OnIPCClosed() {
- ipc_ = NULL;
+ ipc_.reset();
}
PepperPlatformAudioOutputImpl::~PepperPlatformAudioOutputImpl() {
// Make sure we have been shut down. Warning: this will usually happen on
// the I/O thread!
- DCHECK_EQ(0, stream_id_);
+ DCHECK(!ipc_);
DCHECK(!client_);
}
PepperPlatformAudioOutputImpl::PepperPlatformAudioOutputImpl()
: client_(NULL),
- stream_id_(0),
main_message_loop_proxy_(base::MessageLoopProxy::current()) {
- ipc_ = RenderThreadImpl::current()->audio_message_filter();
}
bool PepperPlatformAudioOutputImpl::Initialize(
@@ -122,11 +120,16 @@ bool PepperPlatformAudioOutputImpl::Initialize(
DCHECK(client);
client_ = client;
+ RenderThreadImpl* const render_thread = RenderThreadImpl::current();
+ ipc_ = render_thread->audio_message_filter()->
+ CreateAudioOutputIPC(source_render_view_id);
+ CHECK(ipc_);
+
media::AudioParameters::Format format;
const int kMaxFramesForLowLatency = 2047;
media::AudioHardwareConfig* hardware_config =
- RenderThreadImpl::current()->GetAudioHardwareConfig();
+ render_thread->GetAudioHardwareConfig();
const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
if (!cmd_line->HasSwitch(switches::kDisableAudioOutputResampler)) {
@@ -149,39 +152,42 @@ bool PepperPlatformAudioOutputImpl::Initialize(
ChildProcess::current()->io_message_loop()->PostTask(
FROM_HERE,
base::Bind(&PepperPlatformAudioOutputImpl::InitializeOnIOThread,
- this, params, source_render_view_id));
+ this, params));
return true;
}
void PepperPlatformAudioOutputImpl::InitializeOnIOThread(
- const media::AudioParameters& params, int source_render_view_id) {
- // Make sure we don't call init more than once.
- DCHECK_EQ(0, stream_id_);
- stream_id_ = ipc_->AddDelegate(this);
- DCHECK_NE(0, stream_id_);
-
- ipc_->CreateStream(stream_id_, params);
- ipc_->AssociateStreamWithProducer(stream_id_, source_render_view_id);
+ const media::AudioParameters& params) {
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->CreateStream(this, params);
}
void PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread() {
- if (stream_id_)
- ipc_->PlayStream(stream_id_);
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->PlayStream();
}
void PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread() {
- if (stream_id_)
- ipc_->PauseStream(stream_id_);
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+ if (ipc_)
+ ipc_->PauseStream();
}
void PepperPlatformAudioOutputImpl::ShutDownOnIOThread() {
+ DCHECK(ChildProcess::current()->io_message_loop_proxy()->
+ BelongsToCurrentThread());
+
// Make sure we don't call shutdown more than once.
- if (!stream_id_)
+ if (!ipc_)
return;
- ipc_->CloseStream(stream_id_);
- ipc_->RemoveDelegate(stream_id_);
- stream_id_ = 0;
+ ipc_->CloseStream();
+ ipc_.reset();
Release(); // Release for the delegate, balances out the reference taken in
// PepperPluginDelegateImpl::CreateAudio.
diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.h b/content/renderer/pepper/pepper_platform_audio_output_impl.h
index 0be7588..b8eb05d 100644
--- a/content/renderer/pepper/pepper_platform_audio_output_impl.h
+++ b/content/renderer/pepper/pepper_platform_audio_output_impl.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "media/audio/audio_output_ipc.h"
#include "webkit/plugins/ppapi/plugin_delegate.h"
@@ -20,8 +21,6 @@ class MessageLoopProxy;
namespace content {
-class AudioMessageFilter;
-
class PepperPlatformAudioOutputImpl
: public webkit::ppapi::PluginDelegate::PlatformAudioOutput,
public media::AudioOutputIPCDelegate,
@@ -63,8 +62,7 @@ class PepperPlatformAudioOutputImpl
webkit::ppapi::PluginDelegate::PlatformAudioOutputClient* client);
// I/O thread backends to above functions.
- void InitializeOnIOThread(const media::AudioParameters& params,
- int source_render_view_id);
+ void InitializeOnIOThread(const media::AudioParameters& params);
void StartPlaybackOnIOThread();
void StopPlaybackOnIOThread();
void ShutDownOnIOThread();
@@ -75,11 +73,7 @@ class PepperPlatformAudioOutputImpl
// 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> 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.
- int32 stream_id_;
+ scoped_ptr<media::AudioOutputIPC> ipc_;
base::MessageLoopProxy* main_message_loop_proxy_;
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 7a3133d..63c3164 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -90,7 +90,6 @@
#include "content/renderer/media/media_stream_dispatcher.h"
#include "content/renderer/media/media_stream_impl.h"
#include "content/renderer/media/render_media_log.h"
-#include "content/renderer/media/renderer_audio_output_device.h"
#include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
#include "content/renderer/media/rtc_peer_connection_handler.h"
#include "content/renderer/media/video_capture_impl_manager.h"
@@ -113,6 +112,7 @@
#include "content/renderer/web_ui_extension_data.h"
#include "content/renderer/webplugin_delegate_proxy.h"
#include "content/renderer/websharedworker_proxy.h"
+#include "media/audio/audio_output_device.h"
#include "media/base/audio_renderer_mixer_input.h"
#include "media/base/filter_collection.h"
#include "media/base/media_switches.h"
@@ -2723,13 +2723,10 @@ WebMediaPlayer* RenderViewImpl::createMediaPlayer(
CreateInput(routing_id_);
DVLOG(1) << "Using AudioRendererMixerManager-provided sink: " << sink;
} else {
- scoped_refptr<RendererAudioOutputDevice> device =
- AudioDeviceFactory::NewOutputDevice();
// The RenderView creating AudioRendererSink will be the source of
// the audio (WebMediaPlayer is always associated with a document in a
// frame at the time RenderAudioSourceProvider is instantiated).
- device->SetSourceRenderView(routing_id_);
- sink = device;
+ sink = AudioDeviceFactory::NewOutputDevice(routing_id_);
DVLOG(1) << "Using AudioDeviceFactory-provided sink: " << sink;
}
}