/*
 *  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 encoder algorithms.
 *
 */
#include <limits.h>
#include <string.h>
#include "vpx/internal/vpx_codec_internal.h"
#include "vpx_config.h"

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

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

  if (ver != VPX_ENCODER_ABI_VERSION)
    res = VPX_CODEC_ABI_MISMATCH;
  else if (!ctx || !iface || !cfg)
    res = VPX_CODEC_INVALID_PARAM;
  else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
    res = VPX_CODEC_ABI_MISMATCH;
  else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
    res = VPX_CODEC_INCAPABLE;
  else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
    res = VPX_CODEC_INCAPABLE;
  else if ((flags & VPX_CODEC_USE_PSNR)
           && !(iface->caps & VPX_CODEC_CAP_PSNR))
    res = VPX_CODEC_INCAPABLE;
  else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION)
           && !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION))
    res = VPX_CODEC_INCAPABLE;
  else {
    ctx->iface = iface;
    ctx->name = iface->name;
    ctx->priv = NULL;
    ctx->init_flags = flags;
    ctx->config.enc = cfg;
    res = ctx->iface->init(ctx, NULL);

    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_enc_init_multi_ver(vpx_codec_ctx_t      *ctx,
                                             vpx_codec_iface_t    *iface,
                                             vpx_codec_enc_cfg_t  *cfg,
                                             int                   num_enc,
                                             vpx_codec_flags_t     flags,
                                             vpx_rational_t       *dsf,
                                             int                   ver) {
  vpx_codec_err_t res = 0;

  if (ver != VPX_ENCODER_ABI_VERSION)
    res = VPX_CODEC_ABI_MISMATCH;
  else if (!ctx || !iface || !cfg || (num_enc > 16 || num_enc < 1))
    res = VPX_CODEC_INVALID_PARAM;
  else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
    res = VPX_CODEC_ABI_MISMATCH;
  else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
    res = VPX_CODEC_INCAPABLE;
  else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
    res = VPX_CODEC_INCAPABLE;
  else if ((flags & VPX_CODEC_USE_PSNR)
           && !(iface->caps & VPX_CODEC_CAP_PSNR))
    res = VPX_CODEC_INCAPABLE;
  else if ((flags & VPX_CODEC_USE_OUTPUT_PARTITION)
           && !(iface->caps & VPX_CODEC_CAP_OUTPUT_PARTITION))
    res = VPX_CODEC_INCAPABLE;
  else {
    int i;
    void *mem_loc = NULL;

    if (!(res = iface->enc.mr_get_mem_loc(cfg, &mem_loc))) {
      for (i = 0; i < num_enc; i++) {
        vpx_codec_priv_enc_mr_cfg_t mr_cfg;

        /* Validate down-sampling factor. */
        if (dsf->num < 1 || dsf->num > 4096 || dsf->den < 1 ||
            dsf->den > dsf->num) {
          res = VPX_CODEC_INVALID_PARAM;
          break;
        }

        mr_cfg.mr_low_res_mode_info = mem_loc;
        mr_cfg.mr_total_resolutions = num_enc;
        mr_cfg.mr_encoder_id = num_enc - 1 - i;
        mr_cfg.mr_down_sampling_factor.num = dsf->num;
        mr_cfg.mr_down_sampling_factor.den = dsf->den;

        /* Force Key-frame synchronization. Namely, encoder at higher
         * resolution always use the same frame_type chosen by the
         * lowest-resolution encoder.
         */
        if (mr_cfg.mr_encoder_id)
          cfg->kf_mode = VPX_KF_DISABLED;

        ctx->iface = iface;
        ctx->name = iface->name;
        ctx->priv = NULL;
        ctx->init_flags = flags;
        ctx->config.enc = cfg;
        res = ctx->iface->init(ctx, &mr_cfg);

        if (res) {
          const char *error_detail =
            ctx->priv ? ctx->priv->err_detail : NULL;
          /* Destroy current ctx */
          ctx->err_detail = error_detail;
          vpx_codec_destroy(ctx);

          /* Destroy already allocated high-level ctx */
          while (i) {
            ctx--;
            ctx->err_detail = error_detail;
            vpx_codec_destroy(ctx);
            i--;
          }
        }

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

        if (res)
          break;

        ctx++;
        cfg++;
        dsf++;
      }
      ctx--;
    }
  }

  return SAVE_STATUS(ctx, res);
}


vpx_codec_err_t  vpx_codec_enc_config_default(vpx_codec_iface_t    *iface,
                                              vpx_codec_enc_cfg_t  *cfg,
                                              unsigned int          usage) {
  vpx_codec_err_t res;
  vpx_codec_enc_cfg_map_t *map;

  if (!iface || !cfg || usage > INT_MAX)
    res = VPX_CODEC_INVALID_PARAM;
  else if (!(iface->caps & VPX_CODEC_CAP_ENCODER))
    res = VPX_CODEC_INCAPABLE;
  else {
    res = VPX_CODEC_INVALID_PARAM;

    for (map = iface->enc.cfg_maps; map->usage >= 0; map++) {
      if (map->usage == (int)usage) {
        *cfg = map->cfg;
        cfg->g_usage = usage;
        res = VPX_CODEC_OK;
        break;
      }
    }
  }

  return res;
}


#if ARCH_X86 || ARCH_X86_64
/* On X86, disable the x87 unit's internal 80 bit precision for better
 * consistency with the SSE unit's 64 bit precision.
 */
#include "vpx_ports/x86.h"
#define FLOATING_POINT_INIT() do {\
    unsigned short x87_orig_mode = x87_set_double_precision();
#define FLOATING_POINT_RESTORE() \
  x87_set_control_word(x87_orig_mode); }while(0)


#else
static void FLOATING_POINT_INIT() {}
static void FLOATING_POINT_RESTORE() {}
#endif


vpx_codec_err_t  vpx_codec_encode(vpx_codec_ctx_t            *ctx,
                                  const vpx_image_t          *img,
                                  vpx_codec_pts_t             pts,
                                  unsigned long               duration,
                                  vpx_enc_frame_flags_t       flags,
                                  unsigned long               deadline) {
  vpx_codec_err_t res = 0;

  if (!ctx || (img && !duration))
    res = VPX_CODEC_INVALID_PARAM;
  else if (!ctx->iface || !ctx->priv)
    res = VPX_CODEC_ERROR;
  else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
    res = VPX_CODEC_INCAPABLE;
  else {
    unsigned int num_enc = ctx->priv->enc.total_encoders;

    /* Execute in a normalized floating point environment, if the platform
     * requires it.
     */
    FLOATING_POINT_INIT();

    if (num_enc == 1)
      res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts,
                                   duration, flags, deadline);
    else {
      /* Multi-resolution encoding:
       * Encode multi-levels in reverse order. For example,
       * if mr_total_resolutions = 3, first encode level 2,
       * then encode level 1, and finally encode level 0.
       */
      int i;

      ctx += num_enc - 1;
      if (img) img += num_enc - 1;

      for (i = num_enc - 1; i >= 0; i--) {
        if ((res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts,
                                          duration, flags, deadline)))
          break;

        ctx--;
        if (img) img--;
      }
      ctx++;
    }

    FLOATING_POINT_RESTORE();
  }

  return SAVE_STATUS(ctx, res);
}


const vpx_codec_cx_pkt_t *vpx_codec_get_cx_data(vpx_codec_ctx_t   *ctx,
                                                vpx_codec_iter_t  *iter) {
  const vpx_codec_cx_pkt_t *pkt = NULL;

  if (ctx) {
    if (!iter)
      ctx->err = VPX_CODEC_INVALID_PARAM;
    else if (!ctx->iface || !ctx->priv)
      ctx->err = VPX_CODEC_ERROR;
    else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
      ctx->err = VPX_CODEC_INCAPABLE;
    else
      pkt = ctx->iface->enc.get_cx_data(ctx->priv->alg_priv, iter);
  }

  if (pkt && pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
    /* If the application has specified a destination area for the
     * compressed data, and the codec has not placed the data there,
     * and it fits, copy it.
     */
    char *dst_buf = ctx->priv->enc.cx_data_dst_buf.buf;

    if (dst_buf
        && pkt->data.raw.buf != dst_buf
        && pkt->data.raw.sz
        + ctx->priv->enc.cx_data_pad_before
        + ctx->priv->enc.cx_data_pad_after
        <= ctx->priv->enc.cx_data_dst_buf.sz) {
      vpx_codec_cx_pkt_t *modified_pkt = &ctx->priv->enc.cx_data_pkt;

      memcpy(dst_buf + ctx->priv->enc.cx_data_pad_before,
             pkt->data.raw.buf, pkt->data.raw.sz);
      *modified_pkt = *pkt;
      modified_pkt->data.raw.buf = dst_buf;
      modified_pkt->data.raw.sz += ctx->priv->enc.cx_data_pad_before
                                   + ctx->priv->enc.cx_data_pad_after;
      pkt = modified_pkt;
    }

    if (dst_buf == pkt->data.raw.buf) {
      ctx->priv->enc.cx_data_dst_buf.buf = dst_buf + pkt->data.raw.sz;
      ctx->priv->enc.cx_data_dst_buf.sz -= pkt->data.raw.sz;
    }
  }

  return pkt;
}


vpx_codec_err_t vpx_codec_set_cx_data_buf(vpx_codec_ctx_t       *ctx,
                                          const vpx_fixed_buf_t *buf,
                                          unsigned int           pad_before,
                                          unsigned int           pad_after) {
  if (!ctx || !ctx->priv)
    return VPX_CODEC_INVALID_PARAM;

  if (buf) {
    ctx->priv->enc.cx_data_dst_buf = *buf;
    ctx->priv->enc.cx_data_pad_before = pad_before;
    ctx->priv->enc.cx_data_pad_after = pad_after;
  } else {
    ctx->priv->enc.cx_data_dst_buf.buf = NULL;
    ctx->priv->enc.cx_data_dst_buf.sz = 0;
    ctx->priv->enc.cx_data_pad_before = 0;
    ctx->priv->enc.cx_data_pad_after = 0;
  }

  return VPX_CODEC_OK;
}


const vpx_image_t *vpx_codec_get_preview_frame(vpx_codec_ctx_t   *ctx) {
  vpx_image_t *img = NULL;

  if (ctx) {
    if (!ctx->iface || !ctx->priv)
      ctx->err = VPX_CODEC_ERROR;
    else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
      ctx->err = VPX_CODEC_INCAPABLE;
    else if (!ctx->iface->enc.get_preview)
      ctx->err = VPX_CODEC_INCAPABLE;
    else
      img = ctx->iface->enc.get_preview(ctx->priv->alg_priv);
  }

  return img;
}


vpx_fixed_buf_t *vpx_codec_get_global_headers(vpx_codec_ctx_t   *ctx) {
  vpx_fixed_buf_t *buf = NULL;

  if (ctx) {
    if (!ctx->iface || !ctx->priv)
      ctx->err = VPX_CODEC_ERROR;
    else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
      ctx->err = VPX_CODEC_INCAPABLE;
    else if (!ctx->iface->enc.get_glob_hdrs)
      ctx->err = VPX_CODEC_INCAPABLE;
    else
      buf = ctx->iface->enc.get_glob_hdrs(ctx->priv->alg_priv);
  }

  return buf;
}


vpx_codec_err_t  vpx_codec_enc_config_set(vpx_codec_ctx_t            *ctx,
                                          const vpx_codec_enc_cfg_t  *cfg) {
  vpx_codec_err_t res;

  if (!ctx || !ctx->iface || !ctx->priv || !cfg)
    res = VPX_CODEC_INVALID_PARAM;
  else if (!(ctx->iface->caps & VPX_CODEC_CAP_ENCODER))
    res = VPX_CODEC_INCAPABLE;
  else
    res = ctx->iface->enc.cfg_set(ctx->priv->alg_priv, cfg);

  return SAVE_STATUS(ctx, res);
}


int vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *list,
                           const struct vpx_codec_cx_pkt *pkt) {
  if (list->cnt < list->max) {
    list->pkts[list->cnt++] = *pkt;
    return 0;
  }

  return 1;
}


const vpx_codec_cx_pkt_t *vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
                                                 vpx_codec_iter_t           *iter) {
  const vpx_codec_cx_pkt_t *pkt;

  if (!(*iter)) {
    *iter = list->pkts;
  }

  pkt = (const void *) * iter;

  if ((size_t)(pkt - list->pkts) < list->cnt)
    *iter = pkt + 1;
  else
    pkt = NULL;

  return pkt;
}
