Merge "move new neon subpixel function"
[profile/ivi/libvpx.git] / vpx / src / vpx_decoder.c
1 /*
2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  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
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10
11
12 /*!\file vpx_decoder.c
13  * \brief Provides the high level interface to wrap decoder algorithms.
14  *
15  */
16 #include <string.h>
17 #include "vpx/internal/vpx_codec_internal.h"
18
19 #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
20
21 vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
22                                        vpx_codec_iface_t    *iface,
23                                        vpx_codec_dec_cfg_t  *cfg,
24                                        vpx_codec_flags_t     flags,
25                                        int                   ver)
26 {
27     vpx_codec_err_t res;
28
29     if (ver != VPX_DECODER_ABI_VERSION)
30         res = VPX_CODEC_ABI_MISMATCH;
31     else if (!ctx || !iface)
32         res = VPX_CODEC_INVALID_PARAM;
33     else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
34         res = VPX_CODEC_ABI_MISMATCH;
35     else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
36         res = VPX_CODEC_INCAPABLE;
37     else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
38         res = VPX_CODEC_INCAPABLE;
39     else
40     {
41         memset(ctx, 0, sizeof(*ctx));
42         ctx->iface = iface;
43         ctx->name = iface->name;
44         ctx->priv = NULL;
45         ctx->init_flags = flags;
46         ctx->config.dec = cfg;
47         res = VPX_CODEC_OK;
48
49         if (!(flags & VPX_CODEC_USE_XMA))
50         {
51             res = ctx->iface->init(ctx);
52
53             if (res)
54             {
55                 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
56                 vpx_codec_destroy(ctx);
57             }
58
59             if (ctx->priv)
60                 ctx->priv->iface = ctx->iface;
61         }
62     }
63
64     return SAVE_STATUS(ctx, res);
65 }
66
67
68 vpx_codec_err_t vpx_codec_peek_stream_info(vpx_codec_iface_t       *iface,
69         const uint8_t         *data,
70         unsigned int           data_sz,
71         vpx_codec_stream_info_t *si)
72 {
73     vpx_codec_err_t res;
74
75     if (!iface || !data || !data_sz || !si
76         || si->sz < sizeof(vpx_codec_stream_info_t))
77         res = VPX_CODEC_INVALID_PARAM;
78     else
79     {
80         /* Set default/unknown values */
81         si->w = 0;
82         si->h = 0;
83
84         res = iface->dec.peek_si(data, data_sz, si);
85     }
86
87     return res;
88 }
89
90
91 vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t         *ctx,
92         vpx_codec_stream_info_t *si)
93 {
94     vpx_codec_err_t res;
95
96     if (!ctx || !si || si->sz < sizeof(vpx_codec_stream_info_t))
97         res = VPX_CODEC_INVALID_PARAM;
98     else if (!ctx->iface || !ctx->priv)
99         res = VPX_CODEC_ERROR;
100     else
101     {
102         /* Set default/unknown values */
103         si->w = 0;
104         si->h = 0;
105
106         res = ctx->iface->dec.get_si(ctx->priv->alg_priv, si);
107     }
108
109     return SAVE_STATUS(ctx, res);
110 }
111
112
113 vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t    *ctx,
114                                  const uint8_t        *data,
115                                  unsigned int    data_sz,
116                                  void       *user_priv,
117                                  long        deadline)
118 {
119     vpx_codec_err_t res;
120
121     /* Sanity checks */
122     /* NULL data ptr allowed if data_sz is 0 too */
123     if (!ctx || (!data && data_sz))
124         res = VPX_CODEC_INVALID_PARAM;
125     else if (!ctx->iface || !ctx->priv)
126         res = VPX_CODEC_ERROR;
127     else
128     {
129         res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
130                                      user_priv, deadline);
131     }
132
133     return SAVE_STATUS(ctx, res);
134 }
135
136 vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t  *ctx,
137                                  vpx_codec_iter_t *iter)
138 {
139     vpx_image_t *img;
140
141     if (!ctx || !iter || !ctx->iface || !ctx->priv)
142         img = NULL;
143     else
144         img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
145
146     return img;
147 }
148
149
150 vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t             *ctx,
151         vpx_codec_put_frame_cb_fn_t  cb,
152         void                      *user_priv)
153 {
154     vpx_codec_err_t res;
155
156     if (!ctx || !cb)
157         res = VPX_CODEC_INVALID_PARAM;
158     else if (!ctx->iface || !ctx->priv
159              || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
160         res = VPX_CODEC_ERROR;
161     else
162     {
163         ctx->priv->dec.put_frame_cb.put_frame = cb;
164         ctx->priv->dec.put_frame_cb.user_priv = user_priv;
165         res = VPX_CODEC_OK;
166     }
167
168     return SAVE_STATUS(ctx, res);
169 }
170
171
172 vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t             *ctx,
173         vpx_codec_put_slice_cb_fn_t  cb,
174         void                      *user_priv)
175 {
176     vpx_codec_err_t res;
177
178     if (!ctx || !cb)
179         res = VPX_CODEC_INVALID_PARAM;
180     else if (!ctx->iface || !ctx->priv
181              || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
182         res = VPX_CODEC_ERROR;
183     else
184     {
185         ctx->priv->dec.put_slice_cb.put_slice = cb;
186         ctx->priv->dec.put_slice_cb.user_priv = user_priv;
187         res = VPX_CODEC_OK;
188     }
189
190     return SAVE_STATUS(ctx, res);
191 }
192
193
194 vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t                *ctx,
195                                       vpx_codec_mmap_t               *mmap,
196                                       vpx_codec_iter_t               *iter)
197 {
198     vpx_codec_err_t res = VPX_CODEC_OK;
199
200     if (!ctx || !mmap || !iter || !ctx->iface)
201         res = VPX_CODEC_INVALID_PARAM;
202     else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
203         res = VPX_CODEC_ERROR;
204     else
205         res = ctx->iface->get_mmap(ctx, mmap, iter);
206
207     return SAVE_STATUS(ctx, res);
208 }
209
210
211 vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t   *ctx,
212                                       vpx_codec_mmap_t  *mmap,
213                                       unsigned int     num_maps)
214 {
215     vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
216
217     if (!ctx || !mmap || !ctx->iface)
218         res = VPX_CODEC_INVALID_PARAM;
219     else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
220         res = VPX_CODEC_ERROR;
221     else
222     {
223         unsigned int i;
224
225         for (i = 0; i < num_maps; i++, mmap++)
226         {
227             if (!mmap->base)
228                 break;
229
230             /* Everything look ok, set the mmap in the decoder */
231             res = ctx->iface->set_mmap(ctx, mmap);
232
233             if (res)
234                 break;
235         }
236     }
237
238     return SAVE_STATUS(ctx, res);
239 }