| // Copyright (c) 2012 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/plugin_globals.h" |
| #include "ppapi/proxy/plugin_resource_tracker.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_dev_api.h" |
| #include "ppapi/thunk/thunk.h" |
| |
| namespace ppapi { |
| namespace proxy { |
| |
| namespace { |
| |
| void ProvidePictureBuffers(PP_Instance instance, PP_Resource decoder, |
| uint32_t req_num_of_bufs, |
| const PP_Size* dimensions, |
| uint32_t texture_target) { |
| HostResource decoder_resource; |
| decoder_resource.SetHostResource(instance, decoder); |
| |
| // This is called by the graphics system in response to a message from the |
| // GPU process. These messages will not be synchronized with the lifetime |
| // of the plugin so we need to null-check here. |
| HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| if (dispatcher) { |
| dispatcher->Send(new PpapiMsg_PPPVideoDecoder_ProvidePictureBuffers( |
| API_ID_PPP_VIDEO_DECODER_DEV, |
| decoder_resource, req_num_of_bufs, *dimensions, texture_target)); |
| } |
| } |
| |
| void DismissPictureBuffer(PP_Instance instance, PP_Resource decoder, |
| int32_t picture_buffer_id) { |
| HostResource decoder_resource; |
| decoder_resource.SetHostResource(instance, decoder); |
| |
| // Null check as in ProvidePictureBuffers above. |
| HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| if (dispatcher) { |
| dispatcher->Send(new PpapiMsg_PPPVideoDecoder_DismissPictureBuffer( |
| API_ID_PPP_VIDEO_DECODER_DEV, |
| decoder_resource, picture_buffer_id)); |
| } |
| } |
| |
| void PictureReady(PP_Instance instance, PP_Resource decoder, |
| const PP_Picture_Dev* picture) { |
| HostResource decoder_resource; |
| decoder_resource.SetHostResource(instance, decoder); |
| |
| // Null check as in ProvidePictureBuffers above. |
| HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| if (dispatcher) { |
| dispatcher->Send(new PpapiMsg_PPPVideoDecoder_PictureReady( |
| API_ID_PPP_VIDEO_DECODER_DEV, decoder_resource, *picture)); |
| } |
| } |
| |
| void NotifyError(PP_Instance instance, PP_Resource decoder, |
| PP_VideoDecodeError_Dev error) { |
| HostResource decoder_resource; |
| decoder_resource.SetHostResource(instance, decoder); |
| |
| // It's possible that the error we're being notified about is happening |
| // because the instance is shutting down. In this case, our instance may |
| // already have been removed from the HostDispatcher map. |
| HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); |
| if (dispatcher) { |
| dispatcher->Send( |
| new PpapiMsg_PPPVideoDecoder_NotifyError( |
| API_ID_PPP_VIDEO_DECODER_DEV, decoder_resource, error)); |
| } |
| } |
| |
| static const PPP_VideoDecoder_Dev video_decoder_interface = { |
| &ProvidePictureBuffers, |
| &DismissPictureBuffer, |
| &PictureReady, |
| &NotifyError |
| }; |
| |
| } // namespace |
| |
| PPP_VideoDecoder_Proxy::PPP_VideoDecoder_Proxy(Dispatcher* dispatcher) |
| : InterfaceProxy(dispatcher), |
| ppp_video_decoder_impl_(NULL) { |
| if (dispatcher->IsPlugin()) { |
| ppp_video_decoder_impl_ = static_cast<const PPP_VideoDecoder_Dev*>( |
| dispatcher->local_get_interface()(PPP_VIDEODECODER_DEV_INTERFACE)); |
| } |
| } |
| |
| PPP_VideoDecoder_Proxy::~PPP_VideoDecoder_Proxy() { |
| } |
| |
| // static |
| const PPP_VideoDecoder_Dev* PPP_VideoDecoder_Proxy::GetProxyInterface() { |
| return &video_decoder_interface; |
| } |
| |
| bool PPP_VideoDecoder_Proxy::OnMessageReceived(const IPC::Message& msg) { |
| if (!dispatcher()->IsPlugin()) |
| return false; |
| |
| 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_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, |
| uint32_t texture_target) { |
| PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> |
| PluginResourceForHostResource(decoder); |
| if (!plugin_decoder) |
| return; |
| CallWhileUnlocked(ppp_video_decoder_impl_->ProvidePictureBuffers, |
| decoder.instance(), |
| plugin_decoder, |
| req_num_of_bufs, |
| &dimensions, |
| texture_target); |
| } |
| |
| void PPP_VideoDecoder_Proxy::OnMsgDismissPictureBuffer( |
| const HostResource& decoder, int32_t picture_id) { |
| PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> |
| PluginResourceForHostResource(decoder); |
| if (!plugin_decoder) |
| return; |
| CallWhileUnlocked(ppp_video_decoder_impl_->DismissPictureBuffer, |
| decoder.instance(), |
| plugin_decoder, |
| picture_id); |
| } |
| |
| void PPP_VideoDecoder_Proxy::OnMsgPictureReady( |
| const HostResource& decoder, const PP_Picture_Dev& picture) { |
| PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> |
| PluginResourceForHostResource(decoder); |
| if (!plugin_decoder) |
| return; |
| CallWhileUnlocked(ppp_video_decoder_impl_->PictureReady, |
| decoder.instance(), |
| plugin_decoder, |
| &picture); |
| } |
| |
| void PPP_VideoDecoder_Proxy::OnMsgNotifyError( |
| const HostResource& decoder, PP_VideoDecodeError_Dev error) { |
| PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> |
| PluginResourceForHostResource(decoder); |
| if (!plugin_decoder) |
| return; |
| CallWhileUnlocked(ppp_video_decoder_impl_->NotifyError, |
| decoder.instance(), |
| plugin_decoder, |
| error); |
| } |
| |
| } // namespace proxy |
| } // namespace ppapi |