1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ppapi/proxy/ppp_video_decoder_proxy.h" 6 7 #include "ppapi/proxy/host_dispatcher.h" 8 #include "ppapi/proxy/plugin_globals.h" 9 #include "ppapi/proxy/plugin_resource_tracker.h" 10 #include "ppapi/proxy/ppapi_messages.h" 11 #include "ppapi/proxy/ppb_video_decoder_proxy.h" 12 #include "ppapi/thunk/enter.h" 13 #include "ppapi/thunk/ppb_video_decoder_api.h" 14 #include "ppapi/thunk/thunk.h" 15 16 using ppapi::thunk::PPB_VideoDecoder_API; 17 18 namespace ppapi { 19 namespace proxy { 20 21 namespace { 22 23 void ProvidePictureBuffers(PP_Instance instance, PP_Resource decoder, 24 uint32_t req_num_of_bufs, 25 const PP_Size* dimensions, 26 uint32_t texture_target) { 27 HostResource decoder_resource; 28 decoder_resource.SetHostResource(instance, decoder); 29 30 HostDispatcher::GetForInstance(instance)->Send( 31 new PpapiMsg_PPPVideoDecoder_ProvidePictureBuffers( 32 API_ID_PPP_VIDEO_DECODER_DEV, 33 decoder_resource, req_num_of_bufs, *dimensions, texture_target)); 34 } 35 36 void DismissPictureBuffer(PP_Instance instance, PP_Resource decoder, 37 int32_t picture_buffer_id) { 38 HostResource decoder_resource; 39 decoder_resource.SetHostResource(instance, decoder); 40 41 HostDispatcher::GetForInstance(instance)->Send( 42 new PpapiMsg_PPPVideoDecoder_DismissPictureBuffer( 43 API_ID_PPP_VIDEO_DECODER_DEV, 44 decoder_resource, picture_buffer_id)); 45 } 46 47 void PictureReady(PP_Instance instance, PP_Resource decoder, 48 const PP_Picture_Dev* picture) { 49 HostResource decoder_resource; 50 decoder_resource.SetHostResource(instance, decoder); 51 52 HostDispatcher::GetForInstance(instance)->Send( 53 new PpapiMsg_PPPVideoDecoder_PictureReady( 54 API_ID_PPP_VIDEO_DECODER_DEV, decoder_resource, *picture)); 55 } 56 57 void NotifyError(PP_Instance instance, PP_Resource decoder, 58 PP_VideoDecodeError_Dev error) { 59 HostResource decoder_resource; 60 decoder_resource.SetHostResource(instance, decoder); 61 62 // It's possible that the error we're being notified about is happening 63 // because the instance is shutting down. In this case, our instance may 64 // already have been removed from the HostDispatcher map. 65 HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); 66 if (dispatcher) { 67 dispatcher->Send( 68 new PpapiMsg_PPPVideoDecoder_NotifyError( 69 API_ID_PPP_VIDEO_DECODER_DEV, decoder_resource, error)); 70 } 71 } 72 73 static const PPP_VideoDecoder_Dev video_decoder_interface = { 74 &ProvidePictureBuffers, 75 &DismissPictureBuffer, 76 &PictureReady, 77 &NotifyError 78 }; 79 80 InterfaceProxy* CreateVideoDecoderPPPProxy(Dispatcher* dispatcher) { 81 return new PPP_VideoDecoder_Proxy(dispatcher); 82 } 83 84 } // namespace 85 86 PPP_VideoDecoder_Proxy::PPP_VideoDecoder_Proxy(Dispatcher* dispatcher) 87 : InterfaceProxy(dispatcher), 88 ppp_video_decoder_impl_(NULL) { 89 if (dispatcher->IsPlugin()) { 90 ppp_video_decoder_impl_ = static_cast<const PPP_VideoDecoder_Dev*>( 91 dispatcher->local_get_interface()(PPP_VIDEODECODER_DEV_INTERFACE)); 92 } 93 } 94 95 PPP_VideoDecoder_Proxy::~PPP_VideoDecoder_Proxy() { 96 } 97 98 // static 99 const InterfaceProxy::Info* PPP_VideoDecoder_Proxy::GetInfo() { 100 static const Info info = { 101 &video_decoder_interface, 102 PPP_VIDEODECODER_DEV_INTERFACE, 103 API_ID_PPP_VIDEO_DECODER_DEV, 104 false, 105 &CreateVideoDecoderPPPProxy, 106 }; 107 return &info; 108 } 109 110 bool PPP_VideoDecoder_Proxy::OnMessageReceived(const IPC::Message& msg) { 111 if (!dispatcher()->IsPlugin()) 112 return false; 113 114 bool handled = true; 115 IPC_BEGIN_MESSAGE_MAP(PPP_VideoDecoder_Proxy, msg) 116 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_ProvidePictureBuffers, 117 OnMsgProvidePictureBuffers) 118 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_DismissPictureBuffer, 119 OnMsgDismissPictureBuffer) 120 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_PictureReady, 121 OnMsgPictureReady) 122 IPC_MESSAGE_HANDLER(PpapiMsg_PPPVideoDecoder_NotifyError, 123 OnMsgNotifyError) 124 IPC_MESSAGE_UNHANDLED(handled = false) 125 IPC_END_MESSAGE_MAP() 126 DCHECK(handled); 127 return handled; 128 } 129 130 void PPP_VideoDecoder_Proxy::OnMsgProvidePictureBuffers( 131 const HostResource& decoder, 132 uint32_t req_num_of_bufs, 133 const PP_Size& dimensions, 134 uint32_t texture_target) { 135 PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> 136 PluginResourceForHostResource(decoder); 137 if (!plugin_decoder) 138 return; 139 CallWhileUnlocked(ppp_video_decoder_impl_->ProvidePictureBuffers, 140 decoder.instance(), 141 plugin_decoder, 142 req_num_of_bufs, 143 &dimensions, 144 texture_target); 145 } 146 147 void PPP_VideoDecoder_Proxy::OnMsgDismissPictureBuffer( 148 const HostResource& decoder, int32_t picture_id) { 149 PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> 150 PluginResourceForHostResource(decoder); 151 if (!plugin_decoder) 152 return; 153 CallWhileUnlocked(ppp_video_decoder_impl_->DismissPictureBuffer, 154 decoder.instance(), 155 plugin_decoder, 156 picture_id); 157 } 158 159 void PPP_VideoDecoder_Proxy::OnMsgPictureReady( 160 const HostResource& decoder, const PP_Picture_Dev& picture) { 161 PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> 162 PluginResourceForHostResource(decoder); 163 if (!plugin_decoder) 164 return; 165 CallWhileUnlocked(ppp_video_decoder_impl_->PictureReady, 166 decoder.instance(), 167 plugin_decoder, 168 &picture); 169 } 170 171 void PPP_VideoDecoder_Proxy::OnMsgNotifyError( 172 const HostResource& decoder, PP_VideoDecodeError_Dev error) { 173 PP_Resource plugin_decoder = PluginGlobals::Get()->plugin_resource_tracker()-> 174 PluginResourceForHostResource(decoder); 175 if (!plugin_decoder) 176 return; 177 CallWhileUnlocked(ppp_video_decoder_impl_->NotifyError, 178 decoder.instance(), 179 plugin_decoder, 180 error); 181 } 182 183 } // namespace proxy 184 } // namespace ppapi 185