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
     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 if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
     40             !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
     41         res = VPX_CODEC_INCAPABLE;
     42     else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
     43             !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
     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, NULL);
     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 
     76 vpx_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 
     99 vpx_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 
    121 vpx_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 
    144 vpx_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 
    158 vpx_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 
    180 vpx_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 
    202 vpx_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 
    219 vpx_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