Line data Source code
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 :
21 0 : static aom_codec_alg_priv_t *get_alg_priv(aom_codec_ctx_t *ctx) {
22 0 : return (aom_codec_alg_priv_t *)ctx->priv;
23 : }
24 :
25 0 : 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 0 : if (ver != AOM_DECODER_ABI_VERSION)
32 0 : res = AOM_CODEC_ABI_MISMATCH;
33 0 : else if (!ctx || !iface)
34 0 : res = AOM_CODEC_INVALID_PARAM;
35 0 : else if (iface->abi_version != AOM_CODEC_INTERNAL_ABI_VERSION)
36 0 : res = AOM_CODEC_ABI_MISMATCH;
37 0 : else if ((flags & AOM_CODEC_USE_POSTPROC) &&
38 0 : !(iface->caps & AOM_CODEC_CAP_POSTPROC))
39 0 : res = AOM_CODEC_INCAPABLE;
40 0 : else if ((flags & AOM_CODEC_USE_ERROR_CONCEALMENT) &&
41 0 : !(iface->caps & AOM_CODEC_CAP_ERROR_CONCEALMENT))
42 0 : res = AOM_CODEC_INCAPABLE;
43 0 : else if ((flags & AOM_CODEC_USE_INPUT_FRAGMENTS) &&
44 0 : !(iface->caps & AOM_CODEC_CAP_INPUT_FRAGMENTS))
45 0 : res = AOM_CODEC_INCAPABLE;
46 0 : else if (!(iface->caps & AOM_CODEC_CAP_DECODER))
47 0 : res = AOM_CODEC_INCAPABLE;
48 : else {
49 0 : memset(ctx, 0, sizeof(*ctx));
50 0 : ctx->iface = iface;
51 0 : ctx->name = iface->name;
52 0 : ctx->priv = NULL;
53 0 : ctx->init_flags = flags;
54 0 : ctx->config.dec = cfg;
55 :
56 0 : res = ctx->iface->init(ctx, NULL);
57 0 : if (res) {
58 0 : ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
59 0 : aom_codec_destroy(ctx);
60 : }
61 : }
62 :
63 0 : return SAVE_STATUS(ctx, res);
64 : }
65 :
66 0 : aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface,
67 : const uint8_t *data,
68 : unsigned int data_sz,
69 : aom_codec_stream_info_t *si) {
70 : aom_codec_err_t res;
71 :
72 0 : if (!iface || !data || !data_sz || !si) {
73 0 : res = AOM_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 : aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx,
86 : aom_codec_stream_info_t *si) {
87 : aom_codec_err_t res;
88 :
89 0 : if (!ctx || !si) {
90 0 : res = AOM_CODEC_INVALID_PARAM;
91 0 : } else if (!ctx->iface || !ctx->priv) {
92 0 : res = AOM_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 : aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data,
105 : unsigned int data_sz, void *user_priv,
106 : long deadline) {
107 : aom_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 = AOM_CODEC_INVALID_PARAM;
113 0 : else if (!ctx->iface || !ctx->priv)
114 0 : res = AOM_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 : aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter) {
124 : aom_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 : aom_codec_err_t aom_codec_register_put_frame_cb(aom_codec_ctx_t *ctx,
135 : aom_codec_put_frame_cb_fn_t cb,
136 : void *user_priv) {
137 : aom_codec_err_t res;
138 :
139 0 : if (!ctx || !cb)
140 0 : res = AOM_CODEC_INVALID_PARAM;
141 0 : else if (!ctx->iface || !ctx->priv ||
142 0 : !(ctx->iface->caps & AOM_CODEC_CAP_PUT_FRAME))
143 0 : res = AOM_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 = AOM_CODEC_OK;
148 : }
149 :
150 0 : return SAVE_STATUS(ctx, res);
151 : }
152 :
153 0 : aom_codec_err_t aom_codec_register_put_slice_cb(aom_codec_ctx_t *ctx,
154 : aom_codec_put_slice_cb_fn_t cb,
155 : void *user_priv) {
156 : aom_codec_err_t res;
157 :
158 0 : if (!ctx || !cb)
159 0 : res = AOM_CODEC_INVALID_PARAM;
160 0 : else if (!ctx->iface || !ctx->priv ||
161 0 : !(ctx->iface->caps & AOM_CODEC_CAP_PUT_SLICE))
162 0 : res = AOM_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 = AOM_CODEC_OK;
167 : }
168 :
169 0 : return SAVE_STATUS(ctx, res);
170 : }
171 :
172 0 : aom_codec_err_t aom_codec_set_frame_buffer_functions(
173 : aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get,
174 : aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
175 : aom_codec_err_t res;
176 :
177 0 : if (!ctx || !cb_get || !cb_release) {
178 0 : res = AOM_CODEC_INVALID_PARAM;
179 0 : } else if (!ctx->iface || !ctx->priv ||
180 0 : !(ctx->iface->caps & AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
181 0 : res = AOM_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 : }
|