Home | History | Annotate | Download | only in src
      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 vpx_decoder.c
     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 
     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,
     25                                        int                   ver)
     26 {
     27     vpx_codec_err_t res;
     28 
     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
     40     {
     41         memset(ctx, 0, sizeof(*ctx));
     42         ctx->iface = iface;
     43         ctx->name = iface->name;
     44         ctx->priv = NULL;
     45         ctx->init_flags = flags;
     46         ctx->config.dec = cfg;
     47         res = VPX_CODEC_OK;
     48 
     49         if (!(flags & VPX_CODEC_USE_XMA))
     50         {
     51             res = ctx->iface->init(ctx);
     52 
     53             if (res)
     54             {
     55                 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
     56                 vpx_codec_destroy(ctx);
     57             }
     58 
     59             if (ctx->priv)
     60                 ctx->priv->iface = ctx->iface;
     61         }
     62     }
     63 
     64     return SAVE_STATUS(ctx, res);
     65 }
     66 
     67 
     68 vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t       *iface,
     69         const uint8_t         *data,
     70         unsigned int           data_sz,
     71         vpx_codec_stream_info_t *si)
     72 {
     73     vpx_codec_err_t res;
     74 
     75     if (!iface || !data || !data_sz || !si
     76         || si->sz < sizeof(vpx_codec_stream_info_t))
     77         res = VPX_CODEC_INVALID_PARAM;
     78     else
     79     {
     80         /* Set default/unknown values */
     81         si->w = 0;
     82         si->h = 0;
     83 
     84         res = iface->dec.peek_si(data, data_sz, si);
     85     }
     86 
     87     return res;
     88 }
     89 
     90 
     91 vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t         *ctx,
     92         vpx_codec_stream_info_t *si)
     93 {
     94     vpx_codec_err_t res;
     95 
     96     if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
     97         res = VPX_CODEC_INVALID_PARAM;
     98     else if (!ctx->iface || !ctx->priv)
     99         res = VPX_CODEC_ERROR;
    100     else
    101     {
    102         /* Set default/unknown values */
    103         si->w = 0;
    104         si->h = 0;
    105 
    106         res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si);
    107     }
    108 
    109     return SAVE_STATUS(ctx, res);
    110 }
    111 
    112 
    113 vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t    *ctx,
    114                                  const uint8_t        *data,
    115                                  unsigned int    data_sz,
    116                                  void       *user_priv,
    117                                  long        deadline)
    118 {
    119     vpx_codec_err_t res;
    120 
    121     if (!ctx || !data || !data_sz)
    122         res = VPX_CODEC_INVALID_PARAM;
    123     else if (!ctx->iface || !ctx->priv)
    124         res = VPX_CODEC_ERROR;
    125     else
    126     {
    127         res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
    128                                      user_priv, deadline);
    129     }
    130 
    131     return SAVE_STATUS(ctx, res);
    132 }
    133 
    134 vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t  *ctx,
    135                                  vpx_codec_iter_t *iter)
    136 {
    137     vpx_image_t *img;
    138 
    139     if (!ctx || !iter || !ctx->iface || !ctx->priv)
    140         img = NULL;
    141     else
    142         img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
    143 
    144     return img;
    145 }
    146 
    147 
    148 vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t             *ctx,
    149         vpx_codec_put_frame_cb_fn_t  cb,
    150         void                      *user_priv)
    151 {
    152     vpx_codec_err_t res;
    153 
    154     if (!ctx || !cb)
    155         res = VPX_CODEC_INVALID_PARAM;
    156     else if (!ctx->iface || !ctx->priv
    157              || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
    158         res = VPX_CODEC_ERROR;
    159     else
    160     {
    161         ctx->priv->dec.put_frame_cb.put_frame = cb;
    162         ctx->priv->dec.put_frame_cb.user_priv = user_priv;
    163         res = VPX_CODEC_OK;
    164     }
    165 
    166     return SAVE_STATUS(ctx, res);
    167 }
    168 
    169 
    170 vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t             *ctx,
    171         vpx_codec_put_slice_cb_fn_t  cb,
    172         void                      *user_priv)
    173 {
    174     vpx_codec_err_t res;
    175 
    176     if (!ctx || !cb)
    177         res = VPX_CODEC_INVALID_PARAM;
    178     else if (!ctx->iface || !ctx->priv
    179              || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
    180         res = VPX_CODEC_ERROR;
    181     else
    182     {
    183         ctx->priv->dec.put_slice_cb.put_slice = cb;
    184         ctx->priv->dec.put_slice_cb.user_priv = user_priv;
    185         res = VPX_CODEC_OK;
    186     }
    187 
    188     return SAVE_STATUS(ctx, res);
    189 }
    190 
    191 
    192 vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t                *ctx,
    193                                       vpx_codec_mmap_t               *mmap,
    194                                       vpx_codec_iter_t               *iter)
    195 {
    196     vpx_codec_err_t res = VPX_CODEC_OK;
    197 
    198     if (!ctx || !mmap || !iter || !ctx->iface)
    199         res = VPX_CODEC_INVALID_PARAM;
    200     else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
    201         res = VPX_CODEC_ERROR;
    202     else
    203         res = ctx->iface->get_mmap(ctx, mmap, iter);
    204 
    205     return SAVE_STATUS(ctx, res);
    206 }
    207 
    208 
    209 vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t   *ctx,
    210                                       vpx_codec_mmap_t  *mmap,
    211                                       unsigned int     num_maps)
    212 {
    213     vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
    214 
    215     if (!ctx || !mmap || !ctx->iface)
    216         res = VPX_CODEC_INVALID_PARAM;
    217     else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
    218         res = VPX_CODEC_ERROR;
    219     else
    220     {
    221         unsigned int i;
    222 
    223         for (i = 0; i < num_maps; i++, mmap++)
    224         {
    225             if (!mmap->base)
    226                 break;
    227 
    228             /* Everything look ok, set the mmap in the decoder */
    229             res = ctx->iface->set_mmap(ctx, mmap);
    230 
    231             if (res)
    232                 break;
    233         }
    234     }
    235 
    236     return SAVE_STATUS(ctx, res);
    237 }
    238