Index: content/renderer/pepper_plugin_delegate_impl.cc |
=================================================================== |
--- content/renderer/pepper_plugin_delegate_impl.cc (revision 103964) |
+++ content/renderer/pepper_plugin_delegate_impl.cc (working copy) |
@@ -35,6 +35,7 @@ |
#include "content/renderer/gpu/renderer_gl_context.h" |
#include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" |
#include "content/renderer/media/audio_message_filter.h" |
+#include "content/renderer/media/audio_input_message_filter.h" |
#include "content/renderer/media/video_capture_impl_manager.h" |
#include "content/renderer/p2p/p2p_transport_impl.h" |
#include "content/renderer/pepper_platform_context_3d_impl.h" |
@@ -335,6 +336,179 @@ |
} |
} |
+class PlatformAudioInputImpl |
+ : public webkit::ppapi::PluginDelegate::PlatformAudioInput, |
+ public AudioInputMessageFilter::Delegate, |
+ public base::RefCountedThreadSafe<PlatformAudioInputImpl> { |
+ public: |
+ PlatformAudioInputImpl() |
+ : client_(NULL), stream_id_(0), |
+ main_message_loop_(MessageLoop::current()) { |
+ filter_ = RenderThread::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( |
+ webkit::ppapi::PluginDelegate::PlatformAudioInput::Client* client); |
brettw
2011/10/12 19:33:13
Should be indented only 4 spaces
|
+ |
+ // PlatformAudio implementation (called on main thread). |
+ virtual bool StartCapture(); |
+ virtual bool StopCapture(); |
+ virtual void ShutDown(); |
+ |
+ 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) {} |
+ |
+ //TODO(peterb) need to add |
brettw
2011/10/12 20:39:34
This should be cleaned up or clarified.
|
+ 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::PlatformAudioInput::Client* 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_; |
+ |
+ MessageLoop* main_message_loop_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(PlatformAudioInputImpl); |
+}; |
+ |
+bool PlatformAudioInputImpl::Initialize( |
+ webkit::ppapi::PluginDelegate::PlatformAudioInput::Client* client) { |
+ DCHECK(client); |
+ // Make sure we don't call init more than once. |
+ DCHECK_EQ(0, stream_id_); |
+ |
+ client_ = client; |
+ |
+//TODO(peterb) figure out the params to use |
brettw
2011/10/12 20:39:34
Did you figure out the proper params? Can this be
|
+ AudioParameters params; |
+ params.format = AudioParameters::AUDIO_PCM_LINEAR; |
+ params.channels = 2; |
+//peterb params.sample_rate = sample_rate; |
+ params.sample_rate = 44100; //peterb PP_AUDIOSAMPLERATE_44100; |
+ params.bits_per_sample = 16; |
+//peterb params.samples_per_packet = sample_count; |
+ params.samples_per_packet = 2048; |
+ |
+ ChildProcess::current()->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ NewRunnableMethod(this, &PlatformAudioInputImpl::InitializeOnIOThread, |
+ params)); |
+ return true; |
+} |
+ |
+bool PlatformAudioInputImpl::StartCapture() { |
+ if (filter_) { |
brettw
2011/10/12 20:39:34
I don't think this can be NULL. I notice the exist
|
+ ChildProcess::current()->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ NewRunnableMethod(this, |
+ &PlatformAudioInputImpl::StartCaptureOnIOThread)); |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+bool PlatformAudioInputImpl::StopCapture() { |
+ if (filter_) { |
+ ChildProcess::current()->io_message_loop()->PostTask( |
+ FROM_HERE, |
+ NewRunnableMethod(this, |
+ &PlatformAudioInputImpl::StopCaptureOnIOThread)); |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+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, |
+ NewRunnableMethod(this, &PlatformAudioInputImpl::ShutDownOnIOThread)); |
+} |
+ |
+void PlatformAudioInputImpl::InitializeOnIOThread( |
+ const AudioParameters& params) { |
brettw
2011/10/12 19:33:13
Only 4 space indent.
|
+ 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, |
brettw
2011/10/12 20:39:34
Style nit: I usually try to put each param on a se
|
+ 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 (MessageLoop::current() == main_message_loop_) { |
+ // 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, |
+ NewRunnableMethod(this, &PlatformAudioInputImpl::OnLowLatencyCreated, |
+ handle, socket_handle, length)); |
+ } |
+} |
+ |
class DispatcherDelegate : public ppapi::proxy::ProxyChannel::Delegate { |
public: |
virtual ~DispatcherDelegate() {} |
@@ -986,6 +1160,22 @@ |
} |
} |
+webkit::ppapi::PluginDelegate::PlatformAudioInput* |
+PepperPluginDelegateImpl::CreateAudioInput( |
+ webkit::ppapi::PluginDelegate::PlatformAudioInput::Client* client) { |
+ scoped_refptr<PlatformAudioInputImpl> |
+ audio_input(new PlatformAudioInputImpl()); |
brettw
2011/10/12 19:33:13
4 space indent.
|
+ if (audio_input->Initialize(client)) { |
+ // Balanced by Release invoked in |
+ // PlatformAudioInputImpl::ShutDownOnIOThread(). |
+ return audio_input.release(); |
+ } else { |
brettw
2011/10/12 20:39:34
I'd just delete this else condition and use the re
|
+ return NULL; |
+ } |
+ return NULL; |
+} |
+ |
+ |
// If a broker has not already been created for this plugin, creates one. |
webkit::ppapi::PluginDelegate::PpapiBroker* |
PepperPluginDelegateImpl::ConnectToPpapiBroker( |