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

  HostDispatcher::GetForInstance(instance)->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);

  HostDispatcher::GetForInstance(instance)->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);

  HostDispatcher::GetForInstance(instance)->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
