Merge commit 'fix integer promotion bug in partition size check'
[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     if (!ctx || !data || !data_sz)
122         res = VPX_CODEC_INVALID_PARAM;
123     else if (!ctx->iface || !ctx->priv)
124         res = VPX_CODEC_ERROR;
125     else
126     {
127         res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
128                                      user_priv, deadline);
129     }
130
131     return SAVE_STATUS(ctx, res);
132 }
133
134 vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t  *ctx,
135                                  vpx_codec_iter_t *iter)
136 {
137     vpx_image_t *img;
138
139     if (!ctx || !iter || !ctx->iface || !ctx->priv)
140         img = NULL;
141     else
142         img = ctx->iface->dec.get_frame(ctx->priv->alg_priv, iter);
143
144     return img;
145 }
146
147
148 vpx_codec_err_t vpx_codec_register_put_frame_cb(vpx_codec_ctx_t             *ctx,
149         vpx_codec_put_frame_cb_fn_t  cb,
150         void                      *user_priv)
151 {
152     vpx_codec_err_t res;
153
154     if (!ctx || !cb)
155         res = VPX_CODEC_INVALID_PARAM;
156     else if (!ctx->iface || !ctx->priv
157              || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
158         res = VPX_CODEC_ERROR;
159     else
160     {
161         ctx->priv->dec.put_frame_cb.put_frame = cb;
162         ctx->priv->dec.put_frame_cb.user_priv = user_priv;
163         res = VPX_CODEC_OK;
164     }
165
166     return SAVE_STATUS(ctx, res);
167 }
168
169
170 vpx_codec_err_t vpx_codec_register_put_slice_cb(vpx_codec_ctx_t             *ctx,
171         vpx_codec_put_slice_cb_fn_t  cb,
172         void                      *user_priv)
173 {
174     vpx_codec_err_t res;
175
176     if (!ctx || !cb)
177         res = VPX_CODEC_INVALID_PARAM;
178     else if (!ctx->iface || !ctx->priv
179              || !(ctx->iface->caps & VPX_CODEC_CAP_PUT_FRAME))
180         res = VPX_CODEC_ERROR;
181     else
182     {
183         ctx->priv->dec.put_slice_cb.put_slice = cb;
184         ctx->priv->dec.put_slice_cb.user_priv = user_priv;
185         res = VPX_CODEC_OK;
186     }
187
188     return SAVE_STATUS(ctx, res);
189 }
190
191
192 vpx_codec_err_t vpx_codec_get_mem_map(vpx_codec_ctx_t                *ctx,
193                                       vpx_codec_mmap_t               *mmap,
194                                       vpx_codec_iter_t               *iter)
195 {
196     vpx_codec_err_t res = VPX_CODEC_OK;
197
198     if (!ctx || !mmap || !iter || !ctx->iface)
199         res = VPX_CODEC_INVALID_PARAM;
200     else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
201         res = VPX_CODEC_ERROR;
202     else
203         res = ctx->iface->get_mmap(ctx, mmap, iter);
204
205     return SAVE_STATUS(ctx, res);
206 }
207
208
209 vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t   *ctx,
210                                       vpx_codec_mmap_t  *mmap,
211                                       unsigned int     num_maps)
212 {
213     vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
214
215     if (!ctx || !mmap || !ctx->iface)
216         res = VPX_CODEC_INVALID_PARAM;
217     else if (!(ctx->iface->caps & VPX_CODEC_CAP_XMA))
218         res = VPX_CODEC_ERROR;
219     else
220     {
221         unsigned int i;
222
223         for (i = 0; i < num_maps; i++, mmap++)
224         {
225             if (!mmap->base)
226                 break;
227
228             /* Everything look ok, set the mmap in the decoder */
229             res = ctx->iface->set_mmap(ctx, mmap);
230
231             if (res)
232                 break;
233         }
234     }
235
236     return SAVE_STATUS(ctx, res);
237 }