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