1// Copyright (c) 2014 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/cpp/video_decoder.h"
6
7#include "ppapi/c/pp_errors.h"
8#include "ppapi/c/ppb_video_decoder.h"
9#include "ppapi/cpp/completion_callback.h"
10#include "ppapi/cpp/instance_handle.h"
11#include "ppapi/cpp/module.h"
12#include "ppapi/cpp/module_impl.h"
13
14namespace pp {
15
16namespace {
17
18template <>
19const char* interface_name<PPB_VideoDecoder_0_1>() {
20  return PPB_VIDEODECODER_INTERFACE_0_1;
21}
22
23template <>
24const char* interface_name<PPB_VideoDecoder_0_2>() {
25  return PPB_VIDEODECODER_INTERFACE_0_2;
26}
27
28}  // namespace
29
30VideoDecoder::VideoDecoder() {
31}
32
33VideoDecoder::VideoDecoder(const InstanceHandle& instance) {
34  if (has_interface<PPB_VideoDecoder_0_1>()) {
35    PassRefFromConstructor(
36        get_interface<PPB_VideoDecoder_0_1>()->Create(instance.pp_instance()));
37  }
38}
39
40VideoDecoder::VideoDecoder(const VideoDecoder& other) : Resource(other) {
41}
42
43int32_t VideoDecoder::Initialize(const Graphics3D& context,
44                                 PP_VideoProfile profile,
45                                 PP_HardwareAcceleration acceleration,
46                                 const CompletionCallback& cc) {
47  if (has_interface<PPB_VideoDecoder_0_2>()) {
48    return get_interface<PPB_VideoDecoder_0_2>()->Initialize(
49        pp_resource(),
50        context.pp_resource(),
51        profile,
52        acceleration,
53        cc.pp_completion_callback());
54  }
55  if (has_interface<PPB_VideoDecoder_0_1>()) {
56    if (acceleration == PP_HARDWAREACCELERATION_NONE)
57      return cc.MayForce(PP_ERROR_NOTSUPPORTED);
58    return get_interface<PPB_VideoDecoder_0_1>()->Initialize(
59        pp_resource(),
60        context.pp_resource(),
61        profile,
62        acceleration == PP_HARDWAREACCELERATION_WITHFALLBACK
63            ? PP_TRUE
64            : PP_FALSE,
65        cc.pp_completion_callback());
66  }
67  return cc.MayForce(PP_ERROR_NOINTERFACE);
68}
69
70int32_t VideoDecoder::Decode(uint32_t decode_id,
71                             uint32_t size,
72                             const void* buffer,
73                             const CompletionCallback& cc) {
74  if (has_interface<PPB_VideoDecoder_0_2>()) {
75    return get_interface<PPB_VideoDecoder_0_2>()->Decode(
76        pp_resource(), decode_id, size, buffer, cc.pp_completion_callback());
77  }
78  if (has_interface<PPB_VideoDecoder_0_1>()) {
79    return get_interface<PPB_VideoDecoder_0_1>()->Decode(
80        pp_resource(), decode_id, size, buffer, cc.pp_completion_callback());
81  }
82  return cc.MayForce(PP_ERROR_NOINTERFACE);
83}
84
85int32_t VideoDecoder::GetPicture(
86    const CompletionCallbackWithOutput<PP_VideoPicture>& cc) {
87  if (has_interface<PPB_VideoDecoder_0_2>()) {
88    return get_interface<PPB_VideoDecoder_0_2>()->GetPicture(
89        pp_resource(), cc.output(), cc.pp_completion_callback());
90  }
91  if (has_interface<PPB_VideoDecoder_0_1>()) {
92    return get_interface<PPB_VideoDecoder_0_1>()->GetPicture(
93        pp_resource(), cc.output(), cc.pp_completion_callback());
94  }
95  return cc.MayForce(PP_ERROR_NOINTERFACE);
96}
97
98void VideoDecoder::RecyclePicture(const PP_VideoPicture& picture) {
99  if (has_interface<PPB_VideoDecoder_0_2>()) {
100    get_interface<PPB_VideoDecoder_0_2>()->RecyclePicture(pp_resource(),
101                                                          &picture);
102  } else if (has_interface<PPB_VideoDecoder_0_1>()) {
103    get_interface<PPB_VideoDecoder_0_1>()->RecyclePicture(pp_resource(),
104                                                          &picture);
105  }
106}
107
108int32_t VideoDecoder::Flush(const CompletionCallback& cc) {
109  if (has_interface<PPB_VideoDecoder_0_2>()) {
110    return get_interface<PPB_VideoDecoder_0_2>()->Flush(
111        pp_resource(), cc.pp_completion_callback());
112  }
113  if (has_interface<PPB_VideoDecoder_0_1>()) {
114    return get_interface<PPB_VideoDecoder_0_1>()->Flush(
115        pp_resource(), cc.pp_completion_callback());
116  }
117  return cc.MayForce(PP_ERROR_NOINTERFACE);
118}
119
120int32_t VideoDecoder::Reset(const CompletionCallback& cc) {
121  if (has_interface<PPB_VideoDecoder_0_2>()) {
122    return get_interface<PPB_VideoDecoder_0_2>()->Reset(
123        pp_resource(), cc.pp_completion_callback());
124  }
125  if (has_interface<PPB_VideoDecoder_0_1>()) {
126    return get_interface<PPB_VideoDecoder_0_1>()->Reset(
127        pp_resource(), cc.pp_completion_callback());
128  }
129  return cc.MayForce(PP_ERROR_NOINTERFACE);
130}
131
132}  // namespace pp
133