Index: content/renderer/pepper_plugin_delegate_impl.cc |
diff --git a/content/renderer/pepper_plugin_delegate_impl.cc b/content/renderer/pepper_plugin_delegate_impl.cc |
index 94bbaf0e4cce424d697c16076a095b7b1920c4a2..e1453e593c353d6e29ec0c626c0543b8a464d351 100644 |
--- a/content/renderer/pepper_plugin_delegate_impl.cc |
+++ b/content/renderer/pepper_plugin_delegate_impl.cc |
@@ -35,6 +35,7 @@ |
#include "content/renderer/gpu/gpu_channel_host.h" |
#include "content/renderer/gpu/renderer_gl_context.h" |
#include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" |
+#include "content/renderer/media/audio_input_message_filter.h" |
#include "content/renderer/media/audio_message_filter.h" |
#include "content/renderer/media/video_capture_impl_manager.h" |
#include "content/renderer/p2p/p2p_transport_impl.h" |
@@ -170,7 +171,7 @@ class PlatformAudioImpl |
public: |
PlatformAudioImpl() |
: client_(NULL), stream_id_(0), |
- main_message_loop_(MessageLoop::current()) { |
+ main_message_loop_proxy_(base::MessageLoopProxy::current()) { |
filter_ = RenderThreadImpl::current()->audio_message_filter(); |
} |
@@ -184,7 +185,7 @@ class PlatformAudioImpl |
// 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::PlatformAudio::Client* client); |
+ webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client); |
// PlatformAudio implementation (called on main thread). |
virtual bool StartPlayback(); |
@@ -216,7 +217,7 @@ class PlatformAudioImpl |
// The client to notify when the stream is created. THIS MUST ONLY BE |
// ACCESSED ON THE MAIN THREAD. |
- webkit::ppapi::PluginDelegate::PlatformAudio::Client* client_; |
+ 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. |
@@ -226,14 +227,14 @@ class PlatformAudioImpl |
// or else you could race with the initialize function which sets it. |
int32 stream_id_; |
- MessageLoop* main_message_loop_; |
+ 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::PlatformAudio::Client* client) { |
+ webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { |
DCHECK(client); |
// Make sure we don't call init more than once. |
@@ -324,18 +325,184 @@ void PlatformAudioImpl::OnLowLatencyCreated( |
#endif |
DCHECK(length); |
- if (MessageLoop::current() == main_message_loop_) { |
+ 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_->PostTask(FROM_HERE, |
+ main_message_loop_proxy_->PostTask(FROM_HERE, |
NewRunnableMethod(this, &PlatformAudioImpl::OnLowLatencyCreated, |
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(); |
+ virtual bool StopCapture(); |
+ virtual void ShutDown(); |
dmichael (off chromium)
2011/11/17 04:05:21
OVERRIDE?
|
+ |
+ private: |
+ // I/O thread backends to above functions. |
+ void InitializeOnIOThread(const AudioParameters& params); |
+ void StartCaptureOnIOThread(); |
+ void StopCaptureOnIOThread(); |
+ void ShutDownOnIOThread(); |
+ |
+ virtual void OnLowLatencyCreated(base::SharedMemoryHandle handle, |
+ base::SyncSocket::Handle socket_handle, |
+ uint32 length); |
+ |
+ virtual void OnVolume(double volume) {} |
+ |
+ virtual void OnStateChanged(AudioStreamState state) {} |
+ |
+ virtual void OnDeviceReady(int index) {} |
+ |
+ // 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, |
+ NewRunnableMethod(this, &PlatformAudioInputImpl::InitializeOnIOThread, |
+ params)); |
+ return true; |
+} |
+ |
+bool PlatformAudioInputImpl::StartCapture() { |
+ ChildProcess::current()->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ NewRunnableMethod(this, |
+ &PlatformAudioInputImpl::StartCaptureOnIOThread)); |
+ return true; |
+} |
+ |
+bool PlatformAudioInputImpl::StopCapture() { |
+ ChildProcess::current()->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ NewRunnableMethod(this, |
+ &PlatformAudioInputImpl::StopCaptureOnIOThread)); |
+ 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, true)); |
+} |
+ |
+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::OnLowLatencyCreated( |
+ 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, |
+ NewRunnableMethod(this, &PlatformAudioInputImpl::OnLowLatencyCreated, |
+ handle, socket_handle, length)); |
+ } |
+} |
+ |
class DispatcherDelegate : public ppapi::proxy::ProxyChannel::Delegate { |
public: |
virtual ~DispatcherDelegate() {} |
@@ -1087,8 +1254,9 @@ void PepperPluginDelegateImpl::SelectedFindResultChanged(int identifier, |
webkit::ppapi::PluginDelegate::PlatformAudio* |
PepperPluginDelegateImpl::CreateAudio( |
- uint32_t sample_rate, uint32_t sample_count, |
- webkit::ppapi::PluginDelegate::PlatformAudio::Client* client) { |
+ 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(). |
@@ -1098,6 +1266,21 @@ PepperPluginDelegateImpl::CreateAudio( |
} |
} |
+webkit::ppapi::PluginDelegate::PlatformAudioInput* |
+PepperPluginDelegateImpl::CreateAudioInput( |
+ uint32_t sample_rate, |
+ uint32_t sample_count, |
+ webkit::ppapi::PluginDelegate::PlatformAudioCommonClient* client) { |
+ scoped_refptr<PlatformAudioInputImpl> |
+ audio_input(new PlatformAudioInputImpl()); |
+ if (audio_input->Initialize(sample_rate, sample_count, client)) { |
+ // Balanced by Release invoked in |
+ // PlatformAudioInputImpl::ShutDownOnIOThread(). |
+ return audio_input.release(); |
+ } |
+ return NULL; |
+} |
+ |
// If a broker has not already been created for this plugin, creates one. |
webkit::ppapi::PluginDelegate::PpapiBroker* |
PepperPluginDelegateImpl::ConnectToPpapiBroker( |