2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
13 * \brief Provides the high level interface to wrap decoder algorithms.
17 #include "vpx/internal/vpx_codec_internal.h"
19 #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
21 vpx_codec_err_t
vpx_codec_dec_init_ver(vpx_codec_ctx_t
*ctx
,
22 vpx_codec_iface_t
*iface
,
23 vpx_codec_dec_cfg_t
*cfg
,
24 vpx_codec_flags_t flags
,
29 if (ver
!= VPX_DECODER_ABI_VERSION
)
30 res
= VPX_CODEC_ABI_MISMATCH
;
31 else if (!ctx
|| !iface
)
32 res
= VPX_CODEC_INVALID_PARAM
;
33 else if (iface
->abi_version
!= VPX_CODEC_INTERNAL_ABI_VERSION
)
34 res
= VPX_CODEC_ABI_MISMATCH
;
35 else if ((flags
& VPX_CODEC_USE_XMA
) && !(iface
->caps
& VPX_CODEC_CAP_XMA
))
36 res
= VPX_CODEC_INCAPABLE
;
37 else if ((flags
& VPX_CODEC_USE_POSTPROC
) && !(iface
->caps
& VPX_CODEC_CAP_POSTPROC
))
38 res
= VPX_CODEC_INCAPABLE
;
39 else if ((flags
& VPX_CODEC_USE_ERROR_CONCEALMENT
) &&
40 !(iface
->caps
& VPX_CODEC_CAP_ERROR_CONCEALMENT
))
41 res
= VPX_CODEC_INCAPABLE
;
42 else if ((flags
& VPX_CODEC_USE_INPUT_PARTITION
) &&
43 !(iface
->caps
& VPX_CODEC_CAP_INPUT_PARTITION
))
44 res
= VPX_CODEC_INCAPABLE
;
45 else if (!(iface
->caps
& VPX_CODEC_CAP_DECODER
))
46 res
= VPX_CODEC_INCAPABLE
;
49 memset(ctx
, 0, sizeof(*ctx
));
51 ctx
->name
= iface
->name
;
53 ctx
->init_flags
= flags
;
54 ctx
->config
.dec
= cfg
;
57 if (!(flags
& VPX_CODEC_USE_XMA
))
59 res
= ctx
->iface
->init(ctx
);
63 ctx
->err_detail
= ctx
->priv
? ctx
->priv
->err_detail
: NULL
;
64 vpx_codec_destroy(ctx
);
68 ctx
->priv
->iface
= ctx
->iface
;
72 return SAVE_STATUS(ctx
, res
);
76 vpx_codec_err_t
vpx_codec_peek_stream_info(vpx_codec_iface_t
*iface
,
79 vpx_codec_stream_info_t
*si
)
83 if (!iface
|| !data
|| !data_sz
|| !si
84 || si
->sz
< sizeof(vpx_codec_stream_info_t
))
85 res
= VPX_CODEC_INVALID_PARAM
;
88 /* Set default/unknown values */
92 res
= iface
->dec
.peek_si(data
, data_sz
, si
);
99 vpx_codec_err_t
vpx_codec_get_stream_info(vpx_codec_ctx_t
*ctx
,
100 vpx_codec_stream_info_t
*si
)
104 if (!ctx
|| !si
|| si
->sz
< sizeof(vpx_codec_stream_info_t
))
105 res
= VPX_CODEC_INVALID_PARAM
;
106 else if (!ctx
->iface
|| !ctx
->priv
)
107 res
= VPX_CODEC_ERROR
;
110 /* Set default/unknown values */
114 res
= ctx
->iface
->dec
.get_si(ctx
->priv
->alg_priv
, si
);
117 return SAVE_STATUS(ctx
, res
);
121 vpx_codec_err_t
vpx_codec_decode(vpx_codec_ctx_t
*ctx
,
123 unsigned int data_sz
,
130 /* NULL data ptr allowed if data_sz is 0 too */
131 if (!ctx
|| (!data
&& data_sz
))
132 res
= VPX_CODEC_INVALID_PARAM
;
133 else if (!ctx
->iface
|| !ctx
->priv
)
134 res
= VPX_CODEC_ERROR
;
137 res
= ctx
->iface
->dec
.decode(ctx
->priv
->alg_priv
, data
, data_sz
,
138 user_priv
, deadline
);
141 return SAVE_STATUS(ctx
, res
);
144 vpx_image_t
*vpx_codec_get_frame(vpx_codec_ctx_t
*ctx
,
145 vpx_codec_iter_t
*iter
)
149 if (!ctx
|| !iter
|| !ctx
->iface
|| !ctx
->priv
)
152 img
= ctx
->iface
->dec
.get_frame(ctx
->priv
->alg_priv
, iter
);
158 vpx_codec_err_t
vpx_codec_register_put_frame_cb(vpx_codec_ctx_t
*ctx
,
159 vpx_codec_put_frame_cb_fn_t cb
,
165 res
= VPX_CODEC_INVALID_PARAM
;
166 else if (!ctx
->iface
|| !ctx
->priv
167 || !(ctx
->iface
->caps
& VPX_CODEC_CAP_PUT_FRAME
))
168 res
= VPX_CODEC_ERROR
;
171 ctx
->priv
->dec
.put_frame_cb
.u
.put_frame
= cb
;
172 ctx
->priv
->dec
.put_frame_cb
.user_priv
= user_priv
;
176 return SAVE_STATUS(ctx
, res
);
180 vpx_codec_err_t
vpx_codec_register_put_slice_cb(vpx_codec_ctx_t
*ctx
,
181 vpx_codec_put_slice_cb_fn_t cb
,
187 res
= VPX_CODEC_INVALID_PARAM
;
188 else if (!ctx
->iface
|| !ctx
->priv
189 || !(ctx
->iface
->caps
& VPX_CODEC_CAP_PUT_FRAME
))
190 res
= VPX_CODEC_ERROR
;
193 ctx
->priv
->dec
.put_slice_cb
.u
.put_slice
= cb
;
194 ctx
->priv
->dec
.put_slice_cb
.user_priv
= user_priv
;
198 return SAVE_STATUS(ctx
, res
);
202 vpx_codec_err_t
vpx_codec_get_mem_map(vpx_codec_ctx_t
*ctx
,
203 vpx_codec_mmap_t
*mmap
,
204 vpx_codec_iter_t
*iter
)
206 vpx_codec_err_t res
= VPX_CODEC_OK
;
208 if (!ctx
|| !mmap
|| !iter
|| !ctx
->iface
)
209 res
= VPX_CODEC_INVALID_PARAM
;
210 else if (!(ctx
->iface
->caps
& VPX_CODEC_CAP_XMA
))
211 res
= VPX_CODEC_ERROR
;
213 res
= ctx
->iface
->get_mmap(ctx
, mmap
, iter
);
215 return SAVE_STATUS(ctx
, res
);
219 vpx_codec_err_t
vpx_codec_set_mem_map(vpx_codec_ctx_t
*ctx
,
220 vpx_codec_mmap_t
*mmap
,
221 unsigned int num_maps
)
223 vpx_codec_err_t res
= VPX_CODEC_MEM_ERROR
;
225 if (!ctx
|| !mmap
|| !ctx
->iface
)
226 res
= VPX_CODEC_INVALID_PARAM
;
227 else if (!(ctx
->iface
->caps
& VPX_CODEC_CAP_XMA
))
228 res
= VPX_CODEC_ERROR
;
233 for (i
= 0; i
< num_maps
; i
++, mmap
++)
238 /* Everything look ok, set the mmap in the decoder */
239 res
= ctx
->iface
->set_mmap(ctx
, mmap
);
246 return SAVE_STATUS(ctx
, res
);