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
13 : * \brief Describes the decoder algorithm interface for algorithm
14 : * implementations.
15 : *
16 : * This file defines the private structures and data types that are only
17 : * relevant to implementing an algorithm, as opposed to using it.
18 : *
19 : * To create a decoder algorithm class, an interface structure is put
20 : * into the global namespace:
21 : * <pre>
22 : * my_codec.c:
23 : * vpx_codec_iface_t my_codec = {
24 : * "My Codec v1.0",
25 : * VPX_CODEC_ALG_ABI_VERSION,
26 : * ...
27 : * };
28 : * </pre>
29 : *
30 : * An application instantiates a specific decoder instance by using
31 : * vpx_codec_init() and a pointer to the algorithm's interface structure:
32 : * <pre>
33 : * my_app.c:
34 : * extern vpx_codec_iface_t my_codec;
35 : * {
36 : * vpx_codec_ctx_t algo;
37 : * res = vpx_codec_init(&algo, &my_codec);
38 : * }
39 : * </pre>
40 : *
41 : * Once initialized, the instance is manged using other functions from
42 : * the vpx_codec_* family.
43 : */
44 : #ifndef VPX_CODEC_INTERNAL_H
45 : #define VPX_CODEC_INTERNAL_H
46 : #include "../vpx_decoder.h"
47 : #include "../vpx_encoder.h"
48 : #include <stdarg.h>
49 :
50 :
51 : /*!\brief Current ABI version number
52 : *
53 : * \internal
54 : * If this file is altered in any way that changes the ABI, this value
55 : * must be bumped. Examples include, but are not limited to, changing
56 : * types, removing or reassigning enums, adding/removing/rearranging
57 : * fields to structures
58 : */
59 : #define VPX_CODEC_INTERNAL_ABI_VERSION (3) /**<\hideinitializer*/
60 :
61 : typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t;
62 :
63 : /*!\brief init function pointer prototype
64 : *
65 : * Performs algorithm-specific initialization of the decoder context. This
66 : * function is called by the generic vpx_codec_init() wrapper function, so
67 : * plugins implementing this interface may trust the input parameters to be
68 : * properly initialized.
69 : *
70 : * \param[in] ctx Pointer to this instance's context
71 : * \retval #VPX_CODEC_OK
72 : * The input stream was recognized and decoder initialized.
73 : * \retval #VPX_CODEC_MEM_ERROR
74 : * Memory operation failed.
75 : */
76 : typedef vpx_codec_err_t (*vpx_codec_init_fn_t)(vpx_codec_ctx_t *ctx);
77 :
78 : /*!\brief destroy function pointer prototype
79 : *
80 : * Performs algorithm-specific destruction of the decoder context. This
81 : * function is called by the generic vpx_codec_destroy() wrapper function,
82 : * so plugins implementing this interface may trust the input parameters
83 : * to be properly initialized.
84 : *
85 : * \param[in] ctx Pointer to this instance's context
86 : * \retval #VPX_CODEC_OK
87 : * The input stream was recognized and decoder initialized.
88 : * \retval #VPX_CODEC_MEM_ERROR
89 : * Memory operation failed.
90 : */
91 : typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)(vpx_codec_alg_priv_t *ctx);
92 :
93 : /*!\brief parse stream info function pointer prototype
94 : *
95 : * Performs high level parsing of the bitstream. This function is called by
96 : * the generic vpx_codec_parse_stream() wrapper function, so plugins implementing
97 : * this interface may trust the input parameters to be properly initialized.
98 : *
99 : * \param[in] data Pointer to a block of data to parse
100 : * \param[in] data_sz Size of the data buffer
101 : * \param[in,out] si Pointer to stream info to update. The size member
102 : * \ref MUST be properly initialized, but \ref MAY be
103 : * clobbered by the algorithm. This parameter \ref MAY
104 : * be NULL.
105 : *
106 : * \retval #VPX_CODEC_OK
107 : * Bitstream is parsable and stream information updated
108 : */
109 : typedef vpx_codec_err_t (*vpx_codec_peek_si_fn_t)(const uint8_t *data,
110 : unsigned int data_sz,
111 : vpx_codec_stream_info_t *si);
112 :
113 : /*!\brief Return information about the current stream.
114 : *
115 : * Returns information about the stream that has been parsed during decoding.
116 : *
117 : * \param[in] ctx Pointer to this instance's context
118 : * \param[in,out] si Pointer to stream info to update. The size member
119 : * \ref MUST be properly initialized, but \ref MAY be
120 : * clobbered by the algorithm. This parameter \ref MAY
121 : * be NULL.
122 : *
123 : * \retval #VPX_CODEC_OK
124 : * Bitstream is parsable and stream information updated
125 : */
126 : typedef vpx_codec_err_t (*vpx_codec_get_si_fn_t)(vpx_codec_alg_priv_t *ctx,
127 : vpx_codec_stream_info_t *si);
128 :
129 : /*!\brief control function pointer prototype
130 : *
131 : * This function is used to exchange algorithm specific data with the decoder
132 : * instance. This can be used to implement features specific to a particular
133 : * algorithm.
134 : *
135 : * This function is called by the generic vpx_codec_control() wrapper
136 : * function, so plugins implementing this interface may trust the input
137 : * parameters to be properly initialized. However, this interface does not
138 : * provide type safety for the exchanged data or assign meanings to the
139 : * control codes. Those details should be specified in the algorithm's
140 : * header file. In particular, the ctrl_id parameter is guaranteed to exist
141 : * in the algorithm's control mapping table, and the data parameter may be NULL.
142 : *
143 : *
144 : * \param[in] ctx Pointer to this instance's context
145 : * \param[in] ctrl_id Algorithm specific control identifier
146 : * \param[in,out] data Data to exchange with algorithm instance.
147 : *
148 : * \retval #VPX_CODEC_OK
149 : * The internal state data was deserialized.
150 : */
151 : typedef vpx_codec_err_t (*vpx_codec_control_fn_t)(vpx_codec_alg_priv_t *ctx,
152 : int ctrl_id,
153 : va_list ap);
154 :
155 : /*!\brief control function pointer mapping
156 : *
157 : * This structure stores the mapping between control identifiers and
158 : * implementing functions. Each algorithm provides a list of these
159 : * mappings. This list is searched by the vpx_codec_control() wrapper
160 : * function to determine which function to invoke. The special
161 : * value {0, NULL} is used to indicate end-of-list, and must be
162 : * present. The special value {0, <non-null>} can be used as a catch-all
163 : * mapping. This implies that ctrl_id values chosen by the algorithm
164 : * \ref MUST be non-zero.
165 : */
166 : typedef const struct
167 : {
168 : int ctrl_id;
169 : vpx_codec_control_fn_t fn;
170 : } vpx_codec_ctrl_fn_map_t;
171 :
172 : /*!\brief decode data function pointer prototype
173 : *
174 : * Processes a buffer of coded data. If the processing results in a new
175 : * decoded frame becoming available, #VPX_CODEC_CB_PUT_SLICE and
176 : * #VPX_CODEC_CB_PUT_FRAME events are generated as appropriate. This
177 : * function is called by the generic vpx_codec_decode() wrapper function,
178 : * so plugins implementing this interface may trust the input parameters
179 : * to be properly initialized.
180 : *
181 : * \param[in] ctx Pointer to this instance's context
182 : * \param[in] data Pointer to this block of new coded data. If
183 : * NULL, a #VPX_CODEC_CB_PUT_FRAME event is posted
184 : * for the previously decoded frame.
185 : * \param[in] data_sz Size of the coded data, in bytes.
186 : *
187 : * \return Returns #VPX_CODEC_OK if the coded data was processed completely
188 : * and future pictures can be decoded without error. Otherwise,
189 : * see the descriptions of the other error codes in ::vpx_codec_err_t
190 : * for recoverability capabilities.
191 : */
192 : typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t *ctx,
193 : const uint8_t *data,
194 : unsigned int data_sz,
195 : void *user_priv,
196 : long deadline);
197 :
198 : /*!\brief Decoded frames iterator
199 : *
200 : * Iterates over a list of the frames available for display. The iterator
201 : * storage should be initialized to NULL to start the iteration. Iteration is
202 : * complete when this function returns NULL.
203 : *
204 : * The list of available frames becomes valid upon completion of the
205 : * vpx_codec_decode call, and remains valid until the next call to vpx_codec_decode.
206 : *
207 : * \param[in] ctx Pointer to this instance's context
208 : * \param[in out] iter Iterator storage, initialized to NULL
209 : *
210 : * \return Returns a pointer to an image, if one is ready for display. Frames
211 : * produced will always be in PTS (presentation time stamp) order.
212 : */
213 : typedef vpx_image_t*(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx,
214 : vpx_codec_iter_t *iter);
215 :
216 :
217 : /*\brief eXternal Memory Allocation memory map get iterator
218 : *
219 : * Iterates over a list of the memory maps requested by the decoder. The
220 : * iterator storage should be initialized to NULL to start the iteration.
221 : * Iteration is complete when this function returns NULL.
222 : *
223 : * \param[in out] iter Iterator storage, initialized to NULL
224 : *
225 : * \return Returns a pointer to an memory segment descriptor, or NULL to
226 : * indicate end-of-list.
227 : */
228 : typedef vpx_codec_err_t (*vpx_codec_get_mmap_fn_t)(const vpx_codec_ctx_t *ctx,
229 : vpx_codec_mmap_t *mmap,
230 : vpx_codec_iter_t *iter);
231 :
232 :
233 : /*\brief eXternal Memory Allocation memory map set iterator
234 : *
235 : * Sets a memory descriptor inside the decoder instance.
236 : *
237 : * \param[in] ctx Pointer to this instance's context
238 : * \param[in] mmap Memory map to store.
239 : *
240 : * \retval #VPX_CODEC_OK
241 : * The memory map was accepted and stored.
242 : * \retval #VPX_CODEC_MEM_ERROR
243 : * The memory map was rejected.
244 : */
245 : typedef vpx_codec_err_t (*vpx_codec_set_mmap_fn_t)(vpx_codec_ctx_t *ctx,
246 : const vpx_codec_mmap_t *mmap);
247 :
248 :
249 : typedef vpx_codec_err_t (*vpx_codec_encode_fn_t)(vpx_codec_alg_priv_t *ctx,
250 : const vpx_image_t *img,
251 : vpx_codec_pts_t pts,
252 : unsigned long duration,
253 : vpx_enc_frame_flags_t flags,
254 : unsigned long deadline);
255 : typedef const vpx_codec_cx_pkt_t*(*vpx_codec_get_cx_data_fn_t)(vpx_codec_alg_priv_t *ctx,
256 : vpx_codec_iter_t *iter);
257 :
258 : typedef vpx_codec_err_t
259 : (*vpx_codec_enc_config_set_fn_t)(vpx_codec_alg_priv_t *ctx,
260 : const vpx_codec_enc_cfg_t *cfg);
261 : typedef vpx_fixed_buf_t *
262 : (*vpx_codec_get_global_headers_fn_t)(vpx_codec_alg_priv_t *ctx);
263 :
264 : typedef vpx_image_t *
265 : (*vpx_codec_get_preview_frame_fn_t)(vpx_codec_alg_priv_t *ctx);
266 :
267 : /*!\brief usage configuration mapping
268 : *
269 : * This structure stores the mapping between usage identifiers and
270 : * configuration structures. Each algorithm provides a list of these
271 : * mappings. This list is searched by the vpx_codec_enc_config_default()
272 : * wrapper function to determine which config to return. The special value
273 : * {-1, {0}} is used to indicate end-of-list, and must be present. At least
274 : * one mapping must be present, in addition to the end-of-list.
275 : *
276 : */
277 : typedef const struct
278 : {
279 : int usage;
280 : vpx_codec_enc_cfg_t cfg;
281 : } vpx_codec_enc_cfg_map_t;
282 :
283 : #define NOT_IMPLEMENTED 0
284 :
285 : /*!\brief Decoder algorithm interface interface
286 : *
287 : * All decoders \ref MUST expose a variable of this type.
288 : */
289 : struct vpx_codec_iface
290 : {
291 : const char *name; /**< Identification String */
292 : int abi_version; /**< Implemented ABI version */
293 : vpx_codec_caps_t caps; /**< Decoder capabilities */
294 : vpx_codec_init_fn_t init; /**< \copydoc ::vpx_codec_init_fn_t */
295 : vpx_codec_destroy_fn_t destroy; /**< \copydoc ::vpx_codec_destroy_fn_t */
296 : vpx_codec_ctrl_fn_map_t *ctrl_maps; /**< \copydoc ::vpx_codec_ctrl_fn_map_t */
297 : vpx_codec_get_mmap_fn_t get_mmap; /**< \copydoc ::vpx_codec_get_mmap_fn_t */
298 : vpx_codec_set_mmap_fn_t set_mmap; /**< \copydoc ::vpx_codec_set_mmap_fn_t */
299 : struct
300 : {
301 : vpx_codec_peek_si_fn_t peek_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */
302 : vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */
303 : vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */
304 : vpx_codec_get_frame_fn_t get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */
305 : } dec;
306 : struct
307 : {
308 : vpx_codec_enc_cfg_map_t *cfg_maps; /**< \copydoc ::vpx_codec_enc_cfg_map_t */
309 : vpx_codec_encode_fn_t encode; /**< \copydoc ::vpx_codec_encode_fn_t */
310 : vpx_codec_get_cx_data_fn_t get_cx_data; /**< \copydoc ::vpx_codec_get_cx_data_fn_t */
311 : vpx_codec_enc_config_set_fn_t cfg_set; /**< \copydoc ::vpx_codec_enc_config_set_fn_t */
312 : vpx_codec_get_global_headers_fn_t get_glob_hdrs; /**< \copydoc ::vpx_codec_enc_config_set_fn_t */
313 : vpx_codec_get_preview_frame_fn_t get_preview; /**< \copydoc ::vpx_codec_get_preview_frame_fn_t */
314 : } enc;
315 : };
316 :
317 : /*!\brief Callback function pointer / user data pair storage */
318 : typedef struct vpx_codec_priv_cb_pair
319 : {
320 : union
321 : {
322 : vpx_codec_put_frame_cb_fn_t put_frame;
323 : vpx_codec_put_slice_cb_fn_t put_slice;
324 : } u;
325 : void *user_priv;
326 : } vpx_codec_priv_cb_pair_t;
327 :
328 :
329 : /*!\brief Instance private storage
330 : *
331 : * This structure is allocated by the algorithm's init function. It can be
332 : * extended in one of two ways. First, a second, algorithm specific structure
333 : * can be allocated and the priv member pointed to it. Alternatively, this
334 : * structure can be made the first member of the algorithm specific structure,
335 : * and the pointer cast to the proper type.
336 : */
337 : struct vpx_codec_priv
338 : {
339 : unsigned int sz;
340 : vpx_codec_iface_t *iface;
341 : struct vpx_codec_alg_priv *alg_priv;
342 : const char *err_detail;
343 : vpx_codec_flags_t init_flags;
344 : struct
345 : {
346 : vpx_codec_priv_cb_pair_t put_frame_cb;
347 : vpx_codec_priv_cb_pair_t put_slice_cb;
348 : } dec;
349 : struct
350 : {
351 : int tbd;
352 : struct vpx_fixed_buf cx_data_dst_buf;
353 : unsigned int cx_data_pad_before;
354 : unsigned int cx_data_pad_after;
355 : vpx_codec_cx_pkt_t cx_data_pkt;
356 : } enc;
357 : };
358 :
359 : #undef VPX_CTRL_USE_TYPE
360 : #define VPX_CTRL_USE_TYPE(id, typ) \
361 : static typ id##__value(va_list args) {return va_arg(args, typ);} \
362 : static typ id##__convert(void *x)\
363 : {\
364 : union\
365 : {\
366 : void *x;\
367 : typ d;\
368 : } u;\
369 : u.x = x;\
370 : return u.d;\
371 : }
372 :
373 :
374 : #undef VPX_CTRL_USE_TYPE_DEPRECATED
375 : #define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \
376 : static typ id##__value(va_list args) {return va_arg(args, typ);} \
377 : static typ id##__convert(void *x)\
378 : {\
379 : union\
380 : {\
381 : void *x;\
382 : typ d;\
383 : } u;\
384 : u.x = x;\
385 : return u.d;\
386 : }
387 :
388 : #define CAST(id, arg) id##__value(arg)
389 : #define RECAST(id, x) id##__convert(x)
390 :
391 :
392 : /* CODEC_INTERFACE convenience macro
393 : *
394 : * By convention, each codec interface is a struct with extern linkage, where
395 : * the symbol is suffixed with _algo. A getter function is also defined to
396 : * return a pointer to the struct, since in some cases it's easier to work
397 : * with text symbols than data symbols (see issue #169). This function has
398 : * the same name as the struct, less the _algo suffix. The CODEC_INTERFACE
399 : * macro is provided to define this getter function automatically.
400 : */
401 : #define CODEC_INTERFACE(id)\
402 : vpx_codec_iface_t* id(void) { return &id##_algo; }\
403 : vpx_codec_iface_t id##_algo
404 :
405 :
406 : /* Internal Utility Functions
407 : *
408 : * The following functions are intended to be used inside algorithms as
409 : * utilities for manipulating vpx_codec_* data structures.
410 : */
411 : struct vpx_codec_pkt_list
412 : {
413 : unsigned int cnt;
414 : unsigned int max;
415 : struct vpx_codec_cx_pkt pkts[1];
416 : };
417 :
418 : #define vpx_codec_pkt_list_decl(n)\
419 : union {struct vpx_codec_pkt_list head;\
420 : struct {struct vpx_codec_pkt_list head;\
421 : struct vpx_codec_cx_pkt pkts[n];} alloc;}
422 :
423 : #define vpx_codec_pkt_list_init(m)\
424 : (m)->alloc.head.cnt = 0,\
425 : (m)->alloc.head.max = sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0])
426 :
427 : int
428 : vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *,
429 : const struct vpx_codec_cx_pkt *);
430 :
431 : const vpx_codec_cx_pkt_t*
432 : vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
433 : vpx_codec_iter_t *iter);
434 :
435 :
436 : #include <stdio.h>
437 : #include <setjmp.h>
438 : struct vpx_internal_error_info
439 : {
440 : vpx_codec_err_t error_code;
441 : int has_detail;
442 : char detail[80];
443 : int setjmp;
444 : jmp_buf jmp;
445 : };
446 :
447 0 : static void vpx_internal_error(struct vpx_internal_error_info *info,
448 : vpx_codec_err_t error,
449 : const char *fmt,
450 : ...)
451 : {
452 : va_list ap;
453 :
454 0 : info->error_code = error;
455 0 : info->has_detail = 0;
456 :
457 0 : if (fmt)
458 : {
459 0 : size_t sz = sizeof(info->detail);
460 :
461 0 : info->has_detail = 1;
462 0 : va_start(ap, fmt);
463 0 : vsnprintf(info->detail, sz - 1, fmt, ap);
464 0 : va_end(ap);
465 0 : info->detail[sz-1] = '\0';
466 : }
467 :
468 0 : if (info->setjmp)
469 0 : longjmp(info->jmp, info->error_code);
470 0 : }
471 : #endif
|