Merge "examples: use I420 input for encoders"
[profile/ivi/libvpx.git] / vpx / src / vpx_codec.c
1 /*
2  *  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license and patent
5  *  grant that can be found in the LICENSE file in the root of the source
6  *  tree. All contributing project authors may be found in the AUTHORS
7  *  file in the root of the source tree.
8  */
9
10
11 /*!\file vpx_decoder.c
12  * \brief Provides the high level interface to wrap decoder algorithms.
13  *
14  */
15 #include <stdlib.h>
16 #include <string.h>
17 #include "vpx/vpx_integer.h"
18 #include "vpx/internal/vpx_codec_internal.h"
19 #include "vpx_version.h"
20
21 #define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)
22
23 int vpx_codec_version(void)
24 {
25     return VERSION_PACKED;
26 }
27
28
29 const char *vpx_codec_version_str(void)
30 {
31     return VERSION_STRING_NOSP;
32 }
33
34
35 const char *vpx_codec_version_extra_str(void)
36 {
37     return VERSION_EXTRA;
38 }
39
40
41 const char *vpx_codec_iface_name(vpx_codec_iface_t *iface)
42 {
43     return iface ? iface->name : "<invalid interface>";
44 }
45
46 const char *vpx_codec_err_to_string(vpx_codec_err_t  err)
47 {
48     switch (err)
49     {
50     case VPX_CODEC_OK:
51         return "Success";
52     case VPX_CODEC_ERROR:
53         return "Unspecified internal error";
54     case VPX_CODEC_MEM_ERROR:
55         return "Memory allocation error";
56     case VPX_CODEC_ABI_MISMATCH:
57         return "ABI version mismatch";
58     case VPX_CODEC_INCAPABLE:
59         return "Codec does not implement requested capability";
60     case VPX_CODEC_UNSUP_BITSTREAM:
61         return "Bitstream not supported by this decoder";
62     case VPX_CODEC_UNSUP_FEATURE:
63         return "Bitstream required feature not supported by this decoder";
64     case VPX_CODEC_CORRUPT_FRAME:
65         return "Corrupt frame detected";
66     case  VPX_CODEC_INVALID_PARAM:
67         return "Invalid parameter";
68     case VPX_CODEC_LIST_END:
69         return "End of iterated list";
70     }
71
72     return "Unrecognized error code";
73 }
74
75 const char *vpx_codec_error(vpx_codec_ctx_t  *ctx)
76 {
77     return (ctx) ? vpx_codec_err_to_string(ctx->err)
78            : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
79 }
80
81 const char *vpx_codec_error_detail(vpx_codec_ctx_t  *ctx)
82 {
83     if (ctx && ctx->err)
84         return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;
85
86     return NULL;
87 }
88
89
90 vpx_codec_err_t vpx_codec_dec_init_ver(vpx_codec_ctx_t      *ctx,
91                                        vpx_codec_iface_t    *iface,
92                                        vpx_codec_dec_cfg_t  *cfg,
93                                        vpx_codec_flags_t     flags,
94                                        int                   ver)
95 {
96     vpx_codec_err_t res;
97
98     if (ver != VPX_DECODER_ABI_VERSION)
99         res = VPX_CODEC_ABI_MISMATCH;
100     else if (!ctx || !iface)
101         res = VPX_CODEC_INVALID_PARAM;
102     else if (iface->abi_version != VPX_CODEC_INTERNAL_ABI_VERSION)
103         res = VPX_CODEC_ABI_MISMATCH;
104     else if ((flags & VPX_CODEC_USE_XMA) && !(iface->caps & VPX_CODEC_CAP_XMA))
105         res = VPX_CODEC_INCAPABLE;
106     else if ((flags & VPX_CODEC_USE_POSTPROC) && !(iface->caps & VPX_CODEC_CAP_POSTPROC))
107         res = VPX_CODEC_INCAPABLE;
108     else
109     {
110         memset(ctx, 0, sizeof(*ctx));
111         ctx->iface = iface;
112         ctx->name = iface->name;
113         ctx->priv = NULL;
114         ctx->init_flags = flags;
115         ctx->config.dec = cfg;
116         res = VPX_CODEC_OK;
117
118         if (!(flags & VPX_CODEC_USE_XMA))
119         {
120             res = ctx->iface->init(ctx);
121
122             if (res)
123             {
124                 ctx->err_detail = ctx->priv ? ctx->priv->err_detail : NULL;
125                 vpx_codec_destroy(ctx);
126             }
127
128             if (ctx->priv)
129                 ctx->priv->iface = ctx->iface;
130         }
131     }
132
133     return SAVE_STATUS(ctx, res);
134 }
135
136
137 vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
138 {
139     vpx_codec_err_t res;
140
141     if (!ctx)
142         res = VPX_CODEC_INVALID_PARAM;
143     else if (!ctx->iface || !ctx->priv)
144         res = VPX_CODEC_ERROR;
145     else
146     {
147         if (ctx->priv->alg_priv)
148             ctx->iface->destroy(ctx->priv->alg_priv);
149
150         ctx->iface = NULL;
151         ctx->name = NULL;
152         ctx->priv = NULL;
153         res = VPX_CODEC_OK;
154     }
155
156     return SAVE_STATUS(ctx, res);
157 }
158
159
160 vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface)
161 {
162     return (iface) ? iface->caps : 0;
163 }
164
165
166 vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t  *ctx,
167                                    int               ctrl_id,
168                                    ...)
169 {
170     vpx_codec_err_t res;
171
172     if (!ctx || !ctrl_id)
173         res = VPX_CODEC_INVALID_PARAM;
174     else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
175         res = VPX_CODEC_ERROR;
176     else
177     {
178         vpx_codec_ctrl_fn_map_t *entry;
179
180         res = VPX_CODEC_ERROR;
181
182         for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++)
183         {
184             if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
185             {
186                 va_list  ap;
187
188                 va_start(ap, ctrl_id);
189                 res = entry->fn(ctx->priv->alg_priv, ctrl_id, ap);
190                 va_end(ap);
191                 break;
192             }
193         }
194     }
195
196     return SAVE_STATUS(ctx, res);
197 }