diff options
author | nfullagar@google.com <nfullagar@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-25 00:29:25 +0000 |
---|---|---|
committer | nfullagar@google.com <nfullagar@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-25 00:29:25 +0000 |
commit | 06417271819fc46ae45a76ed0d2e2bb18b5dad01 (patch) | |
tree | a13c12ada2e5c4875f3a7de54a8464785744b3ba /webkit/glue/plugins | |
parent | f68e75ab0e1215c0f3446efc0586a4be02798878 (diff) | |
download | chromium_src-06417271819fc46ae45a76ed0d2e2bb18b5dad01.zip chromium_src-06417271819fc46ae45a76ed0d2e2bb18b5dad01.tar.gz chromium_src-06417271819fc46ae45a76ed0d2e2bb18b5dad01.tar.bz2 |
changes for proxy audio
- includes Darin's changes to move StreamCreated() to main thread
- callback for delivering handles to proxy
- changes to trusted interface
BUG=none
TEST=chrome/src/ppapi/examples/audio/audio.cc
Review URL: http://codereview.chromium.org/5202002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@67354 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r-- | webkit/glue/plugins/pepper_audio.cc | 153 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_audio.h | 32 | ||||
-rw-r--r-- | webkit/glue/plugins/pepper_plugin_delegate.h | 5 |
3 files changed, 161 insertions, 29 deletions
diff --git a/webkit/glue/plugins/pepper_audio.cc b/webkit/glue/plugins/pepper_audio.cc index d98ef1b..1731d8a 100644 --- a/webkit/glue/plugins/pepper_audio.cc +++ b/webkit/glue/plugins/pepper_audio.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "ppapi/c/dev/ppb_audio_dev.h" #include "ppapi/c/dev/ppb_audio_trusted_dev.h" +#include "ppapi/c/pp_completion_callback.h" #include "webkit/glue/plugins/pepper_common.h" namespace pepper { @@ -77,13 +78,15 @@ const PPB_AudioConfig_Dev ppb_audioconfig = { // PPB_Audio ------------------------------------------------------------------- PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, - PPB_Audio_Callback callback, void* user_data) { + PPB_Audio_Callback user_callback, void* user_data) { PluginInstance* instance = ResourceTracker::Get()->GetInstance(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)) + if (!user_callback) + return 0; + scoped_refptr<Audio> audio(new Audio(instance->module(), instance_id)); + if (!audio->Init(instance->delegate(), config_id, + user_callback, user_data)) return 0; return audio->GetReference(); } @@ -118,19 +121,50 @@ const PPB_Audio_Dev ppb_audio = { // PPB_AudioTrusted ------------------------------------------------------------ -PP_Resource GetBuffer(PP_Resource audio_id) { - // TODO(neb): Implement me! - return 0; +PP_Resource CreateTrusted(PP_Instance instance_id) { + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return 0; + scoped_refptr<Audio> audio(new Audio(instance->module(), instance_id)); + return audio->GetReference(); +} + +int32_t Open(PP_Resource audio_id, + PP_Resource config_id, + PP_CompletionCallback created) { + scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id); + if (!audio) + return PP_ERROR_BADRESOURCE; + if (!created.func) + return PP_ERROR_BADARGUMENT; + PP_Instance instance_id = audio->pp_instance(); + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); + if (!instance) + return PP_ERROR_FAILED; + return audio->Open(instance->delegate(), config_id, created); +} + +int32_t GetSyncSocket(PP_Resource audio_id, int* sync_socket) { + scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id); + if (audio) + return audio->GetSyncSocket(sync_socket); + return PP_ERROR_BADRESOURCE; } -int GetOSDescriptor(PP_Resource audio_id) { - // TODO(neb): Implement me! - return -1; +int32_t GetSharedMemory(PP_Resource audio_id, + int* shm_handle, + int32_t* shm_size) { + scoped_refptr<Audio> audio = Resource::GetAs<Audio>(audio_id); + if (audio) + return audio->GetSharedMemory(shm_handle, shm_size); + return PP_ERROR_BADRESOURCE; } const PPB_AudioTrusted_Dev ppb_audiotrusted = { - &GetBuffer, - &GetOSDescriptor + &CreateTrusted, + &Open, + &GetSyncSocket, + &GetSharedMemory, }; } // namespace @@ -165,25 +199,38 @@ AudioConfig* AudioConfig::AsAudioConfig() { // Audio ----------------------------------------------------------------------- -Audio::Audio(PluginModule* module) +Audio::Audio(PluginModule* module, PP_Instance instance_id) : Resource(module), playing_(false), + pp_instance_(instance_id), + audio_(NULL), socket_(NULL), shared_memory_(NULL), shared_memory_size_(0), callback_(NULL), - user_data_(NULL) { + user_data_(NULL), + create_callback_pending_(false) { + create_callback_ = PP_MakeCompletionCallback(NULL, NULL); } Audio::~Audio() { // Calling ShutDown() makes sure StreamCreated cannot be called anymore. audio_->ShutDown(); + audio_ = NULL; + // Closing the socket causes the thread to exit - wait for it. socket_->Close(); if (audio_thread_.get()) { audio_thread_->Join(); audio_thread_.reset(); } + + // If the completion callback hasn't fired yet, do so here + // with an error condition. + if (create_callback_pending_) { + PP_RunCompletionCallback(&create_callback_, PP_ERROR_ABORTED); + create_callback_pending_ = false; + } // Shared memory destructor will unmap the memory automatically. } @@ -199,19 +246,73 @@ Audio* Audio::AsAudio() { return this; } -bool Audio::Init(PluginDelegate* plugin_delegate, PP_Resource config_id, +bool Audio::Init(PluginDelegate* plugin_delegate, + PP_Resource config_id, PPB_Audio_Callback callback, void* user_data) { - CHECK(!audio_.get()); + CHECK(!audio_); 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; + + // When the stream is created, we'll get called back on StreamCreated(). + audio_ = plugin_delegate->CreateAudio(config_->sample_rate(), + config_->sample_frame_count(), + this); + return audio_ != NULL; +} + +int32_t Audio::Open(PluginDelegate* plugin_delegate, + PP_Resource config_id, + PP_CompletionCallback create_callback) { + DCHECK(!audio_); + config_ = Resource::GetAs<AudioConfig>(config_id); + if (!config_) + return PP_ERROR_BADRESOURCE; + + // When the stream is created, we'll get called back on StreamCreated(). + audio_ = plugin_delegate->CreateAudio(config_->sample_rate(), + config_->sample_frame_count(), + this); + if (!audio_) + return PP_ERROR_FAILED; + + // At this point, we are guaranteeing ownership of the completion + // callback. Audio promises to fire the completion callback + // once and only once. + create_callback_ = create_callback; + create_callback_pending_ = true; + return PP_ERROR_WOULDBLOCK; +} + +int32_t Audio::GetSyncSocket(int* sync_socket) { + if (socket_ != NULL) { +#if defined(OS_POSIX) + *sync_socket = socket_->handle(); +#elif defined(OS_WIN) + *sync_socket = reinterpret_cast<int>(socket_->handle()); +#else + #error "Platform not supported." +#endif + return PP_OK; + } + return PP_ERROR_FAILED; +} + +int32_t Audio::GetSharedMemory(int* shm_handle, int32_t* shm_size) { + if (shared_memory_ != NULL) { +#if defined(OS_POSIX) + *shm_handle = shared_memory_->handle().fd; +#elif defined(OS_WIN) + *shm_handle = reinterpret_cast<int>(shared_memory_->handle()); +#else + #error "Platform not supported." +#endif + *shm_size = shared_memory_size_; + return PP_OK; + } + return PP_ERROR_FAILED; } bool Audio::StartPlayback() { @@ -250,8 +351,17 @@ void Audio::StreamCreated(base::SharedMemoryHandle shared_memory_handle, shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); shared_memory_size_ = shared_memory_size; + // Trusted side of proxy can specify a callback to recieve handles. + if (create_callback_pending_) { + PP_RunCompletionCallback(&create_callback_, 0); + create_callback_pending_ = false; + } + + // Trusted, non-proxy audio will invoke buffer filling callback on a + // dedicated thread, see Audio::Run() below. if (callback_) { shared_memory_->Map(shared_memory_size_); + // In common case StartPlayback() was called before StreamCreated(). if (playing_) { audio_thread_.reset(new base::DelegateSimpleThread(this, @@ -277,4 +387,3 @@ void Audio::Run() { } } // namespace pepper - diff --git a/webkit/glue/plugins/pepper_audio.h b/webkit/glue/plugins/pepper_audio.h index ccba021..8c14666 100644 --- a/webkit/glue/plugins/pepper_audio.h +++ b/webkit/glue/plugins/pepper_audio.h @@ -13,6 +13,7 @@ #include "ppapi/c/dev/ppb_audio_dev.h" #include "ppapi/c/dev/ppb_audio_config_dev.h" #include "ppapi/c/dev/ppb_audio_trusted_dev.h" +#include "ppapi/c/pp_completion_callback.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" @@ -46,19 +47,32 @@ class Audio : public Resource, public PluginDelegate::PlatformAudio::Client, public base::DelegateSimpleThread::Delegate { public: - explicit Audio(PluginModule* module); + explicit Audio(PluginModule* module, PP_Instance instance_id); virtual ~Audio(); static const PPB_Audio_Dev* GetInterface(); static const PPB_AudioTrusted_Dev* GetTrustedInterface(); - bool Init(PluginDelegate* plugin_delegate, PP_Resource config_id, - PPB_Audio_Callback callback, void* user_data); + bool Init(PluginDelegate* plugin_delegate, + PP_Resource config_id, + PPB_Audio_Callback user_callback, void* user_data); + + int32_t Open(PluginDelegate* plugin_delegate, + PP_Resource config_id, + PP_CompletionCallback create_callback); PP_Resource GetCurrentConfiguration() { return config_->GetReference(); } + PP_Instance pp_instance() { + return pp_instance_; + } + + int32_t GetSyncSocket(int* sync_socket); + + int32_t GetSharedMemory(int* shm_handle, int32_t* shm_size); + bool StartPlayback(); bool StopPlayback(); @@ -83,8 +97,11 @@ class Audio : public Resource, // AudioConfig used for creating this Audio object. scoped_refptr<AudioConfig> config_; + // Instance id + PP_Instance pp_instance_; + // PluginDelegate audio object that we delegate audio IPC through. - scoped_ptr<PluginDelegate::PlatformAudio> audio_; + PluginDelegate::PlatformAudio* audio_; // Socket used to notify us when audio is ready to accept new samples. This // pointer is created in StreamCreated(). @@ -106,9 +123,14 @@ class Audio : public Resource, // User data pointer passed verbatim to the callback function. void* user_data_; + + // Is a create callback pending to fire? + bool create_callback_pending_; + + // Trusted callback invoked from StreamCreated. + PP_CompletionCallback create_callback_; }; } // 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 97f775a..7032c2c 100644 --- a/webkit/glue/plugins/pepper_plugin_delegate.h +++ b/webkit/glue/plugins/pepper_plugin_delegate.h @@ -129,8 +129,6 @@ class PluginDelegate { 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; @@ -142,6 +140,9 @@ class PluginDelegate { // Closes the stream. Make sure to call this before the object is // destructed. virtual void ShutDown() = 0; + + protected: + virtual ~PlatformAudio() {} }; class PlatformVideoDecoder { |