summaryrefslogtreecommitdiff
path: root/vpx/src
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2010-05-24 11:39:59 -0400
committerJohn Koleszar <jkoleszar@google.com>2010-05-24 20:27:42 -0400
commitb7492341ac224b9dda9e618f6a9e9ab37e8afa66 (patch)
tree5f9d0e4429be663f3d9274bbba4eaeb4b4cbe159 /vpx/src
parentee8bcb1a7dcecc4dd393129237f234cbb619bab4 (diff)
downloadlibvpx-b7492341ac224b9dda9e618f6a9e9ab37e8afa66.tar
libvpx-b7492341ac224b9dda9e618f6a9e9ab37e8afa66.tar.gz
libvpx-b7492341ac224b9dda9e618f6a9e9ab37e8afa66.tar.bz2
libvpx-b7492341ac224b9dda9e618f6a9e9ab37e8afa66.zip
install includes in DIST_DIR/include/vpx, move vpx_codec/ to vpx/
This renames the vpx_codec/ directory to vpx/, to allow applications to more consistently reference these includes with the vpx/ prefix. This allows the includes to be installed in /usr/local/include/vpx rather than polluting the system includes directory with an excessive number of includes. Change-Id: I7b0652a20543d93f38f421c60b0bbccde4d61b4f
Diffstat (limited to 'vpx/src')
-rw-r--r--vpx/src/vpx_codec.c197
-rw-r--r--vpx/src/vpx_decoder.c201
-rw-r--r--vpx/src/vpx_decoder_compat.c200
-rw-r--r--vpx/src/vpx_encoder.c324
-rw-r--r--vpx/src/vpx_image.c261
5 files changed, 1183 insertions, 0 deletions
diff --git a/vpx/src/vpx_codec.c b/vpx/src/vpx_codec.c
new file mode 100644
index 000000000..45dfce0aa
--- /dev/null
+++ b/vpx/src/vpx_codec.c
@@ -0,0 +1,197 @@
+/*
+ * 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/vpx_integer.h"
+#include "vpx/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);
+}
diff --git a/vpx/src/vpx_decoder.c b/vpx/src/vpx_decoder.c
new file mode 100644
index 000000000..8257f89b2
--- /dev/null
+++ b/vpx/src/vpx_decoder.c
@@ -0,0 +1,201 @@
+/*
+ * 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 "vpx/internal/vpx_codec_internal.h"
+
+#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
+
+vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
+ const uint8_t *data,
+ unsigned int data_sz,
+ vpx_codec_stream_info_t *si)
+{
+ vpx_codec_err_t res;
+
+ if (!iface || !data || !data_sz || !si
+ || si->sz < sizeof(vpx_codec_stream_info_t))
+ res = VPX_CODEC_INVALID_PARAM;
+ else
+ {
+ /* Set default/unknown values */
+ si->w = 0;
+ si->h = 0;
+
+ res = iface->dec.peek_si(data, data_sz, si);
+ }
+
+ return res;
+}
+
+
+vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
+ vpx_codec_stream_info_t *si)
+{
+ vpx_codec_err_t res;
+
+ if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
+ res = VPX_CODEC_INVALID_PARAM;
+ else if (!ctx->iface || !ctx->priv)
+ res = VPX_CODEC_ERROR;
+ else
+ {
+ /* Set default/unknown values */
+ si->w = 0;
+ si->h = 0;
+
+ res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si);
+ }
+
+ return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx,
+ const uint8_t *data,
+ unsigned int data_sz,
+ void *user_priv,
+ long deadline)
+{
+ vpx_codec_err_t res;
+
+ if (!ctx || !data || !data_sz)
+ res = VPX_CODEC_INVALID_PARAM;
+ else if (!ctx->iface || !ctx->priv)
+ res = VPX_CODEC_ERROR;
+
+#if CONFIG_EVAL_LIMIT
+ else if (ctx->priv->eval_counter >= 500)
+ {
+ ctx->priv->err_detail = "Evaluation limit exceeded.";
+ res = VPX_CODEC_ERROR;
+ }
+
+#endif
+ else
+ {
+ res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
+ user_priv, deadline);
+#if CONFIG_EVAL_LIMIT
+ ctx->priv->eval_counter++;
+#endif
+ }
+
+ return SAVE_STATUS(ctx, res);
+}
+
+vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx,
+ vpx_codec_iter_t *iter)
+{
+ vpx_image_t *img;
+
+ if (!ctx || !iter || !ctx->iface || !ctx->priv)
+ img = NULL;
+ else
+ img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
+
+ return img;
+}
+
+
+vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
+ vpx_codec_put_frame_cb_fn_t cb,
+ void *user_priv)
+{
+ vpx_codec_err_t res;
+
+ if (!ctx || !cb)
+ res = VPX_CODEC_INVALID_PARAM;
+ else if (!ctx->iface || !ctx->priv
+ || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
+ res = VPX_CODEC_ERROR;
+ else
+ {
+ ctx->priv->dec.put_frame_cb.put_frame = cb;
+ ctx->priv->dec.put_frame_cb.user_priv = user_priv;
+ res = VPX_CODEC_OK;
+ }
+
+ return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
+ vpx_codec_put_slice_cb_fn_t cb,
+ void *user_priv)
+{
+ vpx_codec_err_t res;
+
+ if (!ctx || !cb)
+ res = VPX_CODEC_INVALID_PARAM;
+ else if (!ctx->iface || !ctx->priv
+ || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
+ res = VPX_CODEC_ERROR;
+ else
+ {
+ ctx->priv->dec.put_slice_cb.put_slice = cb;
+ ctx->priv->dec.put_slice_cb.user_priv = user_priv;
+ res = VPX_CODEC_OK;
+ }
+
+ return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t *ctx,
+ vpx_codec_mmap_t *mmap,
+ vpx_codec_iter_t *iter)
+{
+ vpx_codec_err_t res = VPX_CODEC_OK;
+
+ if (!ctx || !mmap || !iter || !ctx->iface)
+ res = VPX_CODEC_INVALID_PARAM;
+ else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
+ res = VPX_CODEC_ERROR;
+ else
+ res = ctx->iface->get_mmap(ctx, mmap, iter);
+
+ return SAVE_STATUS(ctx, res);
+}
+
+
+vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t *ctx,
+ vpx_codec_mmap_t *mmap,
+ unsigned int num_maps)
+{
+ vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
+
+ if (!ctx || !mmap || !ctx->iface)
+ res = VPX_CODEC_INVALID_PARAM;
+ else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
+ res = VPX_CODEC_ERROR;
+ else
+ {
+ 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;
+ }
+ }
+
+ return SAVE_STATUS(ctx, res);
+}
diff --git a/vpx/src/vpx_decoder_compat.c b/vpx/src/vpx_decoder_compat.c
new file mode 100644
index 000000000..96594fe2f
--- /dev/null
+++ b/vpx/src/vpx_decoder_compat.c
@@ -0,0 +1,200 @@
+/*
+ * 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/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);
+}
diff --git a/vpx/src/vpx_encoder.c b/vpx/src/vpx_encoder.c
new file mode 100644
index 000000000..a9a40de71
--- /dev/null
+++ b/vpx/src/vpx_encoder.c
@@ -0,0 +1,324 @@
+/*
+ * 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_encoder.c
+ * \brief Provides the high level interface to wrap encoder algorithms.
+ *
+ */
+#include <limits.h>
+#include <string.h>
+#include "vpx/internal/vpx_codec_internal.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
+ {
+ ctx->iface = iface;
+ ctx->name = iface->name;
+ ctx->priv = NULL;
+ ctx->init_flags = flags;
+ ctx->config.enc = cfg;
+ 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_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;
+
+ 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;
+
+#if CONFIG_EVAL_LIMIT
+ else if (ctx->priv->eval_counter >= 500)
+ {
+ ctx->priv->err_detail = "Evaluation limit exceeded.";
+ res = VPX_CODEC_ERROR;
+ }
+
+#endif
+ else
+ {
+ /* Execute in a normalized floating point environment, if the platform
+ * requires it.
+ */
+ FLOATING_POINT_INIT();
+ res = ctx->iface->enc.encode(ctx->priv->alg_priv, img, pts,
+ duration, flags, deadline);
+ FLOATING_POINT_RESTORE();
+
+#if CONFIG_EVAL_LIMIT
+ ctx->priv->eval_counter++;
+#endif
+ }
+
+ 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 (pkt - list->pkts < list->cnt)
+ *iter = pkt + 1;
+ else
+ pkt = NULL;
+
+ return pkt;
+}
diff --git a/vpx/src/vpx_image.c b/vpx/src/vpx_image.c
new file mode 100644
index 000000000..881ab1a31
--- /dev/null
+++ b/vpx/src/vpx_image.c
@@ -0,0 +1,261 @@
+/*
+ * 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.
+ */
+
+
+#include <stdlib.h>
+#include <string.h>
+#include "vpx/vpx_image.h"
+
+static vpx_image_t *img_alloc_helper(vpx_image_t *img,
+ vpx_img_fmt_t fmt,
+ unsigned int d_w,
+ unsigned int d_h,
+ unsigned int stride_align,
+ unsigned char *img_data)
+{
+
+ unsigned int h, w, s, xcs, ycs, bps;
+ int align;
+
+ /* Treat align==0 like align==1 */
+ if (!stride_align)
+ stride_align = 1;
+
+ /* Validate alignment (must be power of 2) */
+ if (stride_align & (stride_align - 1))
+ goto fail;
+
+ /* Get sample size for this format */
+ switch (fmt)
+ {
+ case VPX_IMG_FMT_RGB32:
+ case VPX_IMG_FMT_RGB32_LE:
+ case VPX_IMG_FMT_ARGB:
+ case VPX_IMG_FMT_ARGB_LE:
+ bps = 32;
+ break;
+ case VPX_IMG_FMT_RGB24:
+ case VPX_IMG_FMT_BGR24:
+ bps = 24;
+ break;
+ case VPX_IMG_FMT_RGB565:
+ case VPX_IMG_FMT_RGB565_LE:
+ case VPX_IMG_FMT_RGB555:
+ case VPX_IMG_FMT_RGB555_LE:
+ case VPX_IMG_FMT_UYVY:
+ case VPX_IMG_FMT_YUY2:
+ case VPX_IMG_FMT_YVYU:
+ bps = 16;
+ break;
+ case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_YV12:
+ case VPX_IMG_FMT_VPXI420:
+ case VPX_IMG_FMT_VPXYV12:
+ bps = 12;
+ break;
+ default:
+ bps = 16;
+ break;
+ }
+
+ /* Get chroma shift values for this format */
+ switch (fmt)
+ {
+ case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_YV12:
+ case VPX_IMG_FMT_VPXI420:
+ case VPX_IMG_FMT_VPXYV12:
+ xcs = 1;
+ break;
+ default:
+ xcs = 0;
+ break;
+ }
+
+ switch (fmt)
+ {
+ case VPX_IMG_FMT_I420:
+ case VPX_IMG_FMT_YV12:
+ case VPX_IMG_FMT_VPXI420:
+ case VPX_IMG_FMT_VPXYV12:
+ ycs = 1;
+ break;
+ default:
+ ycs = 0;
+ break;
+ }
+
+ /* Calculate storage sizes given the chroma subsampling */
+ align = (1 << xcs) - 1;
+ w = (d_w + align) & ~align;
+ align = (1 << ycs) - 1;
+ h = (d_h + align) & ~align;
+ s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8;
+ s = (s + stride_align - 1) & ~(stride_align - 1);
+
+ /* Allocate the new image */
+ if (!img)
+ {
+ img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t));
+
+ if (!img)
+ goto fail;
+
+ img->self_allocd = 1;
+ }
+ else
+ {
+ memset(img, 0, sizeof(vpx_image_t));
+ }
+
+ img->img_data = img_data;
+
+ if (!img_data)
+ {
+ img->img_data = malloc((fmt & VPX_IMG_FMT_PLANAR) ? h * w * bps / 8 : h * s);
+ img->img_data_owner = 1;
+ }
+
+ if (!img->img_data)
+ goto fail;
+
+ img->fmt = fmt;
+ img->w = w;
+ img->h = h;
+ img->x_chroma_shift = xcs;
+ img->y_chroma_shift = ycs;
+ img->bps = bps;
+
+ /* Calculate strides */
+ img->stride[PLANE_Y] = img->stride[PLANE_ALPHA] = s;
+ img->stride[PLANE_U] = img->stride[PLANE_V] = s >> xcs;
+
+ /* Default viewport to entire image */
+ if (!vpx_img_set_rect(img, 0, 0, d_w, d_h))
+ return img;
+
+fail:
+ vpx_img_free(img);
+ return NULL;
+}
+
+vpx_image_t *vpx_img_alloc(vpx_image_t *img,
+ vpx_img_fmt_t fmt,
+ unsigned int d_w,
+ unsigned int d_h,
+ unsigned int stride_align)
+{
+ return img_alloc_helper(img, fmt, d_w, d_h, stride_align, NULL);
+}
+
+vpx_image_t *vpx_img_wrap(vpx_image_t *img,
+ vpx_img_fmt_t fmt,
+ unsigned int d_w,
+ unsigned int d_h,
+ unsigned int stride_align,
+ unsigned char *img_data)
+{
+ return img_alloc_helper(img, fmt, d_w, d_h, stride_align, img_data);
+}
+
+int vpx_img_set_rect(vpx_image_t *img,
+ unsigned int x,
+ unsigned int y,
+ unsigned int w,
+ unsigned int h)
+{
+ unsigned char *data;
+
+ if (x + w <= img->w && y + h <= img->h)
+ {
+ img->d_w = w;
+ img->d_h = h;
+
+ /* Calculate plane pointers */
+ if (!(img->fmt & VPX_IMG_FMT_PLANAR))
+ {
+ img->planes[PLANE_PACKED] =
+ img->img_data + x * img->bps / 8 + y * img->stride[PLANE_PACKED];
+ }
+ else
+ {
+ data = img->img_data;
+
+ if (img->fmt & VPX_IMG_FMT_HAS_ALPHA)
+ {
+ img->planes[PLANE_ALPHA] =
+ data + x + y * img->stride[PLANE_ALPHA];
+ data += img->h * img->stride[PLANE_ALPHA];
+ }
+
+ img->planes[PLANE_Y] = data + x + y * img->stride[PLANE_Y];
+ data += img->h * img->stride[PLANE_Y];
+
+ if (!(img->fmt & VPX_IMG_FMT_UV_FLIP))
+ {
+ img->planes[PLANE_U] = data
+ + (x >> img->x_chroma_shift)
+ + (y >> img->y_chroma_shift) * img->stride[PLANE_U];
+ data += (img->h >> img->y_chroma_shift) * img->stride[PLANE_U];
+ img->planes[PLANE_V] = data
+ + (x >> img->x_chroma_shift)
+ + (y >> img->y_chroma_shift) * img->stride[PLANE_V];
+ }
+ else
+ {
+ img->planes[PLANE_V] = data
+ + (x >> img->x_chroma_shift)
+ + (y >> img->y_chroma_shift) * img->stride[PLANE_V];
+ data += (img->h >> img->y_chroma_shift) * img->stride[PLANE_V];
+ img->planes[PLANE_U] = data
+ + (x >> img->x_chroma_shift)
+ + (y >> img->y_chroma_shift) * img->stride[PLANE_U];
+ }
+ }
+
+ return 0;
+ }
+
+ return -1;
+}
+
+void vpx_img_flip(vpx_image_t *img)
+{
+ /* Note: In the calculation pointer adjustment calculation, we want the
+ * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
+ * standard indicates that if the adjustment parameter is unsigned, the
+ * stride parameter will be promoted to unsigned, causing errors when
+ * the lhs is a larger type than the rhs.
+ */
+ img->planes[PLANE_Y] += (signed)(img->d_h - 1) * img->stride[PLANE_Y];
+ img->stride[PLANE_Y] = -img->stride[PLANE_Y];
+
+ img->planes[PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
+ * img->stride[PLANE_U];
+ img->stride[PLANE_U] = -img->stride[PLANE_U];
+
+ img->planes[PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
+ * img->stride[PLANE_V];
+ img->stride[PLANE_V] = -img->stride[PLANE_V];
+
+ img->planes[PLANE_ALPHA] += (signed)(img->d_h - 1) * img->stride[PLANE_ALPHA];
+ img->stride[PLANE_ALPHA] = -img->stride[PLANE_ALPHA];
+}
+
+void vpx_img_free(vpx_image_t *img)
+{
+ if (img)
+ {
+ if (img->img_data && img->img_data_owner)
+ free(img->img_data);
+
+ if (img->self_allocd)
+ free(img);
+ }
+}