blob: fc1c2bccae77f5067c26bd44af66e316d8908fbd [file] [log] [blame]
John Koleszar0ea50ce2010-05-18 11:58:33 -04001/*
John Koleszarc2140b82010-09-09 08:16:39 -04002 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar0ea50ce2010-05-18 11:58:33 -04003 *
John Koleszar94c52e42010-06-18 12:39:21 -04004 * Use of this source code is governed by a BSD-style license
John Koleszar09202d82010-06-04 16:19:40 -04005 * 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
John Koleszar94c52e42010-06-18 12:39:21 -04007 * in the file PATENTS. All contributing project authors may
John Koleszar09202d82010-06-04 16:19:40 -04008 * be found in the AUTHORS file in the root of the source tree.
John Koleszar0ea50ce2010-05-18 11:58:33 -04009 */
10
James Zernf42d52e2011-02-16 17:54:49 -080011/*!\file
John Koleszar0ea50ce2010-05-18 11:58:33 -040012 * \brief Provides the high level interface to wrap decoder algorithms.
13 *
14 */
James Zerne80d5692010-05-26 18:14:26 -040015#include <string.h>
John Koleszarb7492342010-05-24 11:39:59 -040016#include "vpx/internal/vpx_codec_internal.h"
John Koleszar0ea50ce2010-05-18 11:58:33 -040017
clang-format83a52072016-08-08 20:22:13 -070018#define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
John Koleszar0ea50ce2010-05-18 11:58:33 -040019
Dmitry Kovalev73edeb02014-08-20 17:02:10 -070020static vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) {
21 return (vpx_codec_alg_priv_t *)ctx->priv;
22}
23
clang-format83a52072016-08-08 20:22:13 -070024vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t *ctx,
25 vpx_codec_iface_t *iface,
Dmitry Kovalev44609652014-08-25 14:02:53 -070026 const vpx_codec_dec_cfg_t *cfg,
clang-format83a52072016-08-08 20:22:13 -070027 vpx_codec_flags_t flags, int ver) {
John Koleszarc6b90392012-07-13 15:21:29 -070028 vpx_codec_err_t res;
James Zerne80d5692010-05-26 18:14:26 -040029
John Koleszarc6b90392012-07-13 15:21:29 -070030 if (ver != VPX_DECODER_ABI_VERSION)
31 res = VPX_CODEC_ABI_MISMATCH;
32 else if (!ctx || !iface)
33 res = VPX_CODEC_INVALID_PARAM;
34 else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
35 res = VPX_CODEC_ABI_MISMATCH;
clang-format83a52072016-08-08 20:22:13 -070036 else if ((flags & VPX_CODEC_USE_POSTPROC) &&
37 !(iface->caps & VPX_CODEC_CAP_POSTPROC))
John Koleszarc6b90392012-07-13 15:21:29 -070038 res = VPX_CODEC_INCAPABLE;
John Koleszar83b1d902012-11-05 12:37:14 -080039 else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
40 !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
41 res = VPX_CODEC_INCAPABLE;
42 else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
43 !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
John Koleszarc6b90392012-07-13 15:21:29 -070044 res = VPX_CODEC_INCAPABLE;
45 else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
46 res = VPX_CODEC_INCAPABLE;
47 else {
48 memset(ctx, 0, sizeof(*ctx));
49 ctx->iface = iface;
50 ctx->name = iface->name;
51 ctx->priv = NULL;
52 ctx->init_flags = flags;
53 ctx->config.dec = cfg;
James Zerne80d5692010-05-26 18:14:26 -040054
James Zernfebdebf2014-08-09 19:16:18 -070055 res = ctx->iface->init(ctx, NULL);
56 if (res) {
57 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
58 vpx_codec_destroy(ctx);
James Zerne80d5692010-05-26 18:14:26 -040059 }
John Koleszarc6b90392012-07-13 15:21:29 -070060 }
James Zerne80d5692010-05-26 18:14:26 -040061
John Koleszarc6b90392012-07-13 15:21:29 -070062 return SAVE_STATUS(ctx, res);
James Zerne80d5692010-05-26 18:14:26 -040063}
64
clang-format83a52072016-08-08 20:22:13 -070065vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t *iface,
66 const uint8_t *data,
67 unsigned int data_sz,
John Koleszarc6b90392012-07-13 15:21:29 -070068 vpx_codec_stream_info_t *si) {
69 vpx_codec_err_t res;
John Koleszar0ea50ce2010-05-18 11:58:33 -040070
clang-format83a52072016-08-08 20:22:13 -070071 if (!iface || !data || !data_sz || !si ||
72 si->sz < sizeof(vpx_codec_stream_info_t))
John Koleszarc6b90392012-07-13 15:21:29 -070073 res = VPX_CODEC_INVALID_PARAM;
74 else {
75 /* Set default/unknown values */
76 si->w = 0;
77 si->h = 0;
John Koleszar0ea50ce2010-05-18 11:58:33 -040078
John Koleszarc6b90392012-07-13 15:21:29 -070079 res = iface->dec.peek_si(data, data_sz, si);
80 }
John Koleszar0ea50ce2010-05-18 11:58:33 -040081
John Koleszarc6b90392012-07-13 15:21:29 -070082 return res;
John Koleszar0ea50ce2010-05-18 11:58:33 -040083}
84
clang-format83a52072016-08-08 20:22:13 -070085vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx,
John Koleszarc6b90392012-07-13 15:21:29 -070086 vpx_codec_stream_info_t *si) {
87 vpx_codec_err_t res;
John Koleszar0ea50ce2010-05-18 11:58:33 -040088
John Koleszarc6b90392012-07-13 15:21:29 -070089 if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
90 res = VPX_CODEC_INVALID_PARAM;
91 else if (!ctx->iface || !ctx->priv)
92 res = VPX_CODEC_ERROR;
93 else {
94 /* Set default/unknown values */
95 si->w = 0;
96 si->h = 0;
John Koleszar0ea50ce2010-05-18 11:58:33 -040097
Dmitry Kovalev73edeb02014-08-20 17:02:10 -070098 res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
John Koleszarc6b90392012-07-13 15:21:29 -070099 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400100
John Koleszarc6b90392012-07-13 15:21:29 -0700101 return SAVE_STATUS(ctx, res);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400102}
103
clang-format83a52072016-08-08 20:22:13 -0700104vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, const uint8_t *data,
105 unsigned int data_sz, void *user_priv,
106 long deadline) {
John Koleszarc6b90392012-07-13 15:21:29 -0700107 vpx_codec_err_t res;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400108
John Koleszarc6b90392012-07-13 15:21:29 -0700109 /* Sanity checks */
110 /* NULL data ptr allowed if data_sz is 0 too */
James Zern6a2e9ef2014-08-09 18:35:40 -0700111 if (!ctx || (!data && data_sz) || (data && !data_sz))
John Koleszarc6b90392012-07-13 15:21:29 -0700112 res = VPX_CODEC_INVALID_PARAM;
113 else if (!ctx->iface || !ctx->priv)
114 res = VPX_CODEC_ERROR;
115 else {
Dmitry Kovalev73edeb02014-08-20 17:02:10 -0700116 res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv,
117 deadline);
John Koleszarc6b90392012-07-13 15:21:29 -0700118 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400119
John Koleszarc6b90392012-07-13 15:21:29 -0700120 return SAVE_STATUS(ctx, res);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400121}
122
clang-format83a52072016-08-08 20:22:13 -0700123vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, vpx_codec_iter_t *iter) {
John Koleszarc6b90392012-07-13 15:21:29 -0700124 vpx_image_t *img;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400125
John Koleszarc6b90392012-07-13 15:21:29 -0700126 if (!ctx || !iter || !ctx->iface || !ctx->priv)
127 img = NULL;
128 else
Dmitry Kovalev73edeb02014-08-20 17:02:10 -0700129 img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400130
John Koleszarc6b90392012-07-13 15:21:29 -0700131 return img;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400132}
133
clang-format83a52072016-08-08 20:22:13 -0700134vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t *ctx,
135 vpx_codec_put_frame_cb_fn_t cb,
136 void *user_priv) {
John Koleszarc6b90392012-07-13 15:21:29 -0700137 vpx_codec_err_t res;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400138
John Koleszarc6b90392012-07-13 15:21:29 -0700139 if (!ctx || !cb)
140 res = VPX_CODEC_INVALID_PARAM;
clang-format83a52072016-08-08 20:22:13 -0700141 else if (!ctx->iface || !ctx->priv ||
142 !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
John Koleszarc6b90392012-07-13 15:21:29 -0700143 res = VPX_CODEC_ERROR;
144 else {
145 ctx->priv->dec.put_frame_cb.u.put_frame = cb;
146 ctx->priv->dec.put_frame_cb.user_priv = user_priv;
147 res = VPX_CODEC_OK;
148 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400149
John Koleszarc6b90392012-07-13 15:21:29 -0700150 return SAVE_STATUS(ctx, res);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400151}
152
clang-format83a52072016-08-08 20:22:13 -0700153vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t *ctx,
154 vpx_codec_put_slice_cb_fn_t cb,
155 void *user_priv) {
John Koleszarc6b90392012-07-13 15:21:29 -0700156 vpx_codec_err_t res;
John Koleszar0ea50ce2010-05-18 11:58:33 -0400157
John Koleszarc6b90392012-07-13 15:21:29 -0700158 if (!ctx || !cb)
159 res = VPX_CODEC_INVALID_PARAM;
clang-format83a52072016-08-08 20:22:13 -0700160 else if (!ctx->iface || !ctx->priv ||
161 !(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE))
John Koleszarc6b90392012-07-13 15:21:29 -0700162 res = VPX_CODEC_ERROR;
163 else {
164 ctx->priv->dec.put_slice_cb.u.put_slice = cb;
165 ctx->priv->dec.put_slice_cb.user_priv = user_priv;
166 res = VPX_CODEC_OK;
167 }
John Koleszar0ea50ce2010-05-18 11:58:33 -0400168
John Koleszarc6b90392012-07-13 15:21:29 -0700169 return SAVE_STATUS(ctx, res);
John Koleszar0ea50ce2010-05-18 11:58:33 -0400170}
171
Frank Galligana4f30a52014-02-06 17:13:08 -0800172vpx_codec_err_t vpx_codec_set_frame_buffer_functions(
173 vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get,
174 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
175 vpx_codec_err_t res;
176
177 if (!ctx || !cb_get || !cb_release) {
178 res = VPX_CODEC_INVALID_PARAM;
179 } else if (!ctx->iface || !ctx->priv ||
180 !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
181 res = VPX_CODEC_ERROR;
182 } else {
Dmitry Kovalev73edeb02014-08-20 17:02:10 -0700183 res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
Frank Galligana4f30a52014-02-06 17:13:08 -0800184 cb_priv);
185 }
186
187 return SAVE_STATUS(ctx, res);
188}