190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1279f15823c34ae1e423108295e416213200bb280fAndreas Huber/*!\file
1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber * \brief Provides the high level interface to wrap decoder algorithms.
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
1590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
16f71323e297a928af368937089d3ed71239786f86Andreas Huber#include <string.h>
17f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "vpx/internal/vpx_codec_internal.h"
1890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
21da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanianstatic vpx_codec_alg_priv_t *get_alg_priv(vpx_codec_ctx_t *ctx) {
22da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  return (vpx_codec_alg_priv_t *)ctx->priv;
23da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian}
24da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
25f71323e297a928af368937089d3ed71239786f86Andreas Hubervpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
26f71323e297a928af368937089d3ed71239786f86Andreas Huber                                       vpx_codec_iface_t    *iface,
27da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                       const vpx_codec_dec_cfg_t *cfg,
28f71323e297a928af368937089d3ed71239786f86Andreas Huber                                       vpx_codec_flags_t     flags,
29ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                       int                   ver) {
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_err_t res;
31ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (ver != VPX_DECODER_ABI_VERSION)
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_ABI_MISMATCH;
34ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (!ctx || !iface)
35ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INVALID_PARAM;
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
37ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_ABI_MISMATCH;
38ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INCAPABLE;
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if ((flags & VPX_CODEC_USE_ERROR_CONCEALMENT) &&
41ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           !(iface->caps & VPX_CODEC_CAP_ERROR_CONCEALMENT))
42ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INCAPABLE;
43ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if ((flags & VPX_CODEC_USE_INPUT_FRAGMENTS) &&
44ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           !(iface->caps & VPX_CODEC_CAP_INPUT_FRAGMENTS))
45ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INCAPABLE;
46ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (!(iface->caps & VPX_CODEC_CAP_DECODER))
47ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INCAPABLE;
48ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
49ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memset(ctx, 0, sizeof(*ctx));
50ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->iface = iface;
51ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->name = iface->name;
52ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->priv = NULL;
53ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->init_flags = flags;
54ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->config.dec = cfg;
55ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    res = ctx->iface->init(ctx, NULL);
57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    if (res) {
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian      vpx_codec_destroy(ctx);
60f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
61ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
62f71323e297a928af368937089d3ed71239786f86Andreas Huber
63ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return SAVE_STATUS(ctx, res);
64f71323e297a928af368937089d3ed71239786f86Andreas Huber}
65f71323e297a928af368937089d3ed71239786f86Andreas Huber
66f71323e297a928af368937089d3ed71239786f86Andreas Huber
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t       *iface,
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           const uint8_t         *data,
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           unsigned int           data_sz,
70ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                           vpx_codec_stream_info_t *si) {
71ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_err_t res;
72ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
73ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!iface || !data || !data_sz || !si
74ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      || si->sz < sizeof(vpx_codec_stream_info_t))
75ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INVALID_PARAM;
76ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
77ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Set default/unknown values */
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    si->w = 0;
79ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    si->h = 0;
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
81ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = iface->dec.peek_si(data, data_sz, si);
82ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
83ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
84ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return res;
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t         *ctx,
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                          vpx_codec_stream_info_t *si) {
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_err_t res;
91ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
92ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
93ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INVALID_PARAM;
94ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (!ctx->iface || !ctx->priv)
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_ERROR;
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
97ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Set default/unknown values */
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    si->w = 0;
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    si->h = 0;
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
101da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    res = ctx->iface->dec.get_si(get_alg_priv(ctx), si);
102ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
103ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
104ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return SAVE_STATUS(ctx, res);
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t    *ctx,
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                 const uint8_t        *data,
11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                 unsigned int    data_sz,
11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                                 void       *user_priv,
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 long        deadline) {
113ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_err_t res;
114ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
115ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Sanity checks */
116ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* NULL data ptr allowed if data_sz is 0 too */
117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (!ctx || (!data && data_sz) || (data && !data_sz))
118ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INVALID_PARAM;
119ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (!ctx->iface || !ctx->priv)
120ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_ERROR;
121ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
122da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    res = ctx->iface->dec.decode(get_alg_priv(ctx), data, data_sz, user_priv,
123da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                 deadline);
124ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
125ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
126ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return SAVE_STATUS(ctx, res);
12790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t  *ctx,
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                 vpx_codec_iter_t *iter) {
131ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_image_t *img;
13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
133ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!ctx || !iter || !ctx->iface || !ctx->priv)
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    img = NULL;
135ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else
136da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    img = ctx->iface->dec.get_frame(get_alg_priv(ctx), iter);
13790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return img;
13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
14090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t             *ctx,
143ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                                vpx_codec_put_frame_cb_fn_t  cb,
144ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                                void                      *user_priv) {
145ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_err_t res;
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
147ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!ctx || !cb)
148ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INVALID_PARAM;
149ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (!ctx->iface || !ctx->priv
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang           || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_ERROR;
152ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
153ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->priv->dec.put_frame_cb.u.put_frame = cb;
154ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->priv->dec.put_frame_cb.user_priv = user_priv;
155ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_OK;
156ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
158ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return SAVE_STATUS(ctx, res);
15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
16090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
16190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
16290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t             *ctx,
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                                vpx_codec_put_slice_cb_fn_t  cb,
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                                                void                      *user_priv) {
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_codec_err_t res;
166ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
167ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!ctx || !cb)
168ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_INVALID_PARAM;
169ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else if (!ctx->iface || !ctx->priv
1702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian           || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_SLICE))
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_ERROR;
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  else {
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->priv->dec.put_slice_cb.u.put_slice = cb;
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    ctx->priv->dec.put_slice_cb.user_priv = user_priv;
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    res = VPX_CODEC_OK;
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return SAVE_STATUS(ctx, res);
17990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1812ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanianvpx_codec_err_t vpx_codec_set_frame_buffer_functions(
1822ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get,
1832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
1842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  vpx_codec_err_t res;
1852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  if (!ctx || !cb_get || !cb_release) {
1872ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    res = VPX_CODEC_INVALID_PARAM;
1882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  } else if (!ctx->iface || !ctx->priv ||
1892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian             !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) {
1902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    res = VPX_CODEC_ERROR;
1912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  } else {
192da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    res = ctx->iface->dec.set_fb_fn(get_alg_priv(ctx), cb_get, cb_release,
1932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian                                    cb_priv);
1942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  }
1952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian  return SAVE_STATUS(ctx, res);
1972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
198