blob: 576ba95a5d025d1964c6961b3496bcebb4674c99 [file] [log] [blame]
// 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