summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorneb@chromium.org <neb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-30 21:24:39 +0000
committerneb@chromium.org <neb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-07-30 21:24:39 +0000
commit937df951109b543a70e5474ee12f20df7b52a8d5 (patch)
tree7689840b4951acd56c068b48c75fa8fb797525c3 /webkit
parenta6550f16d87527b7963e7e827c64b64bddeaaef2 (diff)
downloadchromium_src-937df951109b543a70e5474ee12f20df7b52a8d5.zip
chromium_src-937df951109b543a70e5474ee12f20df7b52a8d5.tar.gz
chromium_src-937df951109b543a70e5474ee12f20df7b52a8d5.tar.bz2
Pepper2 audio (trusted side) implementation. Still missing a synchronization for the callback setting, will be done soon.
BUG=none TEST=test plugin plays music Review URL: http://codereview.chromium.org/2962003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54383 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/pepper_audio.cc191
-rw-r--r--webkit/glue/plugins/pepper_audio.h116
-rw-r--r--webkit/glue/plugins/pepper_plugin_delegate.h36
-rw-r--r--webkit/glue/plugins/pepper_plugin_module.cc7
-rw-r--r--webkit/glue/plugins/pepper_resource.h6
-rw-r--r--webkit/glue/webkit_glue.gypi2
6 files changed, 358 insertions, 0 deletions
diff --git a/webkit/glue/plugins/pepper_audio.cc b/webkit/glue/plugins/pepper_audio.cc
new file mode 100644
index 0000000..2fa13b7
--- /dev/null
+++ b/webkit/glue/plugins/pepper_audio.cc
@@ -0,0 +1,191 @@
+// Copyright (c) 2010 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 "webkit/glue/plugins/pepper_audio.h"
+
+#include "base/logging.h"
+#include "third_party/ppapi/c/ppb_audio.h"
+#include "third_party/ppapi/c/ppb_audio_trusted.h"
+
+
+namespace pepper {
+
+namespace {
+
+// PPB_AudioConfig functions
+
+PP_Resource CreateStereo16bit(PP_Module module_id, uint32_t sample_rate,
+ uint32_t sample_frame_count) {
+ PluginModule* module = PluginModule::FromPPModule(module_id);
+ if (!module)
+ return 0;
+
+ scoped_refptr<AudioConfig> config(new AudioConfig(module, sample_rate,
+ sample_frame_count));
+ return config->GetReference();
+}
+
+uint32_t GetSampleRate(PP_Resource config_id) {
+ scoped_refptr<AudioConfig> config = Resource::GetAs<AudioConfig>(config_id);
+ return config ? config->sample_rate() : 0;
+}
+
+uint32_t GetSampleFrameCount(PP_Resource config_id) {
+ scoped_refptr<AudioConfig> config = Resource::GetAs<AudioConfig>(config_id);
+ return config ? config->sample_frame_count() : 0;
+}
+
+// PPB_Audio functions
+
+PP_Resource Create(PP_Instance instance_id, PP_Resource config_id,
+ PPB_Audio_Callback callback, void* user_data) {
+ PluginInstance* instance = PluginInstance::FromPPInstance(instance_id);
+ if (!instance)
+ return 0;
+ // TODO(neb): Require callback to be present for untrusted plugins.
+ scoped_refptr<Audio> audio(new Audio(instance->module()));
+ if (!audio->Init(instance->delegate(), config_id, callback, user_data))
+ return 0;
+ return audio->GetReference();
+}
+
+PP_Resource GetCurrentConfiguration(PP_Resource audio_id) {
+ scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id);
+ return audio ? audio->GetCurrentConfiguration() : 0;
+}
+
+bool StartPlayback(PP_Resource audio_id) {
+ scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id);
+ return audio ? audio->StartPlayback() : false;
+}
+
+bool StopPlayback(PP_Resource audio_id) {
+ scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id);
+ return audio ? audio->StopPlayback() : false;
+}
+
+// PPB_AudioTrusted functions
+
+PP_Resource GetBuffer(PP_Resource audio_id) {
+ // TODO(neb): Implement me!
+ return 0;
+}
+
+int GetOSDescriptor(PP_Resource audio_id) {
+ // TODO(neb): Implement me!
+ return -1;
+}
+
+const PPB_AudioConfig ppb_audioconfig = {
+ &CreateStereo16bit,
+ &GetSampleRate,
+ &GetSampleFrameCount
+};
+
+const PPB_Audio ppb_audio = {
+ &Create,
+ &GetCurrentConfiguration,
+ &StartPlayback,
+ &StopPlayback,
+};
+
+const PPB_AudioTrusted ppb_audiotrusted = {
+ &GetBuffer,
+ &GetOSDescriptor
+};
+
+} // namespace
+
+AudioConfig::AudioConfig(PluginModule* module, int32_t sample_rate,
+ int32_t sample_frame_count)
+ : Resource(module),
+ sample_rate_(sample_rate),
+ sample_frame_count_(sample_frame_count) {
+}
+
+const PPB_AudioConfig* AudioConfig::GetInterface() {
+ return &ppb_audioconfig;
+}
+
+AudioConfig* AudioConfig::AsAudioConfig() {
+ return this;
+}
+
+Audio::Audio(PluginModule* module)
+ : Resource(module),
+ socket_(NULL),
+ shared_memory_(NULL),
+ shared_memory_size_(0),
+ callback_(NULL),
+ user_data_(NULL) {
+}
+
+Audio::~Audio() {
+ // Calling ShutDown() makes sure StreamCreated cannot be called anymore.
+ audio_->ShutDown();
+ // Closing the socket causes the thread to exit - wait for it.
+ socket_->Close();
+ if (audio_thread_.get()) {
+ audio_thread_->Join();
+ audio_thread_.reset();
+ }
+ // Shared memory destructor will unmap the memory automatically.
+}
+
+
+const PPB_Audio* Audio::GetInterface() {
+ return &ppb_audio;
+}
+
+const PPB_AudioTrusted* Audio::GetTrustedInterface() {
+ return &ppb_audiotrusted;
+}
+
+Audio* Audio::AsAudio() {
+ return this;
+}
+
+bool Audio::Init(PluginDelegate* plugin_delegate, PP_Resource config_id,
+ PPB_Audio_Callback callback, void* user_data) {
+ CHECK(!audio_.get());
+ config_ = Resource::GetAs<AudioConfig>(config_id);
+ if (!config_)
+ return false;
+ callback_ = callback;
+ user_data_ = user_data;
+ // When the stream is created, we'll get called back in StreamCreated().
+ audio_.reset(plugin_delegate->CreateAudio(config_->sample_rate(),
+ config_->sample_frame_count(),
+ this));
+ return audio_.get() != NULL;
+}
+
+void Audio::StreamCreated(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket_handle) {
+ socket_.reset(new base::SyncSocket(socket_handle));
+ shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false));
+ shared_memory_size_ = shared_memory_size;
+
+ if (callback_) {
+ shared_memory_->Map(shared_memory_size_);
+ audio_thread_.reset(new base::DelegateSimpleThread(this,
+ "plugin_audio_thread"));
+ audio_thread_->Start();
+ }
+}
+
+void Audio::Run() {
+ int pending_data;
+ void* buffer = shared_memory_->memory();
+
+ while (sizeof(pending_data) ==
+ socket_->Receive(&pending_data, sizeof(pending_data)) &&
+ pending_data >= 0) {
+ callback_(buffer, user_data_);
+ }
+}
+
+} // namespace pepper
+
diff --git a/webkit/glue/plugins/pepper_audio.h b/webkit/glue/plugins/pepper_audio.h
new file mode 100644
index 0000000..2164f00
--- /dev/null
+++ b/webkit/glue/plugins/pepper_audio.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2010 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 "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+#include "base/shared_memory.h"
+#include "base/simple_thread.h"
+#include "base/sync_socket.h"
+#include "third_party/ppapi/c/ppb_audio.h"
+#include "third_party/ppapi/c/ppb_audio_config.h"
+#include "third_party/ppapi/c/ppb_audio_trusted.h"
+#include "webkit/glue/plugins/pepper_plugin_delegate.h"
+#include "webkit/glue/plugins/pepper_plugin_instance.h"
+#include "webkit/glue/plugins/pepper_plugin_module.h"
+#include "webkit/glue/plugins/pepper_resource.h"
+
+#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_
+#define WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_
+
+namespace pepper {
+
+class PluginInstance;
+class PluginModule;
+
+class AudioConfig : public Resource {
+ public:
+ AudioConfig(PluginModule* module, int32_t sample_rate,
+ int32_t sample_frame_count);
+
+ static const PPB_AudioConfig* GetInterface();
+
+ uint32_t sample_rate() { return sample_rate_; }
+ uint32_t sample_frame_count() { return sample_frame_count_; }
+
+ private:
+ // Resource override.
+ virtual AudioConfig* AsAudioConfig();
+
+ int sample_rate_;
+ int sample_frame_count_;
+};
+
+class Audio : public Resource,
+ public PluginDelegate::PlatformAudio::Client,
+ public base::DelegateSimpleThread::Delegate {
+ public:
+ explicit Audio(PluginModule* module);
+ virtual ~Audio();
+
+ static const PPB_Audio* GetInterface();
+ static const PPB_AudioTrusted* GetTrustedInterface();
+
+ bool Init(PluginDelegate* plugin_delegate, PP_Resource config_id,
+ PPB_Audio_Callback callback, void* user_data);
+
+ PP_Resource GetCurrentConfiguration() {
+ return config_->GetReference();
+ }
+
+ bool StartPlayback() {
+ // TODO(neb): Make this synchronous.
+ return audio_->StartPlayback();
+ }
+
+ bool StopPlayback() {
+ // TODO(neb): Make this synchronous.
+ return audio_->StopPlayback();
+ }
+
+ // Resource override.
+ virtual Audio* AsAudio();
+
+ private:
+ // pepper::PluginDelegate::PlatformAudio::Client implementation.
+ virtual void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size_,
+ base::SyncSocket::Handle socket);
+ // End of pepper::PluginDelegate::PlatformAudio::Client implementation.
+
+ // Audio thread. DelegateSimpleThread::Delegate implementation.
+ virtual void Run();
+ // End of DelegateSimpleThread::Delegate implementation.
+
+ // AudioConfig used for creating this Audio object.
+ scoped_refptr<AudioConfig> config_;
+
+ // PluginDelegate audio object that we delegate audio IPC through.
+ scoped_ptr<PluginDelegate::PlatformAudio> audio_;
+
+ // Socket used to notify us when audio is ready to accept new samples. This
+ // pointer is created in StreamCreated().
+ scoped_ptr<base::SyncSocket> socket_;
+
+ // Sample buffer in shared memory. This pointer is created in
+ // StreamCreated(). The memory is only mapped when the audio thread is
+ // created.
+ scoped_ptr<base::SharedMemory> shared_memory_;
+
+ // The size of the sample buffer in bytes.
+ size_t shared_memory_size_;
+
+ // When the callback is set, this thread is spawned for calling it.
+ scoped_ptr<base::DelegateSimpleThread> audio_thread_;
+
+ // Callback to call when audio is ready to accept new samples.
+ volatile PPB_Audio_Callback callback_;
+
+ // User data pointer passed verbatim to the callback function.
+ void* user_data_;
+};
+
+} // namespace pepper
+
+#endif // WEBKIT_GLUE_PLUGINS_PEPPER_DEVICE_CONTEXT_AUDIO_H_
+
diff --git a/webkit/glue/plugins/pepper_plugin_delegate.h b/webkit/glue/plugins/pepper_plugin_delegate.h
index ffc9d52..18cc312 100644
--- a/webkit/glue/plugins/pepper_plugin_delegate.h
+++ b/webkit/glue/plugins/pepper_plugin_delegate.h
@@ -5,8 +5,12 @@
#ifndef WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
#define WEBKIT_GLUE_PLUGINS_PEPPER_PLUGIN_DELEGATE_H_
+#include "base/shared_memory.h"
+#include "base/sync_socket.h"
#include "third_party/ppapi/c/pp_stdint.h"
+class AudioMessageFilter;
+
namespace skia {
class PlatformCanvas;
}
@@ -34,6 +38,33 @@ class PluginDelegate {
virtual intptr_t GetSharedMemoryHandle() const = 0;
};
+ class PlatformAudio {
+ public:
+ class Client {
+ public:
+ virtual ~Client() {}
+
+ // Called when the stream is created.
+ virtual void StreamCreated(base::SharedMemoryHandle shared_memory_handle,
+ size_t shared_memory_size,
+ base::SyncSocket::Handle socket) = 0;
+ };
+
+ virtual ~PlatformAudio() {}
+
+ // Starts the playback. Returns false on error or if called before the
+ // stream is created or after the stream is closed.
+ virtual bool StartPlayback() = 0;
+
+ // Stops the playback. Returns false on error or if called before the stream
+ // is created or after the stream is closed.
+ virtual bool StopPlayback() = 0;
+
+ // Closes the stream. Make sure to call this before the object is
+ // destructed.
+ virtual void ShutDown() = 0;
+ };
+
// Indicates that the given instance has been created.
virtual void InstanceCreated(pepper::PluginInstance* instance) = 0;
@@ -52,6 +83,11 @@ class PluginDelegate {
// Notifies that the index of the currently selected item has been updated.
virtual void DidChangeSelectedFindResult(int identifier, int index) = 0;
+
+ // The caller will own the pointer returned from this.
+ virtual PlatformAudio* CreateAudio(uint32_t sample_rate,
+ uint32_t sample_count,
+ PlatformAudio::Client* client) = 0;
};
} // namespace pepper
diff --git a/webkit/glue/plugins/pepper_plugin_module.cc b/webkit/glue/plugins/pepper_plugin_module.cc
index 8ffd78b..c515cd4 100644
--- a/webkit/glue/plugins/pepper_plugin_module.cc
+++ b/webkit/glue/plugins/pepper_plugin_module.cc
@@ -34,6 +34,7 @@
#include "third_party/ppapi/c/pp_module.h"
#include "third_party/ppapi/c/pp_resource.h"
#include "third_party/ppapi/c/pp_var.h"
+#include "webkit/glue/plugins/pepper_audio.h"
#include "webkit/glue/plugins/pepper_buffer.h"
#include "webkit/glue/plugins/pepper_device_context_2d.h"
#include "webkit/glue/plugins/pepper_directory_reader.h"
@@ -156,6 +157,12 @@ const void* GetInterface(const char* name) {
return PluginInstance::GetInterface();
if (strcmp(name, PPB_IMAGEDATA_INTERFACE) == 0)
return ImageData::GetInterface();
+ if (strcmp(name, PPB_AUDIO_CONFIG_INTERFACE) == 0)
+ return AudioConfig::GetInterface();
+ if (strcmp(name, PPB_AUDIO_INTERFACE) == 0)
+ return Audio::GetInterface();
+ if (strcmp(name, PPB_AUDIO_TRUSTED_INTERFACE) == 0)
+ return Audio::GetTrustedInterface();
if (strcmp(name, PPB_DEVICECONTEXT2D_INTERFACE) == 0)
return DeviceContext2D::GetInterface();
if (strcmp(name, PPB_URLLOADER_INTERFACE) == 0)
diff --git a/webkit/glue/plugins/pepper_resource.h b/webkit/glue/plugins/pepper_resource.h
index 1acaddcb..ac90f9b 100644
--- a/webkit/glue/plugins/pepper_resource.h
+++ b/webkit/glue/plugins/pepper_resource.h
@@ -14,6 +14,8 @@
namespace pepper {
class Buffer;
+class Audio;
+class AudioConfig;
class DeviceContext2D;
class DirectoryReader;
class FileChooser;
@@ -73,6 +75,8 @@ class Resource : public base::RefCountedThreadSafe<Resource> {
// Type-specific getters for individual resource types. These will return
// NULL if the resource does not match the specified type. Used by the Cast()
// function.
+ virtual Audio* AsAudio() { return NULL; }
+ virtual AudioConfig* AsAudioConfig() { return NULL; }
virtual Buffer* AsBuffer() { return NULL; }
virtual DeviceContext2D* AsDeviceContext2D() { return NULL; }
virtual DirectoryReader* AsDirectoryReader() { return NULL; }
@@ -117,6 +121,8 @@ class Resource : public base::RefCountedThreadSafe<Resource> {
return As##Type(); \
}
+DEFINE_RESOURCE_CAST(Audio)
+DEFINE_RESOURCE_CAST(AudioConfig)
DEFINE_RESOURCE_CAST(Buffer)
DEFINE_RESOURCE_CAST(DeviceContext2D)
DEFINE_RESOURCE_CAST(DirectoryReader)
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 49320fc..f63802d 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -164,6 +164,8 @@
'plugins/gtk_plugin_container_manager.cc',
'plugins/npapi_extension_thunk.cc',
'plugins/npapi_extension_thunk.h',
+ 'plugins/pepper_audio.cc',
+ 'plugins/pepper_audio.h',
'plugins/pepper_buffer.cc',
'plugins/pepper_buffer.h',
'plugins/pepper_device_context_2d.cc',