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 19#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var) 20 21vpx_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, 25 int ver) 26{ 27 vpx_codec_err_t res; 28 29#ifdef MIPS_DSP_REV 30#if (MIPS_DSP_REV>=2) 31 dsputil_static_init(); 32#endif 33#endif 34 35 if (ver != VPX_DECODER_ABI_VERSION) 36 res = VPX_CODEC_ABI_MISMATCH; 37 else if (!ctx || !iface) 38 res = VPX_CODEC_INVALID_PARAM; 39 else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION) 40 res = VPX_CODEC_ABI_MISMATCH; 41 else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA)) 42 res = VPX_CODEC_INCAPABLE; 43 else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC)) 44 res = VPX_CODEC_INCAPABLE; 45 else if (!(iface->caps & VPX_CODEC_CAP_DECODER)) 46 res = VPX_CODEC_INCAPABLE; 47 else 48 { 49 memset(ctx, 0, sizeof(*ctx)); 50 ctx->iface = iface; 51 ctx->name = iface->name; 52 ctx->priv = NULL; 53 ctx->init_flags = flags; 54 ctx->config.dec = cfg; 55 res = VPX_CODEC_OK; 56 57 if (!(flags & VPX_CODEC_USE_XMA)) 58 { 59 res = ctx->iface->init(ctx); 60 61 if (res) 62 { 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 76vpx_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{ 81 vpx_codec_err_t res; 82 83 if (!iface || !data || !data_sz || !si 84 || si->sz < sizeof(vpx_codec_stream_info_t)) 85 res = VPX_CODEC_INVALID_PARAM; 86 else 87 { 88 /* Set default/unknown values */ 89 si->w = 0; 90 si->h = 0; 91 92 res = iface->dec.peek_si(data, data_sz, si); 93 } 94 95 return res; 96} 97 98 99vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx, 100 vpx_codec_stream_info_t *si) 101{ 102 vpx_codec_err_t res; 103 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; 108 else 109 { 110 /* Set default/unknown values */ 111 si->w = 0; 112 si->h = 0; 113 114 res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si); 115 } 116 117 return SAVE_STATUS(ctx, res); 118} 119 120 121vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, 122 const uint8_t *data, 123 unsigned int data_sz, 124 void *user_priv, 125 long deadline) 126{ 127 vpx_codec_err_t res; 128 129 /* Sanity checks */ 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; 135 else 136 { 137 res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz, 138 user_priv, deadline); 139 } 140 141 return SAVE_STATUS(ctx, res); 142} 143 144vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, 145 vpx_codec_iter_t *iter) 146{ 147 vpx_image_t *img; 148 149 if (!ctx || !iter || !ctx->iface || !ctx->priv) 150 img = NULL; 151 else 152 img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter); 153 154 return img; 155} 156 157 158vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx, 159 vpx_codec_put_frame_cb_fn_t cb, 160 void *user_priv) 161{ 162 vpx_codec_err_t res; 163 164 if (!ctx || !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; 169 else 170 { 171 ctx->priv->dec.put_frame_cb.u.put_frame = cb; 172 ctx->priv->dec.put_frame_cb.user_priv = user_priv; 173 res = VPX_CODEC_OK; 174 } 175 176 return SAVE_STATUS(ctx, res); 177} 178 179 180vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx, 181 vpx_codec_put_slice_cb_fn_t cb, 182 void *user_priv) 183{ 184 vpx_codec_err_t res; 185 186 if (!ctx || !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; 191 else 192 { 193 ctx->priv->dec.put_slice_cb.u.put_slice = cb; 194 ctx->priv->dec.put_slice_cb.user_priv = user_priv; 195 res = VPX_CODEC_OK; 196 } 197 198 return SAVE_STATUS(ctx, res); 199} 200 201 202vpx_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) 205{ 206 vpx_codec_err_t res = VPX_CODEC_OK; 207 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; 212 else 213 res = ctx->iface->get_mmap(ctx, mmap, iter); 214 215 return SAVE_STATUS(ctx, res); 216} 217 218 219vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t *ctx, 220 vpx_codec_mmap_t *mmap, 221 unsigned int num_maps) 222{ 223 vpx_codec_err_t res = VPX_CODEC_MEM_ERROR; 224 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; 229 else 230 { 231 unsigned int i; 232 233 for (i = 0; i < num_maps; i++, mmap++) 234 { 235 if (!mmap->base) 236 break; 237 238 /* Everything look ok, set the mmap in the decoder */ 239 res = ctx->iface->set_mmap(ctx, mmap); 240 241 if (res) 242 break; 243 } 244 } 245 246 return SAVE_STATUS(ctx, res); 247} 248