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


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

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

const char *vpx_dec_iface_name(vpx_dec_iface_t *iface)
{
    return vpx_codec_iface_name((vpx_codec_iface_t *)iface);
}

const char *vpx_dec_err_to_string(vpx_dec_err_t  err)
{
    return vpx_codec_err_to_string(err);
}

const char *vpx_dec_error(vpx_dec_ctx_t  *ctx)
{
    return vpx_codec_error((vpx_codec_ctx_t *)ctx);
}

const char *vpx_dec_error_detail(vpx_dec_ctx_t  *ctx)
{
    return vpx_codec_error_detail((vpx_codec_ctx_t *)ctx);
}


vpx_dec_err_t vpx_dec_init_ver(vpx_dec_ctx_t    *ctx,
                               vpx_dec_iface_t  *iface,
                               int               ver)
{
    return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
                                  (vpx_codec_iface_t *)iface,
                                  NULL,
                                  0,
                                  ver);
}


vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx)
{
    return vpx_codec_destroy((vpx_codec_ctx_t *)ctx);
}


vpx_dec_caps_t vpx_dec_get_caps(vpx_dec_iface_t *iface)
{
    return vpx_codec_get_caps((vpx_codec_iface_t *)iface);
}


vpx_dec_err_t vpx_dec_peek_stream_info(vpx_dec_iface_t       *iface,
                                       const uint8_t         *data,
                                       unsigned int           data_sz,
                                       vpx_dec_stream_info_t *si)
{
    return vpx_codec_peek_stream_info((vpx_codec_iface_t *)iface, data, data_sz,
                                      (vpx_codec_stream_info_t *)si);
}


vpx_dec_err_t vpx_dec_get_stream_info(vpx_dec_ctx_t         *ctx,
                                      vpx_dec_stream_info_t *si)
{
    return vpx_codec_get_stream_info((vpx_codec_ctx_t *)ctx,
                                     (vpx_codec_stream_info_t *)si);
}


vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t  *ctx,
                              int             ctrl_id,
                              void           *data)
{
    return vpx_codec_control_((vpx_codec_ctx_t *)ctx, ctrl_id, data);
}


vpx_dec_err_t vpx_dec_decode(vpx_dec_ctx_t  *ctx,
                             uint8_t        *data,
                             unsigned int    data_sz,
                             void       *user_priv,
                             int         rel_pts)
{
    (void)rel_pts;
    return vpx_codec_decode((vpx_codec_ctx_t *)ctx, data, data_sz, user_priv,
                            0);
}

vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t  *ctx,
                               vpx_dec_iter_t *iter)
{
    return vpx_codec_get_frame((vpx_codec_ctx_t *)ctx, iter);
}


vpx_dec_err_t vpx_dec_register_put_frame_cb(vpx_dec_ctx_t             *ctx,
        vpx_dec_put_frame_cb_fn_t  cb,
        void                      *user_priv)
{
    return vpx_codec_register_put_frame_cb((vpx_codec_ctx_t *)ctx, cb,
                                           user_priv);
}


vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t             *ctx,
        vpx_dec_put_slice_cb_fn_t  cb,
        void                      *user_priv)
{
    return vpx_codec_register_put_slice_cb((vpx_codec_ctx_t *)ctx, cb,
                                           user_priv);
}


vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t    *ctx,
                                   vpx_dec_iface_t  *iface,
                                   int               ver)
{
    return vpx_codec_dec_init_ver((vpx_codec_ctx_t *)ctx,
                                  (vpx_codec_iface_t *)iface,
                                  NULL,
                                  VPX_CODEC_USE_XMA,
                                  ver);
}

vpx_dec_err_t vpx_dec_get_mem_map(vpx_dec_ctx_t                *ctx_,
                                  vpx_dec_mmap_t               *mmap,
                                  const vpx_dec_stream_info_t  *si,
                                  vpx_dec_iter_t               *iter)
{
    vpx_codec_ctx_t   *ctx = (vpx_codec_ctx_t *)ctx_;
    vpx_dec_err_t      res = VPX_DEC_OK;

    if (!ctx || !mmap || !si || !iter || !ctx->iface)
        res = VPX_DEC_INVALID_PARAM;
    else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
        res = VPX_DEC_ERROR;
    else
    {
        if (!ctx->config.dec)
        {
            ctx->config.dec = malloc(sizeof(vpx_codec_dec_cfg_t));
            ctx->config.dec->w = si->w;
            ctx->config.dec->h = si->h;
        }

        res = ctx->iface->get_mmap(ctx, mmap, iter);
    }

    return SAVE_STATUS(ctx, res);
}


vpx_dec_err_t vpx_dec_set_mem_map(vpx_dec_ctx_t   *ctx_,
                                  vpx_dec_mmap_t  *mmap,
                                  unsigned int     num_maps)
{
    vpx_codec_ctx_t   *ctx = (vpx_codec_ctx_t *)ctx_;
    vpx_dec_err_t      res = VPX_DEC_MEM_ERROR;

    if (!ctx || !mmap || !ctx->iface)
        res = VPX_DEC_INVALID_PARAM;
    else if (!(ctx->iface->caps & VPX_DEC_CAP_XMA))
        res = VPX_DEC_ERROR;
    else
    {
        void         *save = (ctx->priv) ? NULL : ctx->config.dec;
        unsigned int i;

        for (i = 0; i < num_maps; i++, mmap++)
        {
            if (!mmap->base)
                break;

            /* Everything look ok, set the mmap in the decoder */
            res = ctx->iface->set_mmap(ctx, mmap);

            if (res)
                break;
        }

        if (save) free(save);
    }

    return SAVE_STATUS(ctx, res);
}
