diff options
author | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-06 03:23:58 +0000 |
---|---|---|
committer | vrk@chromium.org <vrk@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-06 03:23:58 +0000 |
commit | 7ace8ad34d1f1d98b62da88ac6aaff1f33d8aaaa (patch) | |
tree | 4beeeef47d3ee8a731dcd56150c6938a99b9df78 /ppapi/proxy | |
parent | 10a57d167dd2836ddbd62e8786a12a344707ac73 (diff) | |
download | chromium_src-7ace8ad34d1f1d98b62da88ac6aaff1f33d8aaaa.zip chromium_src-7ace8ad34d1f1d98b62da88ac6aaff1f33d8aaaa.tar.gz chromium_src-7ace8ad34d1f1d98b62da88ac6aaff1f33d8aaaa.tar.bz2 |
Implement PPAPI VideoDecode out-of-process support
This CL implements the proxy necessary for out-of-process video decoding and
introduces a shared base class between the PPB_VideoDecoder_Impl and the proxy.
BUG=NONE
TEST=gles2 plugin runs with or without --ppapi-out-of-process flag, no crashes
Review URL: http://codereview.chromium.org/7545014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@95724 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy')
-rw-r--r-- | ppapi/proxy/dispatcher.cc | 4 | ||||
-rw-r--r-- | ppapi/proxy/plugin_resource.h | 5 | ||||
-rw-r--r-- | ppapi/proxy/ppapi_messages.h | 66 | ||||
-rw-r--r-- | ppapi/proxy/ppb_buffer_proxy.cc | 31 | ||||
-rw-r--r-- | ppapi/proxy/ppb_buffer_proxy.h | 31 | ||||
-rw-r--r-- | ppapi/proxy/ppb_video_decoder_proxy.cc | 365 | ||||
-rw-r--r-- | ppapi/proxy/ppb_video_decoder_proxy.h | 81 | ||||
-rw-r--r-- | ppapi/proxy/ppp_video_decoder_proxy.cc | 167 | ||||
-rw-r--r-- | ppapi/proxy/ppp_video_decoder_proxy.h | 52 | ||||
-rw-r--r-- | ppapi/proxy/resource_creation_proxy.cc | 5 |
10 files changed, 772 insertions, 35 deletions
diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc index dc61c51..a1c9974 100644 --- a/ppapi/proxy/dispatcher.cc +++ b/ppapi/proxy/dispatcher.cc @@ -80,12 +80,14 @@ #include "ppapi/proxy/ppb_url_util_proxy.h" #include "ppapi/proxy/ppb_var_deprecated_proxy.h" #include "ppapi/proxy/ppb_var_proxy.h" +#include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/proxy/ppp_class_proxy.h" #include "ppapi/proxy/ppp_graphics_3d_proxy.h" #include "ppapi/proxy/ppp_input_event_proxy.h" #include "ppapi/proxy/ppp_instance_private_proxy.h" #include "ppapi/proxy/ppp_instance_proxy.h" #include "ppapi/proxy/ppp_messaging_proxy.h" +#include "ppapi/proxy/ppp_video_decoder_proxy.h" #include "ppapi/proxy/var_serialization_rules.h" namespace pp { @@ -162,6 +164,7 @@ InterfaceList::InterfaceList() { AddPPB(PPB_URLUtil_Proxy::GetInfo()); AddPPB(PPB_Var_Deprecated_Proxy::GetInfo()); AddPPB(PPB_Var_Proxy::GetInfo()); + AddPPB(PPB_VideoDecoder_Proxy::GetInfo()); #ifdef ENABLE_FLAPPER_HACKS AddPPB(PPB_Flash_NetConnector_Proxy::GetInfo()); @@ -173,6 +176,7 @@ InterfaceList::InterfaceList() { AddPPP(PPP_Instance_Private_Proxy::GetInfo()); AddPPP(PPP_Instance_Proxy::GetInfo1_0()); AddPPP(PPP_Messaging_Proxy::GetInfo()); + AddPPP(PPP_VideoDecoder_Proxy::GetInfo()); } void InterfaceList::AddPPP(const InterfaceProxy::Info* info) { diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 8646189..a0675d3 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -32,8 +32,9 @@ F(PrivateFontFile) \ F(Surface3D) \ F(URLLoader) \ - F(URLRequestInfo)\ - F(URLResponseInfo) + F(URLRequestInfo) \ + F(URLResponseInfo) \ + F(VideoDecoder) namespace pp { namespace proxy { diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index 9a1e47b..b039878 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -26,6 +26,7 @@ #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_size.h" +#include "ppapi/c/dev/pp_video_dev.h" #include "ppapi/c/private/ppb_flash_tcp_socket.h" #include "ppapi/proxy/ppapi_param_traits.h" #include "ppapi/proxy/serialized_flash_menu.h" @@ -37,6 +38,7 @@ IPC_ENUM_TRAITS(PP_InputEvent_Type) IPC_ENUM_TRAITS(PP_InputEvent_MouseButton) +IPC_ENUM_TRAITS(PP_VideoDecodeError_Dev) IPC_STRUCT_TRAITS_BEGIN(PP_Point) IPC_STRUCT_TRAITS_MEMBER(x) @@ -58,6 +60,17 @@ IPC_STRUCT_TRAITS_BEGIN(PP_Rect) IPC_STRUCT_TRAITS_MEMBER(size) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(PP_PictureBuffer_Dev) + IPC_STRUCT_TRAITS_MEMBER(id) + IPC_STRUCT_TRAITS_MEMBER(size) + IPC_STRUCT_TRAITS_MEMBER(texture_id) +IPC_STRUCT_TRAITS_END() + +IPC_STRUCT_TRAITS_BEGIN(PP_Picture_Dev) + IPC_STRUCT_TRAITS_MEMBER(picture_buffer_id) + IPC_STRUCT_TRAITS_MEMBER(bitstream_buffer_id) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(::ppapi::Preferences) IPC_STRUCT_TRAITS_MEMBER(standard_font_family) IPC_STRUCT_TRAITS_MEMBER(fixed_font_family) @@ -317,6 +330,36 @@ IPC_MESSAGE_ROUTED3(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack, int32 /* result */, std::string /* data */) +// PPB_VideoDecoder_Dev. +// (Messages from renderer to plugin to notify it to run callbacks.) +IPC_MESSAGE_ROUTED3(PpapiMsg_PPBVideoDecoder_EndOfBitstreamACK, + pp::proxy::HostResource /* video_decoder */, + int32_t /* bitstream buffer id */, + int32_t /* PP_CompletionCallback result */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPBVideoDecoder_FlushACK, + pp::proxy::HostResource /* video_decoder */, + int32_t /* PP_CompletionCallback result */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPBVideoDecoder_ResetACK, + pp::proxy::HostResource /* video_decoder */, + int32_t /* PP_CompletionCallback result */) + +// PPP_VideoDecoder_Dev. +IPC_MESSAGE_ROUTED3(PpapiMsg_PPPVideoDecoder_ProvidePictureBuffers, + pp::proxy::HostResource /* video_decoder */, + uint32_t /* requested number of buffers */, + PP_Size /* dimensions of buffers */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoDecoder_DismissPictureBuffer, + pp::proxy::HostResource /* video_decoder */, + int32_t /* picture buffer id */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoDecoder_PictureReady, + pp::proxy::HostResource /* video_decoder */, + PP_Picture_Dev /* output picture */) +IPC_MESSAGE_ROUTED1(PpapiMsg_PPPVideoDecoder_NotifyEndOfStream, + pp::proxy::HostResource /* video_decoder */) +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPVideoDecoder_NotifyError, + pp::proxy::HostResource /* video_decoder */, + PP_VideoDecodeError_Dev /* error */) + // ----------------------------------------------------------------------------- // These are from the plugin to the renderer. @@ -902,3 +945,26 @@ IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_ResourceCreation_ImageData, pp::proxy::HostResource /* result_resource */, std::string /* image_data_desc */, pp::proxy::ImageHandle /* result */) +// PPB_VideoDecoder. +IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBVideoDecoder_Create, + PP_Instance /* instance */, + pp::proxy::HostResource /* context */, + std::vector<PP_VideoConfigElement> /* config */, + pp::proxy::HostResource /* result */) +IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBVideoDecoder_Decode, + pp::proxy::HostResource /* video_decoder */, + pp::proxy::HostResource /* bitstream buffer */, + int32 /* bitstream buffer id */, + int32 /* size of buffer */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBVideoDecoder_AssignPictureBuffers, + pp::proxy::HostResource /* video_decoder */, + std::vector<PP_PictureBuffer_Dev> /* picture buffers */) +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBVideoDecoder_ReusePictureBuffer, + pp::proxy::HostResource /* video_decoder */, + int32_t /* picture buffer id */) +IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBVideoDecoder_Flush, + pp::proxy::HostResource /* video_decoder */) +IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBVideoDecoder_Reset, + pp::proxy::HostResource /* video_decoder */) +IPC_SYNC_MESSAGE_ROUTED1_0(PpapiHostMsg_PPBVideoDecoder_Destroy, + pp::proxy::HostResource /* video_decoder */) diff --git a/ppapi/proxy/ppb_buffer_proxy.cc b/ppapi/proxy/ppb_buffer_proxy.cc index 2e2ee90..2e782ac 100644 --- a/ppapi/proxy/ppb_buffer_proxy.cc +++ b/ppapi/proxy/ppb_buffer_proxy.cc @@ -14,10 +14,8 @@ #include "ppapi/c/dev/ppb_buffer_dev.h" #include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/plugin_dispatcher.h" -#include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/thunk/enter.h" -#include "ppapi/thunk/ppb_buffer_api.h" #include "ppapi/thunk/ppb_buffer_trusted_api.h" #include "ppapi/thunk/thunk.h" @@ -33,35 +31,6 @@ InterfaceProxy* CreateBufferProxy(Dispatcher* dispatcher, } // namespace -class Buffer : public ppapi::thunk::PPB_Buffer_API, - public PluginResource { - public: - Buffer(const HostResource& resource, - const base::SharedMemoryHandle& shm_handle, - uint32_t size); - virtual ~Buffer(); - - // Resource overrides. - virtual Buffer* AsBuffer() OVERRIDE; - - // ResourceObjectBase overrides. - virtual ppapi::thunk::PPB_Buffer_API* AsPPB_Buffer_API() OVERRIDE; - - // PPB_Buffer_API implementation. - virtual PP_Bool Describe(uint32_t* size_in_bytes) OVERRIDE; - virtual PP_Bool IsMapped() OVERRIDE; - virtual void* Map() OVERRIDE; - virtual void Unmap() OVERRIDE; - - private: - base::SharedMemory shm_; - uint32_t size_; - void* mapped_data_; - int map_count_; - - DISALLOW_COPY_AND_ASSIGN(Buffer); -}; - Buffer::Buffer(const HostResource& resource, const base::SharedMemoryHandle& shm_handle, uint32_t size) diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h index 6002950..e11b94f 100644 --- a/ppapi/proxy/ppb_buffer_proxy.h +++ b/ppapi/proxy/ppb_buffer_proxy.h @@ -8,6 +8,8 @@ #include "base/shared_memory.h" #include "ppapi/c/pp_instance.h" #include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/thunk/ppb_buffer_api.h" struct PPB_Buffer_Dev; @@ -16,6 +18,35 @@ namespace proxy { class HostResource; +class Buffer : public ppapi::thunk::PPB_Buffer_API, + public PluginResource { + public: + Buffer(const HostResource& resource, + const base::SharedMemoryHandle& shm_handle, + uint32_t size); + virtual ~Buffer(); + + // Resource overrides. + virtual Buffer* AsBuffer() OVERRIDE; + + // ResourceObjectBase overrides. + virtual ppapi::thunk::PPB_Buffer_API* AsPPB_Buffer_API() OVERRIDE; + + // PPB_Buffer_API implementation. + virtual PP_Bool Describe(uint32_t* size_in_bytes) OVERRIDE; + virtual PP_Bool IsMapped() OVERRIDE; + virtual void* Map() OVERRIDE; + virtual void Unmap() OVERRIDE; + + private: + base::SharedMemory shm_; + uint32_t size_; + void* mapped_data_; + int map_count_; + + DISALLOW_COPY_AND_ASSIGN(Buffer); +}; + class PPB_Buffer_Proxy : public InterfaceProxy { public: PPB_Buffer_Proxy(Dispatcher* dispatcher, const void* target_interface); diff --git a/ppapi/proxy/ppb_video_decoder_proxy.cc b/ppapi/proxy/ppb_video_decoder_proxy.cc new file mode 100644 index 0000000..97c2348 --- /dev/null +++ b/ppapi/proxy/ppb_video_decoder_proxy.cc @@ -0,0 +1,365 @@ +// Copyright (c) 2011 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 "ppapi/proxy/ppb_video_decoder_proxy.h" + +#include "base/logging.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "ppapi/proxy/enter_proxy.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_buffer_proxy.h" +#include "ppapi/proxy/ppb_context_3d_proxy.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/resource_creation_api.h" +#include "ppapi/thunk/thunk.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_Buffer_API; +using ppapi::thunk::PPB_Context3D_API; +using ppapi::thunk::PPB_VideoDecoder_API; + +namespace pp { +namespace proxy { + +class VideoDecoder : public PluginResource, + public ::ppapi::VideoDecoderImpl { + public: + virtual ~VideoDecoder(); + + static VideoDecoder* Create(const HostResource& resource, + PP_Resource context3d_id, + const PP_VideoConfigElement* config); + + // ResourceObjectBase overrides. + virtual PPB_VideoDecoder_API* AsPPB_VideoDecoder_API() OVERRIDE; + + // PPB_VideoDecoder_API implementation. + virtual int32_t Decode(const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + PP_CompletionCallback callback) OVERRIDE; + virtual void AssignPictureBuffers( + uint32_t no_of_buffers, const PP_PictureBuffer_Dev* buffers) OVERRIDE; + virtual void ReusePictureBuffer(int32_t picture_buffer_id) OVERRIDE; + virtual int32_t Flush(PP_CompletionCallback callback) OVERRIDE; + virtual int32_t Reset(PP_CompletionCallback callback) OVERRIDE; + virtual void Destroy() OVERRIDE; + + protected: + virtual void AddRefResource(PP_Resource resource) OVERRIDE; + virtual void UnrefResource(PP_Resource resource) OVERRIDE; + + private: + friend class PPB_VideoDecoder_Proxy; + explicit VideoDecoder(const HostResource& resource); + + // Run the callbacks that were passed into the plugin interface. + void FlushACK(int32_t result); + void ResetACK(int32_t result); + void EndOfBitstreamACK(int32_t buffer_id, int32_t result); + + DISALLOW_COPY_AND_ASSIGN(VideoDecoder); +}; + +VideoDecoder::VideoDecoder(const HostResource& decoder) + : PluginResource(decoder) { +} + +VideoDecoder* VideoDecoder::Create(const HostResource& resource, + PP_Resource context3d_id, + const PP_VideoConfigElement* config) { + if (!context3d_id) + return NULL; + + EnterResourceNoLock<PPB_Context3D_API> enter_context(context3d_id, true); + if (enter_context.failed()) + return NULL; + + scoped_ptr<VideoDecoder> decoder(new VideoDecoder(resource)); + if (decoder->Init(context3d_id, enter_context.object(), config)) + return decoder.release(); + return NULL; +} + +VideoDecoder::~VideoDecoder() { +} + +::ppapi::thunk::PPB_VideoDecoder_API* VideoDecoder::AsPPB_VideoDecoder_API() { + return this; +} + +int32_t VideoDecoder::Decode( + const PP_VideoBitstreamBuffer_Dev* bitstream_buffer, + PP_CompletionCallback callback) { + ppapi::thunk::EnterResourceNoLock<PPB_Buffer_API> + enter_buffer(bitstream_buffer->data, true); + if (enter_buffer.failed()) + return PP_ERROR_BADRESOURCE; + + SetBitstreamBufferCallback(bitstream_buffer->id, callback); + + Buffer* ppb_buffer = + static_cast<Buffer*>(enter_buffer.object()); + HostResource host_buffer = ppb_buffer->host_resource(); + + FlushCommandBuffer(); + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoDecoder_Decode( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, host_resource(), + host_buffer, bitstream_buffer->id, + bitstream_buffer->size)); + return PP_OK_COMPLETIONPENDING; +} + +void VideoDecoder::AssignPictureBuffers(uint32_t no_of_buffers, + const PP_PictureBuffer_Dev* buffers) { + std::vector<PP_PictureBuffer_Dev> buffer_list( + buffers, buffers + no_of_buffers); + FlushCommandBuffer(); + GetDispatcher()->Send( + new PpapiHostMsg_PPBVideoDecoder_AssignPictureBuffers( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, host_resource(), buffer_list)); +} + +void VideoDecoder::ReusePictureBuffer(int32_t picture_buffer_id) { + FlushCommandBuffer(); + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoDecoder_ReusePictureBuffer( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, host_resource(), picture_buffer_id)); +} + +int32_t VideoDecoder::Flush(PP_CompletionCallback callback) { + SetFlushCallback(callback); + + FlushCommandBuffer(); + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoDecoder_Flush( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, host_resource())); + return PP_OK_COMPLETIONPENDING; +} + +int32_t VideoDecoder::Reset(PP_CompletionCallback callback) { + SetResetCallback(callback); + + FlushCommandBuffer(); + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoDecoder_Reset( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, host_resource())); + return PP_OK_COMPLETIONPENDING; +} + +void VideoDecoder::Destroy() { + FlushCommandBuffer(); + GetDispatcher()->Send(new PpapiHostMsg_PPBVideoDecoder_Destroy( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, host_resource())); + ::ppapi::VideoDecoderImpl::Destroy(); +} + +void VideoDecoder::AddRefResource(PP_Resource resource) { + PluginResourceTracker::GetInstance()->AddRefResource(resource); +} + +void VideoDecoder::UnrefResource(PP_Resource resource) { + PluginResourceTracker::GetInstance()->ReleaseResource(resource); +} + +void VideoDecoder::ResetACK(int32_t result) { + RunResetCallback(result); +} + +void VideoDecoder::FlushACK(int32_t result) { + RunFlushCallback(result); +} + +void VideoDecoder::EndOfBitstreamACK( + int32_t bitstream_buffer_id, int32_t result) { + RunBitstreamBufferCallback(bitstream_buffer_id, result); +} + +namespace { + +InterfaceProxy* CreateVideoDecoderProxy(Dispatcher* dispatcher, + const void* target_interface) { + return new PPB_VideoDecoder_Proxy(dispatcher, target_interface); +} + +} // namespace + +PPB_VideoDecoder_Proxy::PPB_VideoDecoder_Proxy(Dispatcher* dispatcher, + const void* target_interface) + : InterfaceProxy(dispatcher, target_interface), + callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { +} + +PPB_VideoDecoder_Proxy::~PPB_VideoDecoder_Proxy() { +} + +// static +const InterfaceProxy::Info* PPB_VideoDecoder_Proxy::GetInfo() { + static const Info info = { + ::ppapi::thunk::GetPPB_VideoDecoder_Thunk(), + PPB_VIDEODECODER_DEV_INTERFACE, + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, + false, + &CreateVideoDecoderProxy, + }; + return &info; +} + +bool PPB_VideoDecoder_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPB_VideoDecoder_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_Create, + OnMsgCreate) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_Decode, OnMsgDecode) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_AssignPictureBuffers, + OnMsgAssignPictureBuffers) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_ReusePictureBuffer, + OnMsgReusePictureBuffer) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_Flush, OnMsgFlush) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_Reset, OnMsgReset) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBVideoDecoder_Destroy, OnMsgDestroy) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBVideoDecoder_ResetACK, OnMsgResetACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBVideoDecoder_EndOfBitstreamACK, + OnMsgEndOfBitstreamACK) + IPC_MESSAGE_HANDLER(PpapiMsg_PPBVideoDecoder_FlushACK, OnMsgFlushACK) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + DCHECK(handled); + return handled; +} + +PP_Resource PPB_VideoDecoder_Proxy::CreateProxyResource( + PP_Instance instance, PP_Resource context3d_id, + const PP_VideoConfigElement* config) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + // Dispatcher is null if it cannot find the instance passed to it (i.e. if the + // client passes in an invalid instance). + if (!dispatcher) + return 0; + + std::vector<PP_VideoConfigElement> copied; + if (!ppapi::VideoDecoderImpl::CopyConfigsToVector(config, &copied)) + return 0; + + ppapi::thunk::EnterResourceNoLock<PPB_Context3D_API> + enter_context(context3d_id, true); + if (enter_context.failed()) + return 0; + Context3D* ppb_context = + static_cast<Context3D*>(enter_context.object()); + HostResource host_context = ppb_context->host_resource(); + + HostResource result; + dispatcher->Send(new PpapiHostMsg_PPBVideoDecoder_Create( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, instance, + host_context, copied, &result)); + if (result.is_null()) + return 0; + + linked_ptr<VideoDecoder> video_decoder( + VideoDecoder::Create(result, context3d_id, config)); + + return PluginResourceTracker::GetInstance()->AddResource(video_decoder); +} + +void PPB_VideoDecoder_Proxy::OnMsgCreate( + PP_Instance instance, const HostResource& context3d_id, + const std::vector<PP_VideoConfigElement>& config, + HostResource* result) { + ::ppapi::thunk::EnterFunction< ::ppapi::thunk::ResourceCreationAPI> + resource_creation(instance, true); + if (resource_creation.failed()) + return; + + std::vector<PP_VideoConfigElement> copied = config; + copied.push_back(PP_VIDEOATTR_DICTIONARY_TERMINATOR); + + // Make the resource and get the API pointer to its interface. + result->SetHostResource( + instance, resource_creation.functions()->CreateVideoDecoder( + instance, context3d_id.host_resource(), &copied.front())); +} + +void PPB_VideoDecoder_Proxy::OnMsgDecode( + const HostResource& decoder, + const HostResource& buffer, int32 id, int32 size) { + CompletionCallback callback = callback_factory_.NewRequiredCallback( + &PPB_VideoDecoder_Proxy::SendMsgEndOfBitstreamACKToPlugin, decoder, id); + + PP_VideoBitstreamBuffer_Dev bitstream = { id, buffer.host_resource(), size }; + ppb_video_decoder_target()->Decode( + decoder.host_resource(), &bitstream, callback.pp_completion_callback()); +} + +void PPB_VideoDecoder_Proxy::OnMsgAssignPictureBuffers( + const HostResource& decoder, + const std::vector<PP_PictureBuffer_Dev>& buffers) { + DCHECK(!buffers.empty()); + const PP_PictureBuffer_Dev* buffer_array = &buffers.front(); + + ppb_video_decoder_target()->AssignPictureBuffers( + decoder.host_resource(), buffers.size(), buffer_array); +} + +void PPB_VideoDecoder_Proxy::OnMsgReusePictureBuffer( + const HostResource& decoder, int32 picture_buffer_id) { + ppb_video_decoder_target()->ReusePictureBuffer( + decoder.host_resource(), picture_buffer_id); +} + +void PPB_VideoDecoder_Proxy::OnMsgFlush(const HostResource& decoder) { + CompletionCallback callback = callback_factory_.NewRequiredCallback( + &PPB_VideoDecoder_Proxy::SendMsgFlushACKToPlugin, decoder); + ppb_video_decoder_target()->Flush( + decoder.host_resource(), callback.pp_completion_callback()); +} + +void PPB_VideoDecoder_Proxy::OnMsgReset(const HostResource& decoder) { + CompletionCallback callback = callback_factory_.NewRequiredCallback( + &PPB_VideoDecoder_Proxy::SendMsgResetACKToPlugin, decoder); + ppb_video_decoder_target()->Reset( + decoder.host_resource(), callback.pp_completion_callback()); +} + +void PPB_VideoDecoder_Proxy::OnMsgDestroy(const HostResource& decoder) { + ppb_video_decoder_target()->Destroy(decoder.host_resource()); +} + +void PPB_VideoDecoder_Proxy::SendMsgEndOfBitstreamACKToPlugin( + int32_t result, const HostResource& decoder, int32 id) { + dispatcher()->Send(new PpapiMsg_PPBVideoDecoder_EndOfBitstreamACK( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, decoder, id, result)); +} + +void PPB_VideoDecoder_Proxy::SendMsgFlushACKToPlugin( + int32_t result, const HostResource& decoder) { + dispatcher()->Send(new PpapiMsg_PPBVideoDecoder_FlushACK( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, decoder, result)); +} + +void PPB_VideoDecoder_Proxy::SendMsgResetACKToPlugin( + int32_t result, const HostResource& decoder) { + dispatcher()->Send(new PpapiMsg_PPBVideoDecoder_ResetACK( + INTERFACE_ID_PPB_VIDEO_DECODER_DEV, decoder, result)); +} + +void PPB_VideoDecoder_Proxy::OnMsgEndOfBitstreamACK( + const HostResource& decoder, int32_t id, int32_t result) { + EnterPluginFromHostResource<PPB_VideoDecoder_API> enter(decoder); + if (enter.succeeded()) + static_cast<VideoDecoder*>(enter.object())->EndOfBitstreamACK(id, result); +} + +void PPB_VideoDecoder_Proxy::OnMsgFlushACK( + const HostResource& decoder, int32_t result) { + EnterPluginFromHostResource<PPB_VideoDecoder_API> enter(decoder); + if (enter.succeeded()) + static_cast<VideoDecoder*>(enter.object())->FlushACK(result); +} + +void PPB_VideoDecoder_Proxy::OnMsgResetACK( + const HostResource& decoder, int32_t result) { + EnterPluginFromHostResource<PPB_VideoDecoder_API> enter(decoder); + if (enter.succeeded()) + static_cast<VideoDecoder*>(enter.object())->ResetACK(result); +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/ppb_video_decoder_proxy.h b/ppapi/proxy/ppb_video_decoder_proxy.h new file mode 100644 index 0000000..134fec7 --- /dev/null +++ b/ppapi/proxy/ppb_video_decoder_proxy.h @@ -0,0 +1,81 @@ +// Copyright (c) 2011 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. + +#ifndef PPAPI_PROXY_PPB_VIDEO_DECODER_PROXY_H_ +#define PPAPI_PROXY_PPB_VIDEO_DECODER_PROXY_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/proxy/interface_proxy.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" +#include "ppapi/shared_impl/video_decoder_impl.h" +#include "ppapi/thunk/ppb_video_decoder_api.h" + +namespace pp { +namespace proxy { + +class PPB_VideoDecoder_Proxy : public InterfaceProxy { + public: + PPB_VideoDecoder_Proxy(Dispatcher* dispatcher, const void* target_interface); + virtual ~PPB_VideoDecoder_Proxy(); + + static const Info* GetInfo(); + + // Creates a VideoDecoder object in the plugin process. + static PP_Resource CreateProxyResource(PP_Instance instance, + PP_Resource context3d_id, const PP_VideoConfigElement* config); + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + const PPB_VideoDecoder_Dev* ppb_video_decoder_target() const { + return static_cast<const PPB_VideoDecoder_Dev*>(target_interface()); + } + + private: + // Message handlers in the renderer process to receive messages from the + // plugin process. + void OnMsgCreate(PP_Instance instance, const HostResource& context3d_id, + const std::vector<PP_VideoConfigElement>& config, + HostResource* result); + void OnMsgDecode( + const HostResource& decoder, + const HostResource& buffer, int32 id, int32 size); + void OnMsgAssignPictureBuffers( + const HostResource& decoder, + const std::vector<PP_PictureBuffer_Dev>& buffers); + void OnMsgReusePictureBuffer( + const HostResource& decoder, + int32 picture_buffer_id); + void OnMsgFlush(const HostResource& decoder); + void OnMsgReset(const HostResource& decoder); + void OnMsgDestroy(const HostResource& decoder); + + // Send a message from the renderer process to the plugin process to tell it + // to run its callback. + void SendMsgEndOfBitstreamACKToPlugin( + int32_t result, const HostResource& decoder, int32 id); + void SendMsgFlushACKToPlugin( + int32_t result, const HostResource& decoder); + void SendMsgResetACKToPlugin( + int32_t result, const HostResource& decoder); + + // Message handlers in the plugin process to receive messages from the + // renderer process. + void OnMsgEndOfBitstreamACK(const HostResource& decoder, + int32_t id, int32_t result); + void OnMsgFlushACK(const HostResource& decoder, int32_t result); + void OnMsgResetACK(const HostResource& decoder, int32_t result); + + CompletionCallbackFactory<PPB_VideoDecoder_Proxy, + ProxyNonThreadSafeRefCount> callback_factory_; + + DISALLOW_COPY_AND_ASSIGN(PPB_VideoDecoder_Proxy); +}; + +} // namespace proxy +} // namespace pp + +#endif // PPAPI_PROXY_PPB_VIDEO_DECODER_PROXY_H_ diff --git a/ppapi/proxy/ppp_video_decoder_proxy.cc b/ppapi/proxy/ppp_video_decoder_proxy.cc new file mode 100644 index 0000000..cae7c23 --- /dev/null +++ b/ppapi/proxy/ppp_video_decoder_proxy.cc @@ -0,0 +1,167 @@ +// Copyright (c) 2011 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 "ppapi/proxy/ppp_video_decoder_proxy.h" + +#include "ppapi/proxy/host_dispatcher.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppb_video_decoder_proxy.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_video_decoder_api.h" +#include "ppapi/thunk/thunk.h" + +using ::ppapi::thunk::PPB_VideoDecoder_API; + +namespace pp { +namespace proxy { + +namespace { + +void ProvidePictureBuffers(PP_Instance instance, PP_Resource decoder, + uint32_t req_num_of_bufs, PP_Size dimensions) { + HostResource decoder_resource; + decoder_resource.SetHostResource(instance, decoder); + + HostDispatcher::GetForInstance(instance)->Send( + new PpapiMsg_PPPVideoDecoder_ProvidePictureBuffers( + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, + decoder_resource, req_num_of_bufs, dimensions)); +} + +void DismissPictureBuffer(PP_Instance instance, PP_Resource decoder, + int32_t picture_buffer_id) { + HostResource decoder_resource; + decoder_resource.SetHostResource(instance, decoder); + + HostDispatcher::GetForInstance(instance)->Send( + new PpapiMsg_PPPVideoDecoder_DismissPictureBuffer( + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, + decoder_resource, picture_buffer_id)); +} + +void PictureReady(PP_Instance instance, PP_Resource decoder, + PP_Picture_Dev picture) { + HostResource decoder_resource; + decoder_resource.SetHostResource(instance, decoder); + + HostDispatcher::GetForInstance(instance)->Send( + new PpapiMsg_PPPVideoDecoder_PictureReady( + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, decoder_resource, picture)); +} + +void EndOfStream(PP_Instance instance, PP_Resource decoder) { + HostResource decoder_resource; + decoder_resource.SetHostResource(instance, decoder); + + HostDispatcher::GetForInstance(instance)->Send( + new PpapiMsg_PPPVideoDecoder_NotifyEndOfStream( + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, decoder_resource)); +} + +void NotifyError(PP_Instance instance, PP_Resource decoder, + PP_VideoDecodeError_Dev error) { + HostResource decoder_resource; + decoder_resource.SetHostResource(instance, decoder); + + HostDispatcher::GetForInstance(instance)->Send( + new PpapiMsg_PPPVideoDecoder_NotifyError( + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, decoder_resource, error)); +} + +static const PPP_VideoDecoder_Dev video_decoder_interface = { + &ProvidePictureBuffers, + &DismissPictureBuffer, + &PictureReady, + &EndOfStream, + &NotifyError +}; + +InterfaceProxy* CreateVideoDecoderPPPProxy( + Dispatcher* dispatcher, const void* target_interface) { + return new PPP_VideoDecoder_Proxy(dispatcher, target_interface); +} + +} // namespace + +PPP_VideoDecoder_Proxy::PPP_VideoDecoder_Proxy( + Dispatcher* dispatcher, const void* target_interface) + : InterfaceProxy(dispatcher, target_interface) { +} + +PPP_VideoDecoder_Proxy::~PPP_VideoDecoder_Proxy() { +} + +// static +const InterfaceProxy::Info* PPP_VideoDecoder_Proxy::GetInfo() { + static const Info info = { + &video_decoder_interface, + PPP_VIDEODECODER_DEV_INTERFACE, + INTERFACE_ID_PPP_VIDEO_DECODER_DEV, + false, + &CreateVideoDecoderPPPProxy, + }; + return &info; +} + +bool PPP_VideoDecoder_Proxy::OnMessageReceived(const IPC::Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PPP_VideoDecoder_Proxy, msg) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_ProvidePictureBuffers, + OnMsgProvidePictureBuffers) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_DismissPictureBuffer, + OnMsgDismissPictureBuffer) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_PictureReady, + OnMsgPictureReady) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_NotifyEndOfStream, + OnMsgNotifyEndOfStream) + IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_NotifyError, + OnMsgNotifyError) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + DCHECK(handled); + return handled; +} + +void PPP_VideoDecoder_Proxy::OnMsgProvidePictureBuffers( + const HostResource& decoder, uint32_t req_num_of_bufs, + const PP_Size& dimensions) { + PP_Resource plugin_decoder = PluginResourceTracker::GetInstance()-> + PluginResourceForHostResource(decoder); + ppp_video_decoder_target()->ProvidePictureBuffers( + decoder.instance(), plugin_decoder, req_num_of_bufs, dimensions); +} + +void PPP_VideoDecoder_Proxy::OnMsgDismissPictureBuffer( + const HostResource& decoder, int32_t picture_id) { + PP_Resource plugin_decoder = PluginResourceTracker::GetInstance()-> + PluginResourceForHostResource(decoder); + ppp_video_decoder_target()->DismissPictureBuffer( + decoder.instance(), plugin_decoder, picture_id); +} + +void PPP_VideoDecoder_Proxy::OnMsgPictureReady( + const HostResource& decoder, const PP_Picture_Dev& picture) { + PP_Resource plugin_decoder = PluginResourceTracker::GetInstance()-> + PluginResourceForHostResource(decoder); + ppp_video_decoder_target()->PictureReady( + decoder.instance(), plugin_decoder, picture); +} + +void PPP_VideoDecoder_Proxy::OnMsgNotifyEndOfStream( + const HostResource& decoder) { + PP_Resource plugin_decoder = PluginResourceTracker::GetInstance()-> + PluginResourceForHostResource(decoder); + ppp_video_decoder_target()->EndOfStream(decoder.instance(), plugin_decoder); +} + +void PPP_VideoDecoder_Proxy::OnMsgNotifyError( + const HostResource& decoder, PP_VideoDecodeError_Dev error) { + PP_Resource plugin_decoder = PluginResourceTracker::GetInstance()-> + PluginResourceForHostResource(decoder); + ppp_video_decoder_target()->NotifyError( + decoder.instance(), plugin_decoder, error); +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/ppp_video_decoder_proxy.h b/ppapi/proxy/ppp_video_decoder_proxy.h new file mode 100644 index 0000000..c211a89 --- /dev/null +++ b/ppapi/proxy/ppp_video_decoder_proxy.h @@ -0,0 +1,52 @@ +// Copyright (c) 2011 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. + +#ifndef PPAPI_PROXY_PPP_VIDEO_DECODER_PROXY_H_ +#define PPAPI_PROXY_PPP_VIDEO_DECODER_PROXY_H_ + +#include "ppapi/c/dev/ppp_video_decoder_dev.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/host_resource.h" +#include "ppapi/proxy/interface_proxy.h" + +struct PP_Picture_Dev; +struct PP_Size; + +namespace pp { +namespace proxy { + +class PPP_VideoDecoder_Proxy : public InterfaceProxy { + public: + PPP_VideoDecoder_Proxy(Dispatcher* dispatcher, const void* target_interface); + virtual ~PPP_VideoDecoder_Proxy(); + + static const Info* GetInfo(); + + const PPP_VideoDecoder_Dev* ppp_video_decoder_target() const { + return static_cast<const PPP_VideoDecoder_Dev*>(target_interface()); + } + + // InterfaceProxy implementation. + virtual bool OnMessageReceived(const IPC::Message& msg); + + private: + // Message handlers. + void OnMsgProvidePictureBuffers(const HostResource& decoder, + uint32_t req_num_of_buffers, + const PP_Size& dimensions); + void OnMsgDismissPictureBuffer(const HostResource& decoder, + int32_t picture_id); + void OnMsgPictureReady( + const HostResource& decoder, const PP_Picture_Dev& picture_buffer); + void OnMsgNotifyEndOfStream(const HostResource& decoder); + void OnMsgNotifyError(const HostResource& decoder, + PP_VideoDecodeError_Dev error); + + DISALLOW_COPY_AND_ASSIGN(PPP_VideoDecoder_Proxy); +}; + +} // namespace proxy +} // namespace pp + +#endif // PPAPI_PROXY_PPP_VIDEO_DECODER_PROXY_H_ diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc index 57da2e0..dd87a84 100644 --- a/ppapi/proxy/resource_creation_proxy.cc +++ b/ppapi/proxy/resource_creation_proxy.cc @@ -31,6 +31,7 @@ #include "ppapi/proxy/ppb_surface_3d_proxy.h" #include "ppapi/proxy/ppb_url_loader_proxy.h" #include "ppapi/proxy/ppb_url_request_info_proxy.h" +#include "ppapi/proxy/ppb_video_decoder_proxy.h" #include "ppapi/shared_impl/font_impl.h" #include "ppapi/shared_impl/function_group_base.h" #include "ppapi/shared_impl/input_event_impl.h" @@ -300,8 +301,8 @@ PP_Resource ResourceCreationProxy::CreateVideoDecoder( PP_Instance instance, PP_Resource context3d_id, const PP_VideoConfigElement* config) { - NOTIMPLEMENTED(); - return 0; + return PPB_VideoDecoder_Proxy::CreateProxyResource( + instance, context3d_id, config); } PP_Resource ResourceCreationProxy::CreateVideoLayer( |