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 (!(iface->caps & AOM_CODEC_CAP_DECODER))
38 res = AOM_CODEC_INCAPABLE;
39 else {
40 memset(ctx, 0, sizeof(*ctx));
41 ctx->iface = iface;
42 ctx->name = iface->name;
43 ctx->priv = NULL;
44 ctx->init_flags = flags;
45 ctx->config.dec = cfg;
46
47 res = ctx->iface->init(ctx);
48 if (res) {
49 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
50 aom_codec_destroy(ctx);
51 }
52 }
53
54 return SAVE_STATUS(ctx, res);
55 }
56
aom_codec_peek_stream_info(aom_codec_iface_t * iface,const uint8_t * data,size_t data_sz,aom_codec_stream_info_t * si)57 aom_codec_err_t aom_codec_peek_stream_info(aom_codec_iface_t *iface,
58 const uint8_t *data, size_t data_sz,
59 aom_codec_stream_info_t *si) {
60 aom_codec_err_t res;
61
62 if (!iface || !data || !data_sz || !si) {
63 res = AOM_CODEC_INVALID_PARAM;
64 } else {
65 /* Set default/unknown values */
66 si->w = 0;
67 si->h = 0;
68
69 res = iface->dec.peek_si(data, data_sz, si);
70 }
71
72 return res;
73 }
74
aom_codec_get_stream_info(aom_codec_ctx_t * ctx,aom_codec_stream_info_t * si)75 aom_codec_err_t aom_codec_get_stream_info(aom_codec_ctx_t *ctx,
76 aom_codec_stream_info_t *si) {
77 aom_codec_err_t res;
78
79 if (!ctx || !si) {
80 res = AOM_CODEC_INVALID_PARAM;
81 } else if (!ctx->iface || !ctx->priv) {
82 res = AOM_CODEC_ERROR;
83 } else {
84 /* Set default/unknown values */
85 si->w = 0;
86 si->h = 0;
87
88 res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
89 }
90
91 return SAVE_STATUS(ctx, res);
92 }
93
aom_codec_decode(aom_codec_ctx_t * ctx,const uint8_t * data,size_t data_sz,void * user_priv)94 aom_codec_err_t aom_codec_decode(aom_codec_ctx_t *ctx, const uint8_t *data,
95 size_t data_sz, void *user_priv) {
96 aom_codec_err_t res;
97
98 if (!ctx)
99 res = AOM_CODEC_INVALID_PARAM;
100 else if (!ctx->iface || !ctx->priv)
101 res = AOM_CODEC_ERROR;
102 else {
103 res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv);
104 }
105
106 return SAVE_STATUS(ctx, res);
107 }
108
aom_codec_get_frame(aom_codec_ctx_t * ctx,aom_codec_iter_t * iter)109 aom_image_t *aom_codec_get_frame(aom_codec_ctx_t *ctx, aom_codec_iter_t *iter) {
110 aom_image_t *img;
111
112 if (!ctx || !iter || !ctx->iface || !ctx->priv)
113 img = NULL;
114 else
115 img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
116
117 return img;
118 }
119
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)120 aom_codec_err_t aom_codec_set_frame_buffer_functions(
121 aom_codec_ctx_t *ctx, aom_get_frame_buffer_cb_fn_t cb_get,
122 aom_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
123 aom_codec_err_t res;
124
125 if (!ctx || !cb_get || !cb_release) {
126 res = AOM_CODEC_INVALID_PARAM;
127 } else if (!ctx->iface || !ctx->priv) {
128 res = AOM_CODEC_ERROR;
129 } else if (!(ctx->iface->caps & AOM_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
130 res = AOM_CODEC_INCAPABLE;
131 } else {
132 res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
133 cb_priv);
134 }
135
136 return SAVE_STATUS(ctx, res);
137 }
138