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
12 /*!\file
13 * \brief Provides the high level interface to wrap decoder algorithms.
14 *
15 */
16 #include <string.h>
17 #include "vpx/internal/vpx_codec_internal.h"
18 #include "trace_conf.h"
19
20 #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
21
vpx_codec_dec_init_ver(vpx_codec_ctx_t * ctx,vpx_codec_iface_t * iface,vpx_codec_dec_cfg_t * cfg,vpx_codec_flags_t flags,int ver)22 vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
23 vpx_codec_iface_t *iface,
24 vpx_codec_dec_cfg_t *cfg,
25 vpx_codec_flags_t flags,
26 int ver) {
27 vpx_codec_err_t res;
28 (void)ver;
29
30 if (0) {//(ver != VPX_DECODER_ABI_VERSION) {
31 res = VPX_CODEC_ABI_MISMATCH;
32 }
33 else if (!ctx || !iface)
34 res = VPX_CODEC_INVALID_PARAM;
35 else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) {
36 res = VPX_CODEC_ABI_MISMATCH;
37 }
38 else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
39 res = VPX_CODEC_INCAPABLE;
40 else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
41 res = VPX_CODEC_INCAPABLE;
42 else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
43 !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
44 res = VPX_CODEC_INCAPABLE;
45 else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
46 !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
47 res = VPX_CODEC_INCAPABLE;
48 else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
49 res = VPX_CODEC_INCAPABLE;
50 else {
51 memset(ctx, 0, sizeof(*ctx));
52 ctx->iface = iface;
53 ctx->name = iface->name;
54 ctx->priv = NULL;
55 ctx->init_flags = flags;
56 ctx->config.dec = cfg;
57 res = VPX_CODEC_OK;
58
59 if (!(flags & VPX_CODEC_USE_XMA)) {
60 res = ctx->iface->init(ctx, NULL);
61
62 if (res) {
63 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
64 vpx_codec_destroy(ctx);
65 }
66
67 if (ctx->priv)
68 ctx->priv->iface = ctx->iface;
69 }
70 }
71
72 return SAVE_STATUS(ctx, res);
73 }
74
75
vpx_codec_peek_stream_info(vpx_codec_iface_t * iface,const uint8_t * data,unsigned int data_sz,vpx_codec_stream_info_t * si)76 vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
77 const uint8_t *data,
78 unsigned int data_sz,
79 vpx_codec_stream_info_t *si) {
80 vpx_codec_err_t res;
81
82 if (!iface || !data || !data_sz || !si
83 || si->sz < sizeof(vpx_codec_stream_info_t))
84 res = VPX_CODEC_INVALID_PARAM;
85 else {
86 /* Set default/unknown values */
87 si->w = 0;
88 si->h = 0;
89
90 res = iface->dec.peek_si(data, data_sz, si);
91 }
92
93 return res;
94 }
95
96
vpx_codec_get_stream_info(vpx_codec_ctx_t * ctx,vpx_codec_stream_info_t * si)97 vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
98 vpx_codec_stream_info_t *si) {
99 vpx_codec_err_t res;
100
101 if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
102 res = VPX_CODEC_INVALID_PARAM;
103 else if (!ctx->iface || !ctx->priv)
104 res = VPX_CODEC_ERROR;
105 else {
106 /* Set default/unknown values */
107 si->w = 0;
108 si->h = 0;
109
110 res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si);
111 }
112
113 return SAVE_STATUS(ctx, res);
114 }
115
116
vpx_codec_decode(vpx_codec_ctx_t * ctx,const uint8_t * data,unsigned int data_sz,void * user_priv,long deadline)117 vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx,
118 const uint8_t *data,
119 unsigned int data_sz,
120 void *user_priv,
121 long deadline) {
122 vpx_codec_err_t res;
123
124 /* Sanity checks */
125 /* NULL data ptr allowed if data_sz is 0 too */
126 if (!ctx || (!data && data_sz))
127 res = VPX_CODEC_INVALID_PARAM;
128 else if (!ctx->iface || !ctx->priv)
129 res = VPX_CODEC_ERROR;
130 else {
131 res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
132 user_priv, deadline);
133 }
134
135 return SAVE_STATUS(ctx, res);
136 }
137
vpx_codec_get_frame(vpx_codec_ctx_t * ctx,vpx_codec_iter_t * iter)138 vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx,
139 vpx_codec_iter_t *iter) {
140 vpx_image_t *img;
141
142 if (!ctx || !iter || !ctx->iface || !ctx->priv)
143 img = NULL;
144 else
145 img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
146
147 return img;
148 }
149
150
vpx_codec_register_put_frame_cb(vpx_codec_ctx_t * ctx,vpx_codec_put_frame_cb_fn_t cb,void * user_priv)151 vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
152 vpx_codec_put_frame_cb_fn_t cb,
153 void *user_priv) {
154 vpx_codec_err_t res;
155
156 if (!ctx || !cb)
157 res = VPX_CODEC_INVALID_PARAM;
158 else if (!ctx->iface || !ctx->priv
159 || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
160 res = VPX_CODEC_ERROR;
161 else {
162 ctx->priv->dec.put_frame_cb.u.put_frame = cb;
163 ctx->priv->dec.put_frame_cb.user_priv = user_priv;
164 res = VPX_CODEC_OK;
165 }
166
167 return SAVE_STATUS(ctx, res);
168 }
169
170
vpx_codec_register_put_slice_cb(vpx_codec_ctx_t * ctx,vpx_codec_put_slice_cb_fn_t cb,void * user_priv)171 vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
172 vpx_codec_put_slice_cb_fn_t cb,
173 void *user_priv) {
174 vpx_codec_err_t res;
175
176 if (!ctx || !cb)
177 res = VPX_CODEC_INVALID_PARAM;
178 else if (!ctx->iface || !ctx->priv
179 || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE))
180 res = VPX_CODEC_ERROR;
181 else {
182 ctx->priv->dec.put_slice_cb.u.put_slice = cb;
183 ctx->priv->dec.put_slice_cb.user_priv = user_priv;
184 res = VPX_CODEC_OK;
185 }
186
187 return SAVE_STATUS(ctx, res);
188 }
189
190
vpx_codec_get_mem_map(vpx_codec_ctx_t * ctx,vpx_codec_mmap_t * mmap,vpx_codec_iter_t * iter)191 vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t *ctx,
192 vpx_codec_mmap_t *mmap,
193 vpx_codec_iter_t *iter) {
194 vpx_codec_err_t res = VPX_CODEC_OK;
195
196 if (!ctx || !mmap || !iter || !ctx->iface)
197 res = VPX_CODEC_INVALID_PARAM;
198 else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
199 res = VPX_CODEC_ERROR;
200 else
201 res = ctx->iface->get_mmap(ctx, mmap, iter);
202
203 return SAVE_STATUS(ctx, res);
204 }
205
206
vpx_codec_set_mem_map(vpx_codec_ctx_t * ctx,vpx_codec_mmap_t * mmap,unsigned int num_maps)207 vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t *ctx,
208 vpx_codec_mmap_t *mmap,
209 unsigned int num_maps) {
210 vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
211
212 if (!ctx || !mmap || !ctx->iface)
213 res = VPX_CODEC_INVALID_PARAM;
214 else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
215 res = VPX_CODEC_ERROR;
216 else {
217 unsigned int i;
218
219 for (i = 0; i < num_maps; i++, mmap++) {
220 if (!mmap->base)
221 break;
222
223 /* Everything look ok, set the mmap in the decoder */
224 res = ctx->iface->set_mmap(ctx, mmap);
225
226 if (res)
227 break;
228 }
229 }
230
231 return SAVE_STATUS(ctx, res);
232 }
233
vpx_codec_set_frame_buffer_functions(vpx_codec_ctx_t * ctx,vpx_get_frame_buffer_cb_fn_t cb_get,vpx_release_frame_buffer_cb_fn_t cb_release,void * cb_priv)234 vpx_codec_err_t vpx_codec_set_frame_buffer_functions(
235 vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get,
236 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
237 vpx_codec_err_t res;
238
239 if (!ctx || !cb_get || !cb_release) {
240 res = VPX_CODEC_INVALID_PARAM;
241 } else if (!ctx->iface || !ctx->priv ||
242 !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
243 res = VPX_CODEC_ERROR;
244 } else {
245 res = ctx->iface->dec.set_fb_fn(ctx->priv->alg_priv, cb_get, cb_release,
246 cb_priv);
247 }
248
249 return SAVE_STATUS(ctx, res);
250 }
251