Chromium Code Reviews| Index: webkit/glue/plugins/pepper_audio.cc |
| =================================================================== |
| --- webkit/glue/plugins/pepper_audio.cc (revision 66651) |
| +++ webkit/glue/plugins/pepper_audio.cc (working copy) |
| @@ -5,8 +5,9 @@ |
| #include "webkit/glue/plugins/pepper_audio.h" |
| #include "base/logging.h" |
| -#include "ppapi/c/dev/ppb_audio_dev.h" |
| -#include "ppapi/c/dev/ppb_audio_trusted_dev.h" |
| +#include "third_party/ppapi/c/dev/ppb_audio_dev.h" |
| +#include "third_party/ppapi/c/dev/ppb_audio_trusted_dev.h" |
| +#include "third_party/ppapi/c/pp_completion_callback.h" |
| #include "webkit/glue/plugins/pepper_common.h" |
| namespace pepper { |
| @@ -77,13 +78,14 @@ |
| // 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)) |
| + 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 +120,48 @@ |
| // 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(); |
| } |
| -int GetOSDescriptor(PP_Resource audio_id) { |
| - // TODO(neb): Implement me! |
| - return -1; |
| +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_FAILED; |
| + PP_Instance instance_id = audio->pp_instance(); |
| + PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id); |
| + if (!instance) |
| + return PP_ERROR_FAILED; |
| + return audio->OpenTrusted(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_FAILED; |
| +} |
| + |
| +int32_t GetSharedMemory(PP_Resource audio_id, |
| + uint64_t* 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_FAILED; |
| +} |
| + |
| const PPB_AudioTrusted_Dev ppb_audiotrusted = { |
| - &GetBuffer, |
| - &GetOSDescriptor |
| + &CreateTrusted, |
| + &Open, |
| + &GetSyncSocket, |
| + &GetSharedMemory, |
| }; |
| } // namespace |
| @@ -165,25 +196,37 @@ |
| // 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), |
| + shared_memory_handle_(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,21 +242,61 @@ |
| 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::OpenTrusted(PluginDelegate* plugin_delegate, |
| + PP_Resource config_id, |
| + PP_CompletionCallback create_callback) { |
| + CHECK(!audio_); |
|
brettw
2010/11/23 07:10:19
Normally we would DCHECK for something like this
nfullagar
2010/11/23 21:51:17
Done.
|
| + create_callback_ = create_callback; |
|
brettw
2010/11/23 07:10:19
Setting the callback should be done right before y
nfullagar
2010/11/23 21:51:17
good catch, moved
nfullagar
2010/11/23 21:51:17
good catch, moved
|
| + create_callback_pending_ = true; |
| + config_ = Resource::GetAs<AudioConfig>(config_id); |
| + |
| + if (!config_) |
| + return PP_ERROR_FAILED; |
| + // 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_ == NULL) |
| + return PP_ERROR_FAILED; |
| + // At this point, we are guarranteeing ownership of the completion |
|
brettw
2010/11/23 07:10:19
guarranteeing -> guaranteeing
nfullagar
2010/11/23 21:51:17
Done.
|
| + // callback. Audio promises to fire the completion callback |
| + // once and only once. |
| + return PP_ERROR_WOULDBLOCK; |
| +} |
| + |
| +int32_t Audio::GetSyncSocket(int *sync_socket) { |
| + if (socket_ != NULL) { |
| + *sync_socket = static_cast<int>(socket_->handle()); |
| + return PP_OK; |
| + } |
| + return PP_ERROR_FAILED; |
| +} |
| + |
| +int32_t Audio::GetSharedMemory(uint64_t* shm_handle, int32_t* shm_size) { |
| + if (shared_memory_ != NULL) { |
| + *shm_handle = shared_memory_handle_; |
| + *shm_size = shared_memory_size_; |
| + return PP_OK; |
| + } |
| + return PP_ERROR_FAILED; |
| +} |
| + |
| bool Audio::StartPlayback() { |
| if (playing_) |
| return true; |
| @@ -249,7 +332,19 @@ |
| socket_.reset(new base::SyncSocket(socket_handle)); |
| shared_memory_.reset(new base::SharedMemory(shared_memory_handle, false)); |
| shared_memory_size_ = shared_memory_size; |
| - |
| +#if OS_LINUX || OS_MAC |
| + shared_memory_handle_ = static_cast<uint64_t>(shared_memory_handle.fd); |
| +#elif OS_WIN |
| + shared_memory_handle_ = static_cast<uint64_t>(shared_memory_handle); |
| +#else |
| + #error "Unknown OS" |
|
brettw
2010/11/23 07:10:19
I would unindent this 2 spaces.
nfullagar
2010/11/23 21:51:17
Done.
|
| +#endif |
| + // Trusted side of proxy can specify a callback to recieve handles. |
| + if (create_callback_pending_) { |
| + PP_RunCompletionCallback(&create_callback_, 0); |
| + create_callback_pending_ = false; |
| + } |
| + // Recurring callback to fill audio buffers. |
| if (callback_) { |
| shared_memory_->Map(shared_memory_size_); |
| // In common case StartPlayback() was called before StreamCreated(). |
| @@ -277,4 +372,3 @@ |
| } |
| } // namespace pepper |
| - |