Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1966)

Unified Diff: content/renderer/pepper_plugin_delegate_impl.cc

Issue 8574029: Microphone support for Pepper Flash. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: refactor, part 1 Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/renderer/pepper_plugin_delegate_impl.h ('k') | ppapi/api/dev/ppb_audio_input_dev.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..0bff029fcb18f3b2fb72c84bee130c9e90f4f281 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"
@@ -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.
@@ -233,7 +234,7 @@ class 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.
@@ -336,6 +337,172 @@ void PlatformAudioImpl::OnLowLatencyCreated(
}
}
+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_ = 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();
+
+ 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_;
+
+ MessageLoop* main_message_loop_;
jam 2011/11/16 20:49:52 nit: better to use MessageLoopProxy
viettrungluu 2011/11/16 23:51:17 Done (assuming that all I needed to do was to chan
+
+ 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 (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() {}
@@ -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(
« no previous file with comments | « content/renderer/pepper_plugin_delegate_impl.h ('k') | ppapi/api/dev/ppb_audio_input_dev.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698