Line data Source code
1 : /*
2 : * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 : *
4 : * Use of this source code is governed by a BSD-style license
5 : * that can be found in the LICENSE file in the root of the source
6 : * tree. An additional intellectual property rights grant can be found
7 : * in the file PATENTS. All contributing project authors may
8 : * be found in the AUTHORS file in the root of the source tree.
9 : */
10 :
11 : /*!\file
12 : * \brief Provides the high level interface to wrap decoder algorithms.
13 : *
14 : */
15 : #include <string.h>
16 : #include "vpx/internal/vpx_codec_internal.h"
17 :
18 : #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
19 :
20 0 : static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) {
21 0 : return (vpx_codec_alg_priv_t *)ctx->priv;
22 : }
23 :
24 0 : vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
25 : vpx_codec_iface_t *iface,
26 : const vpx_codec_dec_cfg_t *cfg,
27 : vpx_codec_flags_t flags, int ver) {
28 : vpx_codec_err_t res;
29 :
30 0 : if (ver != VPX_DECODER_ABI_VERSION)
31 0 : res = VPX_CODEC_ABI_MISMATCH;
32 0 : else if (!ctx || !iface)
33 0 : res = VPX_CODEC_INVALID_PARAM;
34 0 : else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
35 0 : res = VPX_CODEC_ABI_MISMATCH;
36 0 : else if ((flags & VPX_CODEC_USE_POSTPROC) &&
37 0 : !(iface->caps & VPX_CODEC_CAP_POSTPROC))
38 0 : res = VPX_CODEC_INCAPABLE;
39 0 : else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
40 0 : !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
41 0 : res = VPX_CODEC_INCAPABLE;
42 0 : else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
43 0 : !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
44 0 : res = VPX_CODEC_INCAPABLE;
45 0 : else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
46 0 : res = VPX_CODEC_INCAPABLE;
47 : else {
48 0 : memset(ctx, 0, sizeof(*ctx));
49 0 : ctx->iface = iface;
50 0 : ctx->name = iface->name;
51 0 : ctx->priv = NULL;
52 0 : ctx->init_flags = flags;
53 0 : ctx->config.dec = cfg;
54 :
55 0 : res = ctx->iface->init(ctx, NULL);
56 0 : if (res) {
57 0 : ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
58 0 : vpx_codec_destroy(ctx);
59 : }
60 : }
61 :
62 0 : return SAVE_STATUS(ctx, res);
63 : }
64 :
65 0 : vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
66 : const uint8_t *data,
67 : unsigned int data_sz,
68 : vpx_codec_stream_info_t *si) {
69 : vpx_codec_err_t res;
70 :
71 0 : if (!iface || !data || !data_sz || !si ||
72 0 : si->sz < sizeof(vpx_codec_stream_info_t))
73 0 : res = VPX_CODEC_INVALID_PARAM;
74 : else {
75 : /* Set default/unknown values */
76 0 : si->w = 0;
77 0 : si->h = 0;
78 :
79 0 : res = iface->dec.peek_si(data, data_sz, si);
80 : }
81 :
82 0 : return res;
83 : }
84 :
85 0 : vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
86 : vpx_codec_stream_info_t *si) {
87 : vpx_codec_err_t res;
88 :
89 0 : if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
90 0 : res = VPX_CODEC_INVALID_PARAM;
91 0 : else if (!ctx->iface || !ctx->priv)
92 0 : res = VPX_CODEC_ERROR;
93 : else {
94 : /* Set default/unknown values */
95 0 : si->w = 0;
96 0 : si->h = 0;
97 :
98 0 : res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
99 : }
100 :
101 0 : return SAVE_STATUS(ctx, res);
102 : }
103 :
104 0 : vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data,
105 : unsigned int data_sz, void *user_priv,
106 : long deadline) {
107 : vpx_codec_err_t res;
108 :
109 : /* Sanity checks */
110 : /* NULL data ptr allowed if data_sz is 0 too */
111 0 : if (!ctx || (!data && data_sz) || (data && !data_sz))
112 0 : res = VPX_CODEC_INVALID_PARAM;
113 0 : else if (!ctx->iface || !ctx->priv)
114 0 : res = VPX_CODEC_ERROR;
115 : else {
116 0 : res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv,
117 : deadline);
118 : }
119 :
120 0 : return SAVE_STATUS(ctx, res);
121 : }
122 :
123 0 : vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter) {
124 : vpx_image_t *img;
125 :
126 0 : if (!ctx || !iter || !ctx->iface || !ctx->priv)
127 0 : img = NULL;
128 : else
129 0 : img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
130 :
131 0 : return img;
132 : }
133 :
134 0 : vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
135 : vpx_codec_put_frame_cb_fn_t cb,
136 : void *user_priv) {
137 : vpx_codec_err_t res;
138 :
139 0 : if (!ctx || !cb)
140 0 : res = VPX_CODEC_INVALID_PARAM;
141 0 : else if (!ctx->iface || !ctx->priv ||
142 0 : !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
143 0 : res = VPX_CODEC_ERROR;
144 : else {
145 0 : ctx->priv->dec.put_frame_cb.u.put_frame = cb;
146 0 : ctx->priv->dec.put_frame_cb.user_priv = user_priv;
147 0 : res = VPX_CODEC_OK;
148 : }
149 :
150 0 : return SAVE_STATUS(ctx, res);
151 : }
152 :
153 0 : vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
154 : vpx_codec_put_slice_cb_fn_t cb,
155 : void *user_priv) {
156 : vpx_codec_err_t res;
157 :
158 0 : if (!ctx || !cb)
159 0 : res = VPX_CODEC_INVALID_PARAM;
160 0 : else if (!ctx->iface || !ctx->priv ||
161 0 : !(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE))
162 0 : res = VPX_CODEC_ERROR;
163 : else {
164 0 : ctx->priv->dec.put_slice_cb.u.put_slice = cb;
165 0 : ctx->priv->dec.put_slice_cb.user_priv = user_priv;
166 0 : res = VPX_CODEC_OK;
167 : }
168 :
169 0 : return SAVE_STATUS(ctx, res);
170 : }
171 :
172 0 : vpx_codec_err_t vpx_codec_set_frame_buffer_functions(
173 : vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get,
174 : vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
175 : vpx_codec_err_t res;
176 :
177 0 : if (!ctx || !cb_get || !cb_release) {
178 0 : res = VPX_CODEC_INVALID_PARAM;
179 0 : } else if (!ctx->iface || !ctx->priv ||
180 0 : !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
181 0 : res = VPX_CODEC_ERROR;
182 : } else {
183 0 : res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
184 : cb_priv);
185 : }
186 :
187 0 : return SAVE_STATUS(ctx, res);
188 : }
|