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 | |
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
36 files changed, 1067 insertions, 161 deletions
diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc index 36f61c9..710d9bb 100644 --- a/chrome/test/ui/ppapi_uitest.cc +++ b/chrome/test/ui/ppapi_uitest.cc @@ -215,6 +215,9 @@ TEST_PPAPI_OUT_OF_PROCESS(Memory) TEST_PPAPI_IN_PROCESS(QueryPolicy) //TEST_PPAPI_OUT_OF_PROCESS(QueryPolicy) +TEST_PPAPI_IN_PROCESS(VideoDecoder) +TEST_PPAPI_OUT_OF_PROCESS(VideoDecoder) + // http://crbug.com/90039 and http://crbug.com/83443 (Mac) TEST_F(PPAPITest, FAILS_FileIO) { RunTestViaHTTP("FileIO"); @@ -264,9 +267,3 @@ TEST_PPAPI_IN_PROCESS(UMA) TEST_F(OutOfProcessPPAPITest, FAILS_UMA) { RunTest("UMA"); } - -TEST_PPAPI_IN_PROCESS(VideoDecoder) -// There is no proxy yet (vrk is adding it). -TEST_F(OutOfProcessPPAPITest, FAILS_VideoDecoder) { - RunTest("VideoDecoder"); -} diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 8291648..b37e787 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -552,7 +552,7 @@ void GpuCommandBufferStub::ReportState() { } void GpuCommandBufferStub::OnCreateVideoDecoder( - const std::vector<uint32>& configs, + const std::vector<int32>& configs, IPC::Message* reply_message) { video_decoder_.reset( new GpuVideoDecodeAccelerator(this, route_id_, this)); diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index f6e31f8..c50c22a 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -114,7 +114,7 @@ class GpuCommandBufferStub void OnGetTransferBuffer(int32 id, IPC::Message* reply_message); void OnResizeOffscreenFrameBuffer(const gfx::Size& size); - void OnCreateVideoDecoder(const std::vector<uint32>& configs, + void OnCreateVideoDecoder(const std::vector<int32>& configs, IPC::Message* reply_message); void OnDestroyVideoDecoder(); diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 2861a25..b789fed 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -388,7 +388,7 @@ IPC_SYNC_MESSAGE_ROUTED1_2(GpuCommandBufferMsg_GetTransferBuffer, // Create and initialize a hardware video decoder. IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_CreateVideoDecoder, - std::vector<uint32> /* configs */) + std::vector<int32> /* configs */) // Release all resources held by the hardware video decoder associated with this // stub. diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.cc b/content/common/gpu/media/gpu_video_decode_accelerator.cc index 777a13b..a0c9eb9 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.cc +++ b/content/common/gpu/media/gpu_video_decode_accelerator.cc @@ -94,7 +94,7 @@ void GpuVideoDecodeAccelerator::NotifyError( } void GpuVideoDecodeAccelerator::Initialize( - const std::vector<uint32>& configs, + const std::vector<int32>& configs, IPC::Message* init_done_msg) { DCHECK(!video_decode_accelerator_.get()); DCHECK(!init_done_msg_); diff --git a/content/common/gpu/media/gpu_video_decode_accelerator.h b/content/common/gpu/media/gpu_video_decode_accelerator.h index e1d4261..624f04f 100644 --- a/content/common/gpu/media/gpu_video_decode_accelerator.h +++ b/content/common/gpu/media/gpu_video_decode_accelerator.h @@ -45,7 +45,7 @@ class GpuVideoDecodeAccelerator // Initialize the accelerator with the given configuration and send the // |init_done_msg| when done. - void Initialize(const std::vector<uint32>& configs, + void Initialize(const std::vector<int32>& configs, IPC::Message* init_done_msg); private: diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc index fbfedef..f2e7981 100644 --- a/content/common/gpu/media/omx_video_decode_accelerator.cc +++ b/content/common/gpu/media/omx_video_decode_accelerator.cc @@ -99,7 +99,7 @@ void OmxVideoDecodeAccelerator::SetEglState( } bool OmxVideoDecodeAccelerator::VerifyConfigs( - const std::vector<uint32>& configs) { + const std::vector<int32>& configs) { size_t cur; for (cur = 0; cur + 1 < configs.size(); cur++) { uint32 n = configs[cur++]; @@ -141,7 +141,7 @@ static void InitParam(const OmxVideoDecodeAccelerator& dec, T* param) { param->nSize = sizeof(T); } -bool OmxVideoDecodeAccelerator::Initialize(const std::vector<uint32>& config) { +bool OmxVideoDecodeAccelerator::Initialize(const std::vector<int32>& config) { DCHECK_EQ(message_loop_, MessageLoop::current()); RETURN_ON_FAILURE(VerifyConfigs(config), "Invalid config", INVALID_ARGUMENT, false); diff --git a/content/common/gpu/media/omx_video_decode_accelerator.h b/content/common/gpu/media/omx_video_decode_accelerator.h index 49126b7..4b57c82 100644 --- a/content/common/gpu/media/omx_video_decode_accelerator.h +++ b/content/common/gpu/media/omx_video_decode_accelerator.h @@ -42,7 +42,7 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator { OmxVideoDecodeAccelerator(media::VideoDecodeAccelerator::Client* client); // media::VideoDecodeAccelerator implementation. - bool Initialize(const std::vector<uint32>& config) OVERRIDE; + bool Initialize(const std::vector<int32>& config) OVERRIDE; void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; virtual void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) OVERRIDE; @@ -83,7 +83,7 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator { typedef std::map<int32, OutputPicture> OutputPictureById; // Verify that |config| is compatible with this class and hardware. - bool VerifyConfigs(const std::vector<uint32>& configs); + bool VerifyConfigs(const std::vector<int32>& configs); MessageLoop* message_loop_; OMX_HANDLETYPE component_handle_; diff --git a/content/renderer/gpu/command_buffer_proxy.cc b/content/renderer/gpu/command_buffer_proxy.cc index c4ec7a7..8d11738 100644 --- a/content/renderer/gpu/command_buffer_proxy.cc +++ b/content/renderer/gpu/command_buffer_proxy.cc @@ -393,7 +393,7 @@ void CommandBufferProxy::SetNotifyRepaintTask(Task* task) { scoped_refptr<GpuVideoDecodeAcceleratorHost> CommandBufferProxy::CreateVideoDecoder( - const std::vector<uint32>& configs, + const std::vector<int32>& configs, media::VideoDecodeAccelerator::Client* client) { video_decoder_host_ = new GpuVideoDecodeAcceleratorHost( channel_, route_id_, client); diff --git a/content/renderer/gpu/command_buffer_proxy.h b/content/renderer/gpu/command_buffer_proxy.h index c8600f8..26687b9 100644 --- a/content/renderer/gpu/command_buffer_proxy.h +++ b/content/renderer/gpu/command_buffer_proxy.h @@ -90,7 +90,7 @@ class CommandBufferProxy : public gpu::CommandBuffer, // the GPU process, even if this returns non-NULL. In this case the client is // notified of an error later. scoped_refptr<GpuVideoDecodeAcceleratorHost> CreateVideoDecoder( - const std::vector<uint32>& configs, + const std::vector<int32>& configs, media::VideoDecodeAccelerator::Client* client); #if defined(OS_MACOSX) diff --git a/content/renderer/gpu/gpu_channel_host.cc b/content/renderer/gpu/gpu_channel_host.cc index a82ce74..9229183 100644 --- a/content/renderer/gpu/gpu_channel_host.cc +++ b/content/renderer/gpu/gpu_channel_host.cc @@ -135,7 +135,7 @@ CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer( GpuVideoDecodeAcceleratorHost* GpuChannelHost::CreateVideoDecoder( int command_buffer_route_id, - const std::vector<uint32>& configs, + const std::vector<int32>& configs, media::VideoDecodeAccelerator::Client* client) { ProxyMap::iterator it = proxies_.find(command_buffer_route_id); DCHECK(it != proxies_.end()); diff --git a/content/renderer/gpu/gpu_channel_host.h b/content/renderer/gpu/gpu_channel_host.h index 4f77738..ec5cd20 100644 --- a/content/renderer/gpu/gpu_channel_host.h +++ b/content/renderer/gpu/gpu_channel_host.h @@ -86,7 +86,7 @@ class GpuChannelHost : public IPC::Channel::Listener, // Returned pointer is owned by the CommandBufferProxy for |route_id|. GpuVideoDecodeAcceleratorHost* CreateVideoDecoder( int command_buffer_route_id, - const std::vector<uint32>& configs, + const std::vector<int32>& configs, media::VideoDecodeAccelerator::Client* client); // Destroy a command buffer created by this channel. diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc index 599e3ee..99c94af 100644 --- a/content/renderer/gpu/gpu_video_decode_accelerator_host.cc +++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.cc @@ -60,7 +60,7 @@ bool GpuVideoDecodeAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { } bool GpuVideoDecodeAcceleratorHost::Initialize( - const std::vector<uint32>& configs) { + const std::vector<int32>& configs) { NOTREACHED(); return true; } diff --git a/content/renderer/gpu/gpu_video_decode_accelerator_host.h b/content/renderer/gpu/gpu_video_decode_accelerator_host.h index 02a8a3e..b9a2181 100644 --- a/content/renderer/gpu/gpu_video_decode_accelerator_host.h +++ b/content/renderer/gpu/gpu_video_decode_accelerator_host.h @@ -30,7 +30,7 @@ class GpuVideoDecodeAcceleratorHost virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; // media::VideoDecodeAccelerator implementation. - virtual bool Initialize(const std::vector<uint32>& configs) OVERRIDE; + virtual bool Initialize(const std::vector<int32>& configs) OVERRIDE; virtual void Decode(const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; virtual void AssignPictureBuffers( const std::vector<media::PictureBuffer>& buffers) OVERRIDE; diff --git a/content/renderer/pepper_platform_video_decoder_impl.cc b/content/renderer/pepper_platform_video_decoder_impl.cc index 39733a9..79600bb 100644 --- a/content/renderer/pepper_platform_video_decoder_impl.cc +++ b/content/renderer/pepper_platform_video_decoder_impl.cc @@ -24,7 +24,7 @@ PlatformVideoDecoderImpl::PlatformVideoDecoderImpl( PlatformVideoDecoderImpl::~PlatformVideoDecoderImpl() {} -bool PlatformVideoDecoderImpl::Initialize(const std::vector<uint32>& configs) { +bool PlatformVideoDecoderImpl::Initialize(const std::vector<int32>& configs) { // TODO(vrk): Support multiple decoders. if (decoder_) return true; diff --git a/content/renderer/pepper_platform_video_decoder_impl.h b/content/renderer/pepper_platform_video_decoder_impl.h index d1e8e55..36447a7 100644 --- a/content/renderer/pepper_platform_video_decoder_impl.h +++ b/content/renderer/pepper_platform_video_decoder_impl.h @@ -21,7 +21,7 @@ class PlatformVideoDecoderImpl int32 command_buffer_route_id); // PlatformVideoDecoder (a.k.a. VideoDecodeAccelerator) implementation. - virtual bool Initialize(const std::vector<uint32>& configs) OVERRIDE; + virtual bool Initialize(const std::vector<int32>& configs) OVERRIDE; virtual void Decode( const media::BitstreamBuffer& bitstream_buffer) OVERRIDE; virtual void AssignPictureBuffers( diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h index 6ac1c0e..7ce1785 100644 --- a/media/video/video_decode_accelerator.h +++ b/media/video/video_decode_accelerator.h @@ -229,7 +229,7 @@ class VideoDecodeAccelerator // |config| is the configuration on which the decoder should be initialized. // // Returns true when command successfully accepted. Otherwise false. - virtual bool Initialize(const std::vector<uint32>& config) = 0; + virtual bool Initialize(const std::vector<int32>& config) = 0; // Decodes given bitstream buffer. Once decoder is done with processing // |bitstream_buffer| it will call NotifyEndOfBitstreamBuffer() with the diff --git a/ppapi/c/dev/ppb_video_decoder_dev.h b/ppapi/c/dev/ppb_video_decoder_dev.h index cf188d2..5a3417e 100644 --- a/ppapi/c/dev/ppb_video_decoder_dev.h +++ b/ppapi/c/dev/ppb_video_decoder_dev.h @@ -38,6 +38,8 @@ struct PPB_VideoDecoder_Dev { // |decoder_config| the configuration to use to initialize the decoder. // // The created decoder is returned as PP_Resource. 0 means failure. + // TODO(fischman/vrk): Get rid of silly PP_VideoConfigElement* vector in favor + // of config struct. PP_Resource (*Create)(PP_Instance instance, PP_Resource context, const PP_VideoConfigElement* decoder_config); diff --git a/ppapi/examples/gles2/gles2.cc b/ppapi/examples/gles2/gles2.cc index e917374..aa3a4fb 100644 --- a/ppapi/examples/gles2/gles2.cc +++ b/ppapi/examples/gles2/gles2.cc @@ -298,7 +298,8 @@ void GLES2DemoInstance::DecodeNextNALU() { } void GLES2DemoInstance::ProvidePictureBuffers( - PP_Resource /* decoder */, uint32_t req_num_of_bufs, PP_Size dimensions) { + PP_Resource decoder, uint32_t req_num_of_bufs, PP_Size dimensions) { + assert(decoder == video_decoder_->pp_resource()); std::vector<PP_PictureBuffer_Dev> buffers; for (uint32_t i = 0; i < req_num_of_bufs; i++) { PP_PictureBuffer_Dev buffer; @@ -311,16 +312,18 @@ void GLES2DemoInstance::ProvidePictureBuffers( video_decoder_->AssignPictureBuffers(buffers); } -void GLES2DemoInstance::DismissPictureBuffer(PP_Resource /* decoder */, +void GLES2DemoInstance::DismissPictureBuffer(PP_Resource decoder, int32_t picture_buffer_id) { + assert(decoder == video_decoder_->pp_resource()); PictureBufferMap::iterator it = buffers_by_id_.find(picture_buffer_id); assert(it != buffers_by_id_.end()); DeleteTexture(it->second.texture_id); buffers_by_id_.erase(it); } -void GLES2DemoInstance::PictureReady(PP_Resource /* decoder */, +void GLES2DemoInstance::PictureReady(PP_Resource decoder, const PP_Picture_Dev& picture) { + assert(decoder == video_decoder_->pp_resource()); if (first_frame_delivered_ticks_ == -1) assert((first_frame_delivered_ticks_ = core_if_->GetTimeTicks()) != -1); if (is_painting_) { @@ -333,11 +336,13 @@ void GLES2DemoInstance::PictureReady(PP_Resource /* decoder */, Render(it->second); } -void GLES2DemoInstance::EndOfStream(PP_Resource /* decoder */) { +void GLES2DemoInstance::EndOfStream(PP_Resource decoder) { + assert(decoder == video_decoder_->pp_resource()); } -void GLES2DemoInstance::NotifyError(PP_Resource /* decoder */, +void GLES2DemoInstance::NotifyError(PP_Resource decoder, PP_VideoDecodeError_Dev error) { + assert(decoder == video_decoder_->pp_resource()); LogError(this).s() << "Received error: " << error; assert(!"Unexpected error; see stderr for details"); } @@ -414,7 +419,7 @@ void GLES2DemoInstance::PaintFinished(int32_t result, int picture_buffer_id) { while (!pictures_pending_paint_.empty() && !is_painting_) { PP_Picture_Dev picture = pictures_pending_paint_.front(); pictures_pending_paint_.pop_front(); - PictureReady(0 /* ignored */, picture); + PictureReady(video_decoder_->pp_resource(), picture); } } diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 68a5364..49e392d 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -126,6 +126,8 @@ 'proxy/ppb_var_deprecated_proxy.h', 'proxy/ppb_var_proxy.cc', 'proxy/ppb_var_proxy.h', + 'proxy/ppb_video_decoder_proxy.cc', + 'proxy/ppb_video_decoder_proxy.h', 'proxy/ppp_class_proxy.cc', 'proxy/ppp_class_proxy.h', 'proxy/ppp_graphics_3d_proxy.cc', @@ -138,6 +140,8 @@ 'proxy/ppp_instance_proxy.h', 'proxy/ppp_messaging_proxy.cc', 'proxy/ppp_messaging_proxy.h', + 'proxy/ppp_video_decoder_proxy.cc', + 'proxy/ppp_video_decoder_proxy.h', 'proxy/proxy_channel.cc', 'proxy/proxy_channel.h', 'proxy/proxy_module.cc', diff --git a/ppapi/ppapi_shared.gypi b/ppapi/ppapi_shared.gypi index 7a3b9e3..51865bd 100644 --- a/ppapi/ppapi_shared.gypi +++ b/ppapi/ppapi_shared.gypi @@ -60,6 +60,8 @@ 'shared_impl/url_util_impl.h', 'shared_impl/var.cc', 'shared_impl/var.h', + 'shared_impl/video_decoder_impl.cc', + 'shared_impl/video_decoder_impl.h', 'shared_impl/webkit_forwarding.cc', 'shared_impl/webkit_forwarding.h', 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( diff --git a/ppapi/shared_impl/tracker_base.h b/ppapi/shared_impl/tracker_base.h index 7d4d9e8..7790ea3 100644 --- a/ppapi/shared_impl/tracker_base.h +++ b/ppapi/shared_impl/tracker_base.h @@ -23,6 +23,8 @@ class Var; // called "Tracker", and this would be used in both the plugin side of the // proxy as well as the implementation in the renderer. Currently, all this // does is forward to the process-type-specific tracker to get the information. +// TODO(fischman/vrk): When brettw fixes the TODO above, fix the ugliness in +// VideoDecoderImpl accordingly. class TrackerBase { public: // Must be called before any other function that uses the TrackerBase. diff --git a/ppapi/shared_impl/video_decoder_impl.cc b/ppapi/shared_impl/video_decoder_impl.cc new file mode 100644 index 0000000..ae185c1 --- /dev/null +++ b/ppapi/shared_impl/video_decoder_impl.cc @@ -0,0 +1,109 @@ +// 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/shared_impl/video_decoder_impl.h" + +#include "base/logging.h" +#include "gpu/command_buffer/client/gles2_implementation.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/thunk/ppb_context_3d_api.h" +#include "ppapi/thunk/enter.h" + +using ppapi::thunk::PPB_Context3D_API; + +namespace ppapi { + +VideoDecoderImpl::VideoDecoderImpl() + : flush_callback_(PP_MakeCompletionCallback(NULL, NULL)), + reset_callback_(PP_MakeCompletionCallback(NULL, NULL)), + context3d_id_(0), + gles2_impl_(NULL) { +} + +thunk::PPB_VideoDecoder_API* VideoDecoderImpl::AsPPB_VideoDecoder_API() { + return this; +} + +VideoDecoderImpl::~VideoDecoderImpl() { +} + +bool VideoDecoderImpl::Init(PP_Resource context3d_id, + PPB_Context3D_API* context3d, + const PP_VideoConfigElement* decoder_config) { + if (!context3d || !decoder_config || !context3d_id) + return false; + + DCHECK(!gles2_impl_ && !context3d_id_); + gles2_impl_ = context3d->GetGLES2Impl(); + AddRefResource(context3d_id); + context3d_id_ = context3d_id; + return true; +} + +void VideoDecoderImpl::Destroy() { + context3d_id_ = 0; + gles2_impl_ = NULL; + UnrefResource(context3d_id_); +} + +void VideoDecoderImpl::SetFlushCallback(PP_CompletionCallback callback) { + CHECK(callback.func); + DCHECK(!flush_callback_.func); + flush_callback_ = callback; +} + +void VideoDecoderImpl::SetResetCallback(PP_CompletionCallback callback) { + CHECK(callback.func); + DCHECK(!reset_callback_.func); + reset_callback_ = callback; +} + +void VideoDecoderImpl::SetBitstreamBufferCallback( + int32 bitstream_buffer_id, PP_CompletionCallback callback) { + CHECK(bitstream_buffer_callbacks_.insert( + std::make_pair(bitstream_buffer_id, callback)).second); +} + +void VideoDecoderImpl::RunFlushCallback(int32 result) { + DCHECK(flush_callback_.func); + PP_RunAndClearCompletionCallback(&flush_callback_, result); +} + +void VideoDecoderImpl::RunResetCallback(int32 result) { + DCHECK(reset_callback_.func); + PP_RunAndClearCompletionCallback(&reset_callback_, result); +} + +void VideoDecoderImpl::RunBitstreamBufferCallback( + int32 bitstream_buffer_id, int32 result) { + CallbackById::iterator it = + bitstream_buffer_callbacks_.find(bitstream_buffer_id); + DCHECK(it != bitstream_buffer_callbacks_.end()); + PP_CompletionCallback cc = it->second; + bitstream_buffer_callbacks_.erase(it); + PP_RunCompletionCallback(&cc, PP_OK); +} + +void VideoDecoderImpl::FlushCommandBuffer() { + if (gles2_impl_) + gles2_impl_->Flush(); +} + +bool VideoDecoderImpl::CopyConfigsToVector( + const PP_VideoConfigElement* configs_to_copy, + std::vector<PP_VideoConfigElement>* out_configs) { + // TODO(fischman/vrk): This is still broken. We need to get rid of the silly + // PP_VideoConfigElement vector in favor of a struct (see TODO in + // ppb_video_decoder_dev.h). + const PP_VideoConfigElement* current = configs_to_copy; + while (current && *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR) { + out_configs->push_back(*current); + out_configs->push_back(*(current + 1)); + current += 2; + } + return true; +} + +} // namespace ppapi diff --git a/ppapi/shared_impl/video_decoder_impl.h b/ppapi/shared_impl/video_decoder_impl.h new file mode 100644 index 0000000..cc0da6d --- /dev/null +++ b/ppapi/shared_impl/video_decoder_impl.h @@ -0,0 +1,97 @@ +// 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_SHARED_IMPL_VIDEO_DECODER_IMPL_H_ +#define PPAPI_SHARED_IMPL_VIDEO_DECODER_IMPL_H_ + +#include <map> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/c/dev/ppb_video_decoder_dev.h" +#include "ppapi/shared_impl/resource_object_base.h" +#include "ppapi/thunk/ppb_video_decoder_api.h" + +namespace gpu { +namespace gles2 { +class GLES2Implementation; +} // namespace gles2 +} // namespace gpu + +namespace ppapi { +namespace thunk { +class PPB_Context3D_API; +} // namespace thunk +} // namespace ppapi + +namespace ppapi { + +// Implements the logic to set and run callbacks for various video decoder +// events. Both the proxy and the renderer implementation share this code. +class VideoDecoderImpl : public ResourceObjectBase, + public thunk::PPB_VideoDecoder_API { + public: + VideoDecoderImpl(); + virtual ~VideoDecoderImpl(); + + // ResourceObjectBase implementation. + virtual PPB_VideoDecoder_API* AsPPB_VideoDecoder_API() OVERRIDE; + + // PPB_VideoDecoder_API implementation. + virtual void Destroy() OVERRIDE; + + // Copy C-style config list into |out_configs| vector. + static bool CopyConfigsToVector( + const PP_VideoConfigElement* configs_to_copy, + std::vector<PP_VideoConfigElement>* out_configs); + + protected: + void SetFlushCallback(PP_CompletionCallback callback); + void SetResetCallback(PP_CompletionCallback callback); + void SetBitstreamBufferCallback( + int32 bitstream_buffer_id, PP_CompletionCallback callback); + + void RunFlushCallback(int32 result); + void RunResetCallback(int32 result); + void RunBitstreamBufferCallback(int32 bitstream_buffer_id, int32 result); + + // Tell command buffer to process all commands it has received so far. + void FlushCommandBuffer(); + + // Initialize the underlying decoder and return success status. + virtual bool Init(PP_Resource context3d_id, + thunk::PPB_Context3D_API* context, + const PP_VideoConfigElement* dec_config); + + // TODO(fischman/vrk): Remove accordingly when brettw has merged resource + // trackers. + virtual void AddRefResource(PP_Resource resource) = 0; + virtual void UnrefResource(PP_Resource resource) = 0; + + private: + // Key: bitstream_buffer_id, value: callback to run when bitstream decode is + // done. + typedef std::map<int32, PP_CompletionCallback> CallbackById; + + PP_CompletionCallback flush_callback_; + PP_CompletionCallback reset_callback_; + CallbackById bitstream_buffer_callbacks_; + + // The resource ID of the underlying Context3d object being used. Used only + // for reference counting to keep it alive for the lifetime of |*this|. + PP_Resource context3d_id_; + + // Reference to the GLES2Implementation owned by |context3d_id_|. + // Context3D is guaranteed to be alive for the lifetime of this class. + // In the out-of-process case, Context3D's gles2_impl() exists in the plugin + // process only, so gles2_impl_ is NULL in that case. + gpu::gles2::GLES2Implementation* gles2_impl_; + + DISALLOW_COPY_AND_ASSIGN(VideoDecoderImpl); +}; + +} // namespace ppapi + +#endif // PPAPI_SHARED_IMPL_VIDEO_DECODER_IMPL_H_ diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc index bb25863..184306f 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.cc +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.cc @@ -32,12 +32,7 @@ namespace webkit { namespace ppapi { PPB_VideoDecoder_Impl::PPB_VideoDecoder_Impl(PluginInstance* instance) - : Resource(instance), - callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), - context3d_id_(0), - flush_callback_(PP_BlockUntilComplete()), - reset_callback_(PP_BlockUntilComplete()), - gles2_impl_(NULL) { + : Resource(instance) { ppp_videodecoder_ = static_cast<const PPP_VideoDecoder_Dev*>(instance->module()-> GetPluginInterface(PPP_VIDEODECODER_DEV_INTERFACE)); @@ -54,53 +49,42 @@ PPB_VideoDecoder_API* PPB_VideoDecoder_Impl::AsPPB_VideoDecoder_API() { PP_Resource PPB_VideoDecoder_Impl::Create(PluginInstance* instance, 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_refptr<PPB_VideoDecoder_Impl> decoder( new PPB_VideoDecoder_Impl(instance)); - if (decoder->Init(context3d_id, config)) + if (decoder->Init(context3d_id, enter_context.object(), config)) return decoder->GetReference(); return 0; } bool PPB_VideoDecoder_Impl::Init(PP_Resource context3d_id, + PPB_Context3D_API* context3d, const PP_VideoConfigElement* config) { - if (!instance() || !context3d_id || !config) + if (!::ppapi::VideoDecoderImpl::Init(context3d_id, context3d, config)) return false; - EnterResourceNoLock<PPB_Context3D_API> enter(context3d_id, true); - if (enter.failed()) + std::vector<int32> copied; + if (!CopyConfigsToVector(config, &copied)) return false; - PPB_Context3D_Impl* context3d = - static_cast<PPB_Context3D_Impl*>(enter.object()); - context3d_id_ = context3d_id; - ResourceTracker::Get()->AddRefResource(context3d_id_); + PPB_Context3D_Impl* context3d_impl = + static_cast<PPB_Context3D_Impl*>(context3d); int command_buffer_route_id = - context3d->platform_context()->GetCommandBufferRouteId(); + context3d_impl->platform_context()->GetCommandBufferRouteId(); if (command_buffer_route_id == 0) return false; platform_video_decoder_ = instance()->delegate()->CreateVideoDecoder( this, command_buffer_route_id); - - gles2_impl_ = context3d->gles2_impl(); - if (!platform_video_decoder_) return false; - std::vector<uint32> copied; - // TODO(fischman,vrk): this is completely broken in that it fails to account - // for the semantic distinction between keys and values; it is certainly - // possible for a value to show up as 0, and that shouldn't terminate the - // config vector. Only a *key* of 0 should do so. - // TODO(vrk): This is assuming PP_VideoAttributeDictionary and - // VideoAttributeKey have identical enum values. There is no compiler - // assert to guarantee this. We either need to add such asserts or - // merge PP_VideoAttributeDictionary and VideoAttributeKey. - for (const PP_VideoConfigElement* current = config; - *current != PP_VIDEOATTR_DICTIONARY_TERMINATOR; ++current) { - copied.push_back(static_cast<uint32>(*current)); - } - FlushCommandBuffer(); return platform_video_decoder_->Initialize(copied); } @@ -119,8 +103,7 @@ int32_t PPB_VideoDecoder_Impl::Decode( media::BitstreamBuffer decode_buffer(bitstream_buffer->id, buffer->shared_memory()->handle(), static_cast<size_t>(buffer->size())); - CHECK(bitstream_buffer_callbacks_.insert(std::make_pair( - bitstream_buffer->id, callback)).second); + SetBitstreamBufferCallback(bitstream_buffer->id, callback); FlushCommandBuffer(); platform_video_decoder_->Decode(decode_buffer); @@ -159,9 +142,7 @@ int32_t PPB_VideoDecoder_Impl::Flush(PP_CompletionCallback callback) { if (!platform_video_decoder_) return PP_ERROR_BADRESOURCE; - // Store the callback to be called when Flush() is done. - // TODO(fischman,vrk): consider implications of already-outstanding callback. - flush_callback_ = callback; + SetFlushCallback(callback); FlushCommandBuffer(); platform_video_decoder_->Flush(); @@ -172,9 +153,7 @@ int32_t PPB_VideoDecoder_Impl::Reset(PP_CompletionCallback callback) { if (!platform_video_decoder_) return PP_ERROR_BADRESOURCE; - // Store the callback to be called when Reset() is done. - // TODO(fischman,vrk): consider implications of already-outstanding callback. - reset_callback_ = callback; + SetResetCallback(callback); FlushCommandBuffer(); platform_video_decoder_->Reset(); @@ -187,9 +166,7 @@ void PPB_VideoDecoder_Impl::Destroy() { FlushCommandBuffer(); platform_video_decoder_->Destroy(); - gles2_impl_ = NULL; - if (context3d_id_) - ResourceTracker::Get()->UnrefResource(context3d_id_); + ::ppapi::VideoDecoderImpl::Destroy(); platform_video_decoder_ = NULL; ppp_videodecoder_ = NULL; } @@ -250,41 +227,27 @@ void PPB_VideoDecoder_Impl::NotifyError( } void PPB_VideoDecoder_Impl::NotifyResetDone() { - if (reset_callback_.func == NULL) - return; - - // Call the callback that was stored to be called when Reset is done. - PP_RunAndClearCompletionCallback(&reset_callback_, PP_OK); + RunResetCallback(PP_OK); } void PPB_VideoDecoder_Impl::NotifyEndOfBitstreamBuffer( int32 bitstream_buffer_id) { - CallbackById::iterator it = - bitstream_buffer_callbacks_.find(bitstream_buffer_id); - DCHECK(it != bitstream_buffer_callbacks_.end()); - PP_CompletionCallback cc = it->second; - bitstream_buffer_callbacks_.erase(it); - PP_RunCompletionCallback(&cc, PP_OK); + RunBitstreamBufferCallback(bitstream_buffer_id, PP_OK); } void PPB_VideoDecoder_Impl::NotifyFlushDone() { - if (flush_callback_.func == NULL) - return; - - // Call the callback that was stored to be called when Flush is done. - PP_RunAndClearCompletionCallback(&flush_callback_, PP_OK); + RunFlushCallback(PP_OK); } void PPB_VideoDecoder_Impl::NotifyInitializeDone() { NOTREACHED() << "PlatformVideoDecoder::Initialize() is synchronous!"; } +void PPB_VideoDecoder_Impl::AddRefResource(PP_Resource resource) { + ResourceTracker::Get()->AddRefResource(resource); +} -void PPB_VideoDecoder_Impl::FlushCommandBuffer() { - // For the out-of-process case, |gles2_impl_| will be NULL in the renderer - // process. The VideoDecoder_Proxy is charged with the responsibility of - // doing this Flush() in the analogous places in the plugin process. - if (gles2_impl_) - gles2_impl_->Flush(); +void PPB_VideoDecoder_Impl::UnrefResource(PP_Resource resource) { + ResourceTracker::Get()->UnrefResource(resource); } } // namespace ppapi diff --git a/webkit/plugins/ppapi/ppb_video_decoder_impl.h b/webkit/plugins/ppapi/ppb_video_decoder_impl.h index 2347c4b..09f638e 100644 --- a/webkit/plugins/ppapi/ppb_video_decoder_impl.h +++ b/webkit/plugins/ppapi/ppb_video_decoder_impl.h @@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "ppapi/c/dev/pp_video_dev.h" #include "ppapi/c/pp_var.h" +#include "ppapi/shared_impl/video_decoder_impl.h" #include "ppapi/thunk/ppb_video_decoder_api.h" #include "webkit/plugins/ppapi/plugin_delegate.h" #include "webkit/plugins/ppapi/resource.h" @@ -26,8 +27,15 @@ struct PPP_VideoDecoder_Dev; namespace gpu { namespace gles2 { class GLES2Implementation; -} -} +} // namespace gles2 +} // namespace gpu + +namespace ppapi { +namespace thunk { +class PPB_Context3D_API; +} // namespace thunk +} // namespace ppapi + namespace webkit { namespace ppapi { @@ -35,7 +43,7 @@ namespace ppapi { class PluginInstance; class PPB_VideoDecoder_Impl : public Resource, - public ::ppapi::thunk::PPB_VideoDecoder_API, + public ::ppapi::VideoDecoderImpl, public media::VideoDecodeAccelerator::Client { public: virtual ~PPB_VideoDecoder_Impl(); @@ -71,44 +79,24 @@ class PPB_VideoDecoder_Impl : public Resource, virtual void NotifyEndOfBitstreamBuffer(int32 buffer_id) OVERRIDE; virtual void NotifyResetDone() OVERRIDE; - private: - // Key: bitstream_buffer_id, value: callback to run when bitstream decode is - // done. - typedef std::map<int32, PP_CompletionCallback> CallbackById; + protected: + // VideoDecoderImpl implementation. + virtual bool Init(PP_Resource context3d_id, + ::ppapi::thunk::PPB_Context3D_API* context, + const PP_VideoConfigElement* dec_config) OVERRIDE; + virtual void AddRefResource(PP_Resource resource) OVERRIDE; + virtual void UnrefResource(PP_Resource resource) OVERRIDE; + private: explicit PPB_VideoDecoder_Impl(PluginInstance* instance); - // Initialize the underlying decoder and return success status. - bool Init(PP_Resource context_id, const PP_VideoConfigElement* dec_config); - - // Tell command buffer to process all commands it has received so far. - void FlushCommandBuffer(); - // This is NULL before initialization, and if this PPB_VideoDecoder_Impl is // swapped with another. scoped_refptr<PluginDelegate::PlatformVideoDecoder> platform_video_decoder_; - // Factory to produce our callbacks. - base::ScopedCallbackFactory<PPB_VideoDecoder_Impl> callback_factory_; - - // The resource ID of the underlying Context3d object being used. Used only - // for reference counting to keep it alive for the lifetime of |*this|. - PP_Resource context3d_id_; - - PP_CompletionCallback flush_callback_; - PP_CompletionCallback reset_callback_; - CallbackById bitstream_buffer_callbacks_; - // Reference to the plugin requesting this interface. const PPP_VideoDecoder_Dev* ppp_videodecoder_; - // Reference to the GLES2Implementation owned by PPB_Context3D_Impl. - // PPB_Context3D_Impl is guaranteed to be alive for the lifetime of this - // class. - // In the out-of-process case, Context3D's gles2_impl() exists in the plugin - // process only, so gles2_impl_ is NULL in that case. - gpu::gles2::GLES2Implementation* gles2_impl_; - DISALLOW_COPY_AND_ASSIGN(PPB_VideoDecoder_Impl); }; |