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