/*
 *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license and patent
 *  grant that can be found in the LICENSE file in the root of the source
 *  tree. All contributing project authors may be found in the AUTHORS
 *  file in the root of the source tree.
 */


/*!\file vpx_decoder.c
 * \brief Provides the high level interface to wrap decoder algorithms.
 *
 */
#include <stdlib.h>
#include <string.h>
#include "vpx_codec/internal/vpx_codec_internal.h"
#include "vpx_version.h"

#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)

int vpx_codec_version(void)
{
    return VERSION_PACKED;
}


const char *vpx_codec_version_str(void)
{
    return VERSION_STRING_NOSP;
}


const char *vpx_codec_version_extra_str(void)
{
    return VERSION_EXTRA;
}


const char *vpx_codec_iface_name(vpx_codec_iface_t *iface)
{
    return iface ? iface->name : "<invalid interface>";
}

const char *vpx_codec_err_to_string(vpx_codec_err_t  err)
{
    switch (err)
    {
    case VPX_CODEC_OK:
        return "Success";
    case VPX_CODEC_ERROR:
        return "Unspecified internal error";
    case VPX_CODEC_MEM_ERROR:
        return "Memory allocation error";
    case VPX_CODEC_ABI_MISMATCH:
        return "ABI version mismatch";
    case VPX_CODEC_INCAPABLE:
        return "Codec does not implement requested capability";
    case VPX_CODEC_UNSUP_BITSTREAM:
        return "Bitstream not supported by this decoder";
    case VPX_CODEC_UNSUP_FEATURE:
        return "Bitstream required feature not supported by this decoder";
    case VPX_CODEC_CORRUPT_FRAME:
        return "Corrupt frame detected";
    case  VPX_CODEC_INVALID_PARAM:
        return "Invalid parameter";
    case VPX_CODEC_LIST_END:
        return "End of iterated list";
    }

    return "Unrecognized error code";
}

const char *vpx_codec_error(vpx_codec_ctx_t  *ctx)
{
    return (ctx) ? vpx_codec_err_to_string(ctx->err)
           : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
}

const char *vpx_codec_error_detail(vpx_codec_ctx_t  *ctx)
{
    if (ctx && ctx->err)
        return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;

    return NULL;
}


vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
                                       vpx_codec_iface_t    *iface,
                                       vpx_codec_dec_cfg_t  *cfg,
                                       vpx_codec_flags_t     flags,
                                       int                   ver)
{
    vpx_codec_err_t res;

    if (ver != VPX_DECODER_ABI_VERSION)
        res = VPX_CODEC_ABI_MISMATCH;
    else if (!ctx || !iface)
        res = VPX_CODEC_INVALID_PARAM;
    else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
        res = VPX_CODEC_ABI_MISMATCH;
    else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
        res = VPX_CODEC_INCAPABLE;
    else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
        res = VPX_CODEC_INCAPABLE;
    else
    {
        memset(ctx, 0, sizeof(*ctx));
        ctx->iface = iface;
        ctx->name = iface->name;
        ctx->priv = NULL;
        ctx->init_flags = flags;
        ctx->config.dec = cfg;
        res = VPX_CODEC_OK;

        if (!(flags & VPX_CODEC_USE_XMA))
        {
            res = ctx->iface->init(ctx);

            if (res)
            {
                ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
                vpx_codec_destroy(ctx);
            }

            if (ctx->priv)
                ctx->priv->iface = ctx->iface;
        }
    }

    return SAVE_STATUS(ctx, res);
}


vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
{
    vpx_codec_err_t res;

    if (!ctx)
        res = VPX_CODEC_INVALID_PARAM;
    else if (!ctx->iface || !ctx->priv)
        res = VPX_CODEC_ERROR;
    else
    {
        if (ctx->priv->alg_priv)
            ctx->iface->destroy(ctx->priv->alg_priv);

        ctx->iface = NULL;
        ctx->name = NULL;
        ctx->priv = NULL;
        res = VPX_CODEC_OK;
    }

    return SAVE_STATUS(ctx, res);
}


vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface)
{
    return (iface) ? iface->caps : 0;
}


vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t  *ctx,
                                   int               ctrl_id,
                                   ...)
{
    vpx_codec_err_t res;

    if (!ctx || !ctrl_id)
        res = VPX_CODEC_INVALID_PARAM;
    else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
        res = VPX_CODEC_ERROR;
    else
    {
        vpx_codec_ctrl_fn_map_t *entry;

        res = VPX_CODEC_ERROR;

        for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++)
        {
            if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
            {
                va_list  ap;

                va_start(ap, ctrl_id);
                res = entry->fn(ctx->priv->alg_priv, ctrl_id, ap);
                va_end(ap);
                break;
            }
        }
    }

    return SAVE_STATUS(ctx, res);
}
