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 <stdarg.h>
     17 #include <stdlib.h>
     18 #include "vpx/vpx_integer.h"
     19 #include "vpx/internal/vpx_codec_internal.h"
     20 #include "vpx_version.h"
     21 
     22 #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
     23 
     24 int vpx_codec_version(void) {
     25   return VERSION_PACKED;
     26 }
     27 
     28 
     29 const char *vpx_codec_version_str(void) {
     30   return VERSION_STRING_NOSP;
     31 }
     32 
     33 
     34 const char *vpx_codec_version_extra_str(void) {
     35   return VERSION_EXTRA;
     36 }
     37 
     38 
     39 const char *vpx_codec_iface_name(vpx_codec_iface_t *iface) {
     40   return iface ? iface->name : "<invalid interface>";
     41 }
     42 
     43 const char *vpx_codec_err_to_string(vpx_codec_err_t  err) {
     44   switch (err) {
     45     case VPX_CODEC_OK:
     46       return "Success";
     47     case VPX_CODEC_ERROR:
     48       return "Unspecified internal error";
     49     case VPX_CODEC_MEM_ERROR:
     50       return "Memory allocation error";
     51     case VPX_CODEC_ABI_MISMATCH:
     52       return "ABI version mismatch";
     53     case VPX_CODEC_INCAPABLE:
     54       return "Codec does not implement requested capability";
     55     case VPX_CODEC_UNSUP_BITSTREAM:
     56       return "Bitstream not supported by this decoder";
     57     case VPX_CODEC_UNSUP_FEATURE:
     58       return "Bitstream required feature not supported by this decoder";
     59     case VPX_CODEC_CORRUPT_FRAME:
     60       return "Corrupt frame detected";
     61     case  VPX_CODEC_INVALID_PARAM:
     62       return "Invalid parameter";
     63     case VPX_CODEC_LIST_END:
     64       return "End of iterated list";
     65   }
     66 
     67   return "Unrecognized error code";
     68 }
     69 
     70 const char *vpx_codec_error(vpx_codec_ctx_t  *ctx) {
     71   return (ctx) ? vpx_codec_err_to_string(ctx->err)
     72          : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
     73 }
     74 
     75 const char *vpx_codec_error_detail(vpx_codec_ctx_t  *ctx) {
     76   if (ctx && ctx->err)
     77     return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;
     78 
     79   return NULL;
     80 }
     81 
     82 
     83 vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx) {
     84   vpx_codec_err_t res;
     85 
     86   if (!ctx)
     87     res = VPX_CODEC_INVALID_PARAM;
     88   else if (!ctx->iface || !ctx->priv)
     89     res = VPX_CODEC_ERROR;
     90   else {
     91     if (ctx->priv->alg_priv)
     92       ctx->iface->destroy(ctx->priv->alg_priv);
     93 
     94     ctx->iface = NULL;
     95     ctx->name = NULL;
     96     ctx->priv = NULL;
     97     res = VPX_CODEC_OK;
     98   }
     99 
    100   return SAVE_STATUS(ctx, res);
    101 }
    102 
    103 
    104 vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface) {
    105   return (iface) ? iface->caps : 0;
    106 }
    107 
    108 
    109 vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t  *ctx,
    110                                    int               ctrl_id,
    111                                    ...) {
    112   vpx_codec_err_t res;
    113 
    114   if (!ctx || !ctrl_id)
    115     res = VPX_CODEC_INVALID_PARAM;
    116   else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
    117     res = VPX_CODEC_ERROR;
    118   else {
    119     vpx_codec_ctrl_fn_map_t *entry;
    120 
    121     res = VPX_CODEC_ERROR;
    122 
    123     for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++) {
    124       if (!entry->ctrl_id || entry->ctrl_id == ctrl_id) {
    125         va_list  ap;
    126 
    127         va_start(ap, ctrl_id);
    128         res = entry->fn(ctx->priv->alg_priv, ctrl_id, ap);
    129         va_end(ap);
    130         break;
    131       }
    132     }
    133   }
    134 
    135   return SAVE_STATUS(ctx, res);
    136 }
    137 
    138 //------------------------------------------------------------------------------
    139 // mmap interface
    140 
    141 vpx_codec_err_t vpx_mmap_alloc(vpx_codec_mmap_t *mmap) {
    142   unsigned int align = mmap->align ? mmap->align - 1 : 0;
    143 
    144   if (mmap->flags & VPX_CODEC_MEM_ZERO)
    145     mmap->priv = calloc(1, mmap->sz + align);
    146   else
    147     mmap->priv = malloc(mmap->sz + align);
    148 
    149   if (mmap->priv == NULL) return VPX_CODEC_MEM_ERROR;
    150   mmap->base = (void *)((((uintptr_t)mmap->priv) + align) & ~(uintptr_t)align);
    151   mmap->dtor = vpx_mmap_dtor;
    152   return VPX_CODEC_OK;
    153 }
    154 
    155 void vpx_mmap_dtor(vpx_codec_mmap_t *mmap) {
    156   free(mmap->priv);
    157 }
    158 
    159 vpx_codec_err_t vpx_validate_mmaps(const vpx_codec_stream_info_t *si,
    160                                    const vpx_codec_mmap_t *mmaps,
    161                                    const mem_req_t *mem_reqs, int nreqs,
    162                                    vpx_codec_flags_t init_flags) {
    163   int i;
    164 
    165   for (i = 0; i < nreqs - 1; ++i) {
    166     /* Ensure the segment has been allocated */
    167     if (mmaps[i].base == NULL) {
    168       return VPX_CODEC_MEM_ERROR;
    169     }
    170 
    171     /* Verify variable size segment is big enough for the current si. */
    172     if (mem_reqs[i].calc_sz != NULL) {
    173       vpx_codec_dec_cfg_t cfg;
    174 
    175       cfg.w = si->w;
    176       cfg.h = si->h;
    177 
    178       if (mmaps[i].sz < mem_reqs[i].calc_sz(&cfg, init_flags)) {
    179         return VPX_CODEC_MEM_ERROR;
    180       }
    181     }
    182   }
    183   return VPX_CODEC_OK;
    184 }
    185