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 |
- |