1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 /*!\file
13 * \brief Provides the high level interface to wrap decoder algorithms.
14 *
15 */
16 #include <string.h>
17 #include "aom/internal/aom_codec_internal.h"
18
19 #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
20
get_alg_priv(aom_codec_ctx_t * ctx)21 static aom_codec_alg_priv_t *get_alg_priv(aom_codec_ctx_t *ctx) {
22 return (aom_codec_alg_priv_t *)ctx->priv;
23 }
24
aom_codec_dec_init_ver(aom_codec_ctx_t * ctx,aom_codec_iface_t * iface,const aom_codec_dec_cfg_t * cfg,aom_codec_flags_t flags,int ver)25 aom_codec_err_t aom_codec_dec_init_ver(aom_codec_ctx_t *ctx,
26 aom_codec_iface_t *iface,
27 const aom_codec_dec_cfg_t *cfg,
28 aom_codec_flags_t flags, int ver) {
29 aom_codec_err_t res;
30
31 if (ver != AOM_DECODER_ABI_VERSION)
32 res = AOM_CODEC_ABI_MISMATCH;
33 else if (!ctx || !iface)
34 res = AOM_CODEC_INVALID_PARAM;
35 else if (iface->abi_version != AOM_CODEC_INTERNAL_ABI_VERSION)
36 res = AOM_CODEC_ABI_MISMATCH;
37 else if ((flags & AOM_CODEC_USE_POSTPROC) &&
38 !(iface->caps & AOM_CODEC_CAP_POSTPROC))
39 res = AOM_CODEC_INCAPABLE;
40 else if (!(iface->caps & AOM_CODEC_CAP_DECODER))
41 res = AOM_CODEC_INCAPABLE;
42 else {
43 memset(ctx, 0, sizeof(*ctx));
44 ctx->iface = iface;
45 ctx->name = iface->name;
46 ctx->priv = NULL;
47 ctx->init_flags = flags;
48 ctx->config.dec = cfg;
49
50 res = ctx->iface->init(ctx, NULL);
51 if (res) {
52 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
53 aom_codec_destroy(ctx);
54 }
55 }
56
57 return SAVE_STATUS(ctx, res);
58 }
59
aom_codec_peek_stream_info(aom_codec_iface_t * iface,const uint8_t * data,size_t data_sz,aom_codec_stream_info_t * si)60 aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface,
61 const uint8_t *data, size_t data_sz,
62 aom_codec_stream_info_t *si) {
63 aom_codec_err_t res;
64
65 if (!iface || !data || !data_sz || !si) {
66 res = AOM_CODEC_INVALID_PARAM;
67 } else {
68 /* Set default/unknown values */
69 si->w = 0;
70 si->h = 0;
71
72 res = iface->dec.peek_si(data, data_sz, si);
73 }
74
75 return res;
76 }
77
aom_codec_get_stream_info(aom_codec_ctx_t * ctx,aom_codec_stream_info_t * si)78 aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx,
79 aom_codec_stream_info_t *si) {
80 aom_codec_err_t res;
81
82 if (!ctx || !si) {
83 res = AOM_CODEC_INVALID_PARAM;
84 } else if (!ctx->iface || !ctx->priv) {
85 res = AOM_CODEC_ERROR;
86 } else {
87 /* Set default/unknown values */
88 si->w = 0;
89 si->h = 0;
90
91 res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
92 }
93
94 return SAVE_STATUS(ctx, res);
95 }
96
aom_codec_decode(aom_codec_ctx_t * ctx,const uint8_t * data,size_t data_sz,void * user_priv)97 aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data,
98 size_t data_sz, void *user_priv) {
99 aom_codec_err_t res;
100
101 if (!ctx)
102 res = AOM_CODEC_INVALID_PARAM;
103 else if (!ctx->iface || !ctx->priv)
104 res = AOM_CODEC_ERROR;
105 else {
106 res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv);
107 }
108
109 return SAVE_STATUS(ctx, res);
110 }
111
aom_codec_get_frame(aom_codec_ctx_t * ctx,aom_codec_iter_t * iter)112 aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter) {
113 aom_image_t *img;
114
115 if (!ctx || !iter || !ctx->iface || !ctx->priv)
116 img = NULL;
117 else
118 img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
119
120 return img;
121 }
122
aom_codec_register_put_frame_cb(aom_codec_ctx_t * ctx,aom_codec_put_frame_cb_fn_t cb,void * user_priv)123 aom_codec_err_t aom_codec_register_put_frame_cb(aom_codec_ctx_t *ctx,
124 aom_codec_put_frame_cb_fn_t cb,
125 void *user_priv) {
126 aom_codec_err_t res;
127
128 if (!ctx || !cb)
129 res = AOM_CODEC_INVALID_PARAM;
130 else if (!ctx->iface || !ctx->priv ||
131 !(ctx->iface->caps & AOM_CODEC_CAP_PUT_FRAME))
132 res = AOM_CODEC_ERROR;
133 else {
134 ctx->priv->dec.put_frame_cb.u.put_frame = cb;
135 ctx->priv->dec.put_frame_cb.user_priv = user_priv;
136 res = AOM_CODEC_OK;
137 }
138
139 return SAVE_STATUS(ctx, res);
140 }
141
aom_codec_register_put_slice_cb(aom_codec_ctx_t * ctx,aom_codec_put_slice_cb_fn_t cb,void * user_priv)142 aom_codec_err_t aom_codec_register_put_slice_cb(aom_codec_ctx_t *ctx,
143 aom_codec_put_slice_cb_fn_t cb,
144 void *user_priv) {
145 aom_codec_err_t res;
146
147 if (!ctx || !cb)
148 res = AOM_CODEC_INVALID_PARAM;
149 else if (!ctx->iface || !ctx->priv ||
150 !(ctx->iface->caps & AOM_CODEC_CAP_PUT_SLICE))
151 res = AOM_CODEC_ERROR;
152 else {
153 ctx->priv->dec.put_slice_cb.u.put_slice = cb;
154 ctx->priv->dec.put_slice_cb.user_priv = user_priv;
155 res = AOM_CODEC_OK;
156 }
157
158 return SAVE_STATUS(ctx, res);
159 }
160
aom_codec_set_frame_buffer_functions(aom_codec_ctx_t * ctx,aom_get_frame_buffer_cb_fn_t cb_get,aom_release_frame_buffer_cb_fn_t cb_release,void * cb_priv)161 aom_codec_err_t aom_codec_set_frame_buffer_functions(
162 aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get,
163 aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
164 aom_codec_err_t res;
165
166 if (!ctx || !cb_get || !cb_release) {
167 res = AOM_CODEC_INVALID_PARAM;
168 } else if (!ctx->iface || !ctx->priv ||
169 !(ctx->iface->caps & AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
170 res = AOM_CODEC_ERROR;
171 } else {
172 res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
173 cb_priv);
174 }
175
176 return SAVE_STATUS(ctx, res);
177 }
178