diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-25 22:26:11 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-25 22:26:11 +0000 |
commit | 60c331a16cba4f5347f77df8d5e3907bc3f24ae0 (patch) | |
tree | da8d0eb8e23d24b4d05cf310114e77cfa0f26600 /content/renderer/pepper | |
parent | 7d018f7ff67d4f2febddaac5c98cfd76a79d58fd (diff) | |
download | chromium_src-60c331a16cba4f5347f77df8d5e3907bc3f24ae0.zip chromium_src-60c331a16cba4f5347f77df8d5e3907bc3f24ae0.tar.gz chromium_src-60c331a16cba4f5347f77df8d5e3907bc3f24ae0.tar.bz2 |
Split out the pepper audio delegates.
This moves the audio input and output delegates into their own files.
BUG=
TEST=
Review URL: https://chromiumcodereview.appspot.com/9430034
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@123671 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/pepper')
6 files changed, 440 insertions, 350 deletions
diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.cc b/content/renderer/pepper/pepper_platform_audio_input_impl.cc new file mode 100644 index 0000000..3c3cbe6 --- /dev/null +++ b/content/renderer/pepper/pepper_platform_audio_input_impl.cc @@ -0,0 +1,140 @@ +// 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/pepper/pepper_platform_audio_input_impl.h" + +#include "base/bind.h" +#include "base/logging.h" +#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/render_thread_impl.h" +#include "media/audio/audio_manager_base.h" + +PepperPlatformAudioInputImpl::PepperPlatformAudioInputImpl() + : client_(NULL), + stream_id_(0), + main_message_loop_proxy_(base::MessageLoopProxy::current()) { + filter_ = RenderThreadImpl::current()->audio_input_message_filter(); +} + +PepperPlatformAudioInputImpl::~PepperPlatformAudioInputImpl() { + // Make sure we have been shut down. Warning: this will usually happen on + // the I/O thread! + DCHECK_EQ(0, stream_id_); + DCHECK(!client_); +} + +bool PepperPlatformAudioInputImpl::Initialize( + uint32_t sample_rate, + uint32_t sample_count, + webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { + DCHECK(client); + // Make sure we don't call init more than once. + DCHECK_EQ(0, stream_id_); + + client_ = client; + + AudioParameters params; + params.format = AudioParameters::AUDIO_PCM_LINEAR; + params.channels = 1; + params.sample_rate = sample_rate; + params.bits_per_sample = 16; + params.samples_per_packet = sample_count; + + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioInputImpl::InitializeOnIOThread, + this, params)); + return true; +} + +bool PepperPlatformAudioInputImpl::StartCapture() { + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioInputImpl::StartCaptureOnIOThread, this)); + return true; +} + +bool PepperPlatformAudioInputImpl::StopCapture() { + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioInputImpl::StopCaptureOnIOThread, this)); + return true; +} + +void PepperPlatformAudioInputImpl::ShutDown() { + // 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; + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioInputImpl::ShutDownOnIOThread, this)); +} + +void PepperPlatformAudioInputImpl::InitializeOnIOThread( + const AudioParameters& params) { + stream_id_ = filter_->AddDelegate(this); + filter_->Send(new AudioInputHostMsg_CreateStream( + stream_id_, params, AudioManagerBase::kDefaultDeviceId)); +} + +void PepperPlatformAudioInputImpl::StartCaptureOnIOThread() { + if (stream_id_) + filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_)); +} + +void PepperPlatformAudioInputImpl::StopCaptureOnIOThread() { + if (stream_id_) + filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_)); +} + +void PepperPlatformAudioInputImpl::ShutDownOnIOThread() { + // Make sure we don't call shutdown more than once. + if (!stream_id_) + return; + + filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_)); + filter_->RemoveDelegate(stream_id_); + stream_id_ = 0; + + Release(); // Release for the delegate, balances out the reference taken in + // PepperPluginDelegateImpl::CreateAudioInput. +} + +void PepperPlatformAudioInputImpl::OnStreamCreated( + base::SharedMemoryHandle handle, + base::SyncSocket::Handle socket_handle, + uint32 length) { +#if defined(OS_WIN) + DCHECK(handle); + DCHECK(socket_handle); +#else + DCHECK_NE(-1, handle.fd); + DCHECK_NE(-1, socket_handle); +#endif + DCHECK(length); + + if (base::MessageLoopProxy::current() == main_message_loop_proxy_) { + // Must dereference the client only on the main thread. Shutdown may have + // occurred while the request was in-flight, so we need to NULL check. + if (client_) + client_->StreamCreated(handle, length, socket_handle); + } else { + main_message_loop_proxy_->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioInputImpl::OnStreamCreated, this, + handle, socket_handle, length)); + } +} + +void PepperPlatformAudioInputImpl::OnVolume(double volume) { +} + +void PepperPlatformAudioInputImpl::OnStateChanged(AudioStreamState state) { +} + +void PepperPlatformAudioInputImpl::OnDeviceReady(const std::string&) { +} diff --git a/content/renderer/pepper/pepper_platform_audio_input_impl.h b/content/renderer/pepper/pepper_platform_audio_input_impl.h new file mode 100644 index 0000000..a4f48ea --- /dev/null +++ b/content/renderer/pepper/pepper_platform_audio_input_impl.h @@ -0,0 +1,68 @@ +// 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_PEPPER_PEPPER_PLATFORM_AUDIO_INPUT_IMPL_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_INPUT_IMPL_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/renderer/media/audio_input_message_filter.h" +#include "webkit/plugins/ppapi/plugin_delegate.h" + +struct AudioParameters; + +class PepperPlatformAudioInputImpl + : public webkit::ppapi::PluginDelegate::PlatformAudioInput, + public AudioInputMessageFilter::Delegate, + public base::RefCountedThreadSafe<PepperPlatformAudioInputImpl> { + public: + PepperPlatformAudioInputImpl(); + virtual ~PepperPlatformAudioInputImpl(); + + // Initialize this audio context. StreamCreated() will be called when the + // stream is created. + bool Initialize( + uint32_t sample_rate, + uint32_t sample_count, + webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client); + + // PlatformAudioInput implementation (called on main thread). + virtual bool StartCapture() OVERRIDE; + virtual bool StopCapture() OVERRIDE; + virtual void ShutDown() OVERRIDE; + + private: + // I/O thread backends to above functions. + void InitializeOnIOThread(const AudioParameters& params); + void StartCaptureOnIOThread(); + void StopCaptureOnIOThread(); + void ShutDownOnIOThread(); + + // AudioInputMessageFilter::Delegate. + virtual void OnStreamCreated(base::SharedMemoryHandle handle, + base::SyncSocket::Handle socket_handle, + uint32 length) OVERRIDE; + virtual void OnVolume(double volume) OVERRIDE; + virtual void OnStateChanged(AudioStreamState state) OVERRIDE; + virtual void OnDeviceReady(const std::string&) OVERRIDE; + + // The client to notify when the stream is created. THIS MUST ONLY BE + // ACCESSED ON THE MAIN THREAD. + webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client_; + + // MessageFilter 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_; + + // 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_; + + base::MessageLoopProxy* main_message_loop_proxy_; + + DISALLOW_COPY_AND_ASSIGN(PepperPlatformAudioInputImpl); +}; + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_INPUT_IMPL_H_ diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.cc b/content/renderer/pepper/pepper_platform_audio_output_impl.cc new file mode 100644 index 0000000..1b3a02e --- /dev/null +++ b/content/renderer/pepper/pepper_platform_audio_output_impl.cc @@ -0,0 +1,148 @@ +// 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/pepper/pepper_platform_audio_output_impl.h" + +#include "base/bind.h" +#include "base/logging.h" +#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_hardware.h" +#include "content/renderer/render_thread_impl.h" + +PepperPlatformAudioOutputImpl::PepperPlatformAudioOutputImpl() + : client_(NULL), + stream_id_(0), + main_message_loop_proxy_(base::MessageLoopProxy::current()) { + filter_ = RenderThreadImpl::current()->audio_message_filter(); +} + +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(!client_); +} + +bool PepperPlatformAudioOutputImpl::Initialize( + uint32_t sample_rate, + uint32_t sample_count, + webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { + DCHECK(client); + // Make sure we don't call init more than once. + DCHECK_EQ(0, stream_id_); + + client_ = client; + + AudioParameters params; + const uint32_t kMaxSampleCountForLowLatency = 2048; + // Use the low latency back end if the client request is compatible, and + // the sample count is low enough to justify using AUDIO_PCM_LOW_LATENCY. + if (sample_rate == audio_hardware::GetOutputSampleRate() && + sample_count <= kMaxSampleCountForLowLatency && + sample_count % audio_hardware::GetOutputBufferSize() == 0) + params.format = AudioParameters::AUDIO_PCM_LOW_LATENCY; + else + params.format = AudioParameters::AUDIO_PCM_LINEAR; + params.channels = 2; + params.sample_rate = sample_rate; + params.bits_per_sample = 16; + params.samples_per_packet = sample_count; + + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioOutputImpl::InitializeOnIOThread, + this, params)); + return true; +} + +bool PepperPlatformAudioOutputImpl::StartPlayback() { + if (filter_) { + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread, + this)); + return true; + } + return false; +} + +bool PepperPlatformAudioOutputImpl::StopPlayback() { + if (filter_) { + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread, + this)); + return true; + } + return false; +} + +void PepperPlatformAudioOutputImpl::ShutDown() { + // 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; + ChildProcess::current()->io_message_loop()->PostTask( + FROM_HERE, + base::Bind(&PepperPlatformAudioOutputImpl::ShutDownOnIOThread, this)); +} + +void PepperPlatformAudioOutputImpl::InitializeOnIOThread( + const AudioParameters& params) { + stream_id_ = filter_->AddDelegate(this); + filter_->Send(new AudioHostMsg_CreateStream(stream_id_, params)); +} + +void PepperPlatformAudioOutputImpl::StartPlaybackOnIOThread() { + if (stream_id_) + filter_->Send(new AudioHostMsg_PlayStream(stream_id_)); +} + +void PepperPlatformAudioOutputImpl::StopPlaybackOnIOThread() { + if (stream_id_) + filter_->Send(new AudioHostMsg_PauseStream(stream_id_)); +} + +void PepperPlatformAudioOutputImpl::ShutDownOnIOThread() { + // Make sure we don't call shutdown more than once. + if (!stream_id_) + return; + + filter_->Send(new AudioHostMsg_CloseStream(stream_id_)); + filter_->RemoveDelegate(stream_id_); + stream_id_ = 0; + + Release(); // Release for the delegate, balances out the reference taken in + // PepperPluginDelegateImpl::CreateAudio. +} + +void PepperPlatformAudioOutputImpl::OnStateChanged(AudioStreamState state) { +} + +void PepperPlatformAudioOutputImpl::OnStreamCreated( + base::SharedMemoryHandle handle, + base::SyncSocket::Handle socket_handle, + uint32 length) { +#if defined(OS_WIN) + DCHECK(handle); + DCHECK(socket_handle); +#else + DCHECK_NE(-1, handle.fd); + DCHECK_NE(-1, socket_handle); +#endif + DCHECK(length); + + if (base::MessageLoopProxy::current() == main_message_loop_proxy_) { + // Must dereference the client only on the main thread. Shutdown may have + // occurred while the request was in-flight, so we need to NULL check. + if (client_) + client_->StreamCreated(handle, length, socket_handle); + } else { + main_message_loop_proxy_->PostTask(FROM_HERE, + base::Bind(&PepperPlatformAudioOutputImpl::OnStreamCreated, this, + handle, socket_handle, length)); + } +} diff --git a/content/renderer/pepper/pepper_platform_audio_output_impl.h b/content/renderer/pepper/pepper_platform_audio_output_impl.h new file mode 100644 index 0000000..1615d25 --- /dev/null +++ b/content/renderer/pepper/pepper_platform_audio_output_impl.h @@ -0,0 +1,69 @@ +// 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_PEPPER_PEPPER_PLATFORM_AUDIO_OUTPUT_IMPL_H_ +#define CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_OUTPUT_IMPL_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "content/renderer/media/audio_message_filter.h" +#include "webkit/plugins/ppapi/plugin_delegate.h" + +struct AudioParameters; + +namespace base { +class MessageLoopProxy; +} + +class PepperPlatformAudioOutputImpl + : public webkit::ppapi::PluginDelegate::PlatformAudioOutput, + public AudioMessageFilter::Delegate, + public base::RefCountedThreadSafe<PepperPlatformAudioOutputImpl> { + public: + PepperPlatformAudioOutputImpl(); + virtual ~PepperPlatformAudioOutputImpl(); + + // Initialize this audio context. StreamCreated() will be called when the + // stream is created. + bool Initialize( + uint32_t sample_rate, + uint32_t sample_count, + webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client); + + // PlatformAudioOutput implementation (called on main thread). + virtual bool StartPlayback() OVERRIDE; + virtual bool StopPlayback() OVERRIDE; + virtual void ShutDown() OVERRIDE; + + private: + // I/O thread backends to above functions. + void InitializeOnIOThread(const AudioParameters& params); + void StartPlaybackOnIOThread(); + void StopPlaybackOnIOThread(); + void ShutDownOnIOThread(); + + // AudioMessageFilter::Delegate. + virtual void OnStateChanged(AudioStreamState state) OVERRIDE; + virtual void OnStreamCreated(base::SharedMemoryHandle handle, + base::SyncSocket::Handle socket_handle, + uint32 length) OVERRIDE; + + // The client to notify when the stream is created. THIS MUST ONLY BE + // ACCESSED ON THE MAIN THREAD. + webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client_; + + // MessageFilter 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_; + + // 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_; + + base::MessageLoopProxy* main_message_loop_proxy_; + + DISALLOW_COPY_AND_ASSIGN(PepperPlatformAudioOutputImpl); +}; + +#endif // CONTENT_RENDERER_PEPPER_PEPPER_PLATFORM_AUDIO_OUTPUT_IMPL_H_ diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc index 5dc90f6..e298387 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc @@ -24,7 +24,6 @@ #include "content/common/file_system_messages.h" #include "content/common/gpu/client/content_gl_context.h" #include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h" -#include "content/common/media/audio_messages.h" #include "content/common/pepper_file_messages.h" #include "content/common/pepper_plugin_registry.h" #include "content/common/pepper_messages.h" @@ -36,12 +35,12 @@ #include "content/public/renderer/content_renderer_client.h" #include "content/renderer/gamepad_shared_memory_reader.h" #include "content/renderer/media/audio_hardware.h" -#include "content/renderer/media/audio_input_message_filter.h" -#include "content/renderer/media/audio_message_filter.h" #include "content/renderer/media/media_stream_dispatcher.h" #include "content/renderer/media/media_stream_dispatcher_eventhandler.h" #include "content/renderer/media/pepper_platform_video_decoder_impl.h" #include "content/renderer/p2p/p2p_transport_impl.h" +#include "content/renderer/pepper/pepper_platform_audio_input_impl.h" +#include "content/renderer/pepper/pepper_platform_audio_output_impl.h" #include "content/renderer/pepper/pepper_platform_context_3d_impl.h" #include "content/renderer/pepper/pepper_platform_video_capture_impl.h" #include "content/renderer/render_thread_impl.h" @@ -50,7 +49,6 @@ #include "content/renderer/renderer_clipboard_client.h" #include "content/renderer/webplugin_delegate_proxy.h" #include "ipc/ipc_channel_handle.h" -#include "media/audio/audio_manager_base.h" #include "media/video/capture/video_capture_proxy.h" #include "ppapi/c/dev/pp_video_dev.h" #include "ppapi/c/pp_errors.h" @@ -165,340 +163,6 @@ class PlatformImage2DImpl DISALLOW_COPY_AND_ASSIGN(PlatformImage2DImpl); }; -class PlatformAudioImpl - : public webkit::ppapi::PluginDelegate::PlatformAudio, - public AudioMessageFilter::Delegate, - public base::RefCountedThreadSafe<PlatformAudioImpl> { - public: - PlatformAudioImpl() - : client_(NULL), stream_id_(0), - main_message_loop_proxy_(base::MessageLoopProxy::current()) { - filter_ = RenderThreadImpl::current()->audio_message_filter(); - } - - virtual ~PlatformAudioImpl() { - // Make sure we have been shut down. Warning: this will usually happen on - // the I/O thread! - DCHECK_EQ(0, stream_id_); - DCHECK(!client_); - } - - // Initialize this audio context. StreamCreated() will be called when the - // stream is created. - bool Initialize(uint32_t sample_rate, uint32_t sample_count, - webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client); - - // PlatformAudio implementation (called on main thread). - virtual bool StartPlayback() OVERRIDE; - virtual bool StopPlayback() OVERRIDE; - virtual void ShutDown() OVERRIDE; - - private: - // I/O thread backends to above functions. - void InitializeOnIOThread(const AudioParameters& params); - void StartPlaybackOnIOThread(); - void StopPlaybackOnIOThread(); - void ShutDownOnIOThread(); - - virtual void OnStateChanged(AudioStreamState state) OVERRIDE {} - - virtual void OnStreamCreated(base::SharedMemoryHandle handle, - base::SyncSocket::Handle socket_handle, - uint32 length) OVERRIDE; - - // The client to notify when the stream is created. THIS MUST ONLY BE - // ACCESSED ON THE MAIN THREAD. - webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client_; - - // MessageFilter 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_; - - // 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_; - - base::MessageLoopProxy* main_message_loop_proxy_; - - DISALLOW_COPY_AND_ASSIGN(PlatformAudioImpl); -}; - -bool PlatformAudioImpl::Initialize( - uint32_t sample_rate, uint32_t sample_count, - webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { - DCHECK(client); - // Make sure we don't call init more than once. - DCHECK_EQ(0, stream_id_); - - client_ = client; - - AudioParameters params; - const uint32_t kMaxSampleCountForLowLatency = 2048; - // Use the low latency back end if the client request is compatible, and - // the sample count is low enough to justify using AUDIO_PCM_LOW_LATENCY. - if (sample_rate == audio_hardware::GetOutputSampleRate() && - sample_count <= kMaxSampleCountForLowLatency && - sample_count % audio_hardware::GetOutputBufferSize() == 0) - params.format = AudioParameters::AUDIO_PCM_LOW_LATENCY; - else - params.format = AudioParameters::AUDIO_PCM_LINEAR; - params.channels = 2; - params.sample_rate = sample_rate; - params.bits_per_sample = 16; - params.samples_per_packet = sample_count; - - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioImpl::InitializeOnIOThread, this, params)); - return true; -} - -bool PlatformAudioImpl::StartPlayback() { - if (filter_) { - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioImpl::StartPlaybackOnIOThread, this)); - return true; - } - return false; -} - -bool PlatformAudioImpl::StopPlayback() { - if (filter_) { - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioImpl::StopPlaybackOnIOThread, this)); - return true; - } - return false; -} - -void PlatformAudioImpl::ShutDown() { - // 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; - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioImpl::ShutDownOnIOThread, this)); -} - -void PlatformAudioImpl::InitializeOnIOThread(const AudioParameters& params) { - stream_id_ = filter_->AddDelegate(this); - filter_->Send(new AudioHostMsg_CreateStream(stream_id_, params)); -} - -void PlatformAudioImpl::StartPlaybackOnIOThread() { - if (stream_id_) - filter_->Send(new AudioHostMsg_PlayStream(stream_id_)); -} - -void PlatformAudioImpl::StopPlaybackOnIOThread() { - if (stream_id_) - filter_->Send(new AudioHostMsg_PauseStream(stream_id_)); -} - -void PlatformAudioImpl::ShutDownOnIOThread() { - // Make sure we don't call shutdown more than once. - if (!stream_id_) - return; - - filter_->Send(new AudioHostMsg_CloseStream(stream_id_)); - filter_->RemoveDelegate(stream_id_); - stream_id_ = 0; - - Release(); // Release for the delegate, balances out the reference taken in - // PepperPluginDelegateImpl::CreateAudio. -} - -void PlatformAudioImpl::OnStreamCreated( - base::SharedMemoryHandle handle, base::SyncSocket::Handle socket_handle, - uint32 length) { -#if defined(OS_WIN) - DCHECK(handle); - DCHECK(socket_handle); -#else - DCHECK_NE(-1, handle.fd); - DCHECK_NE(-1, socket_handle); -#endif - DCHECK(length); - - if (base::MessageLoopProxy::current() == main_message_loop_proxy_) { - // Must dereference the client only on the main thread. Shutdown may have - // occurred while the request was in-flight, so we need to NULL check. - if (client_) - client_->StreamCreated(handle, length, socket_handle); - } else { - main_message_loop_proxy_->PostTask(FROM_HERE, - base::Bind(&PlatformAudioImpl::OnStreamCreated, this, handle, - socket_handle, length)); - } -} - -class PlatformAudioInputImpl - : public webkit::ppapi::PluginDelegate::PlatformAudioInput, - public AudioInputMessageFilter::Delegate, - public base::RefCountedThreadSafe<PlatformAudioInputImpl> { - public: - PlatformAudioInputImpl() - : client_(NULL), stream_id_(0), - main_message_loop_proxy_(base::MessageLoopProxy::current()) { - filter_ = RenderThreadImpl::current()->audio_input_message_filter(); - } - - virtual ~PlatformAudioInputImpl() { - // Make sure we have been shut down. Warning: this will usually happen on - // the I/O thread! - DCHECK_EQ(0, stream_id_); - DCHECK(!client_); - } - - // Initialize this audio context. StreamCreated() will be called when the - // stream is created. - bool Initialize( - uint32_t sample_rate, uint32_t sample_count, - webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client); - - // PlatformAudio implementation (called on main thread). - virtual bool StartCapture() OVERRIDE; - virtual bool StopCapture() OVERRIDE; - virtual void ShutDown() OVERRIDE; - - private: - // I/O thread backends to above functions. - void InitializeOnIOThread(const AudioParameters& params); - void StartCaptureOnIOThread(); - void StopCaptureOnIOThread(); - void ShutDownOnIOThread(); - - virtual void OnStreamCreated(base::SharedMemoryHandle handle, - base::SyncSocket::Handle socket_handle, - uint32 length) OVERRIDE; - - virtual void OnVolume(double volume) OVERRIDE {} - - virtual void OnStateChanged(AudioStreamState state) OVERRIDE {} - - virtual void OnDeviceReady(const std::string&) OVERRIDE {} - - // The client to notify when the stream is created. THIS MUST ONLY BE - // ACCESSED ON THE MAIN THREAD. - webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client_; - - // MessageFilter 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_; - - // 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_; - - base::MessageLoopProxy* main_message_loop_proxy_; - - DISALLOW_COPY_AND_ASSIGN(PlatformAudioInputImpl); -}; - -bool PlatformAudioInputImpl::Initialize( - uint32_t sample_rate, uint32_t sample_count, - webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { - DCHECK(client); - // Make sure we don't call init more than once. - DCHECK_EQ(0, stream_id_); - - client_ = client; - - AudioParameters params; - params.format = AudioParameters::AUDIO_PCM_LINEAR; - params.channels = 1; - params.sample_rate = sample_rate; - params.bits_per_sample = 16; - params.samples_per_packet = sample_count; - - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioInputImpl::InitializeOnIOThread, this, params)); - return true; -} - -bool PlatformAudioInputImpl::StartCapture() { - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioInputImpl::StartCaptureOnIOThread, this)); - return true; -} - -bool PlatformAudioInputImpl::StopCapture() { - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioInputImpl::StopCaptureOnIOThread, this)); - return true; -} - -void PlatformAudioInputImpl::ShutDown() { - // 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; - ChildProcess::current()->io_message_loop()->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioInputImpl::ShutDownOnIOThread, this)); -} - -void PlatformAudioInputImpl::InitializeOnIOThread( - const AudioParameters& params) { - stream_id_ = filter_->AddDelegate(this); - filter_->Send(new AudioInputHostMsg_CreateStream( - stream_id_, params, AudioManagerBase::kDefaultDeviceId)); -} - -void PlatformAudioInputImpl::StartCaptureOnIOThread() { - if (stream_id_) - filter_->Send(new AudioInputHostMsg_RecordStream(stream_id_)); -} - -void PlatformAudioInputImpl::StopCaptureOnIOThread() { - if (stream_id_) - filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_)); -} - -void PlatformAudioInputImpl::ShutDownOnIOThread() { - // Make sure we don't call shutdown more than once. - if (!stream_id_) - return; - - filter_->Send(new AudioInputHostMsg_CloseStream(stream_id_)); - filter_->RemoveDelegate(stream_id_); - stream_id_ = 0; - - Release(); // Release for the delegate, balances out the reference taken in - // PepperPluginDelegateImpl::CreateAudioInput. -} - -void PlatformAudioInputImpl::OnStreamCreated( - base::SharedMemoryHandle handle, - base::SyncSocket::Handle socket_handle, - uint32 length) { - -#if defined(OS_WIN) - DCHECK(handle); - DCHECK(socket_handle); -#else - DCHECK_NE(-1, handle.fd); - DCHECK_NE(-1, socket_handle); -#endif - DCHECK(length); - - if (base::MessageLoopProxy::current() == main_message_loop_proxy_) { - // Must dereference the client only on the main thread. Shutdown may have - // occurred while the request was in-flight, so we need to NULL check. - if (client_) - client_->StreamCreated(handle, length, socket_handle); - } else { - main_message_loop_proxy_->PostTask( - FROM_HERE, - base::Bind(&PlatformAudioInputImpl::OnStreamCreated, this, - handle, socket_handle, length)); - } -} - class DispatcherDelegate : public ppapi::proxy::ProxyChannel::Delegate { public: virtual ~DispatcherDelegate() {} @@ -1378,18 +1042,19 @@ uint32_t PepperPluginDelegateImpl::GetAudioHardwareOutputBufferSize() { return static_cast<uint32_t>(audio_hardware::GetOutputBufferSize()); } -webkit::ppapi::PluginDelegate::PlatformAudio* -PepperPluginDelegateImpl::CreateAudio( +webkit::ppapi::PluginDelegate::PlatformAudioOutput* +PepperPluginDelegateImpl::CreateAudioOutput( uint32_t sample_rate, uint32_t sample_count, webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { - scoped_refptr<PlatformAudioImpl> audio(new PlatformAudioImpl()); - if (audio->Initialize(sample_rate, sample_count, client)) { - // Balanced by Release invoked in PlatformAudioImpl::ShutDownOnIOThread(). - return audio.release(); - } else { - return NULL; + scoped_refptr<PepperPlatformAudioOutputImpl> audio_output( + new PepperPlatformAudioOutputImpl); + if (audio_output->Initialize(sample_rate, sample_count, client)) { + // Balanced by Release invoked in + // PepperPlatformAudioOutput::ShutDownOnIOThread(). + return audio_output.release(); } + return NULL; } webkit::ppapi::PluginDelegate::PlatformAudioInput* @@ -1397,11 +1062,11 @@ PepperPluginDelegateImpl::CreateAudioInput( uint32_t sample_rate, uint32_t sample_count, webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { - scoped_refptr<PlatformAudioInputImpl> - audio_input(new PlatformAudioInputImpl()); + scoped_refptr<PepperPlatformAudioInputImpl> audio_input( + new PepperPlatformAudioInputImpl); if (audio_input->Initialize(sample_rate, sample_count, client)) { // Balanced by Release invoked in - // PlatformAudioInputImpl::ShutDownOnIOThread(). + // PepperPlatformAudioInput::ShutDownOnIOThread(). return audio_input.release(); } return NULL; diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h index c82e869..9faca92 100644 --- a/content/renderer/pepper/pepper_plugin_delegate_impl.h +++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h @@ -222,7 +222,7 @@ class PepperPluginDelegateImpl virtual SkBitmap* GetSadPluginBitmap() OVERRIDE; virtual uint32_t GetAudioHardwareOutputSampleRate() OVERRIDE; virtual uint32_t GetAudioHardwareOutputBufferSize() OVERRIDE; - virtual PlatformAudio* CreateAudio( + virtual PlatformAudioOutput* CreateAudioOutput( uint32_t sample_rate, uint32_t sample_count, PlatformAudioCommonClient* client) OVERRIDE; |