michael@0: /*
michael@0: * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
michael@0: *
michael@0: * Use of this source code is governed by a BSD-style license
michael@0: * that can be found in the LICENSE file in the root of the source
michael@0: * tree. An additional intellectual property rights grant can be found
michael@0: * in the file PATENTS. All contributing project authors may
michael@0: * be found in the AUTHORS file in the root of the source tree.
michael@0: */
michael@0:
michael@0:
michael@0: /*!\file
michael@0: * \brief Describes the decoder algorithm interface for algorithm
michael@0: * implementations.
michael@0: *
michael@0: * This file defines the private structures and data types that are only
michael@0: * relevant to implementing an algorithm, as opposed to using it.
michael@0: *
michael@0: * To create a decoder algorithm class, an interface structure is put
michael@0: * into the global namespace:
michael@0: *
michael@0: * my_codec.c:
michael@0: * vpx_codec_iface_t my_codec = {
michael@0: * "My Codec v1.0",
michael@0: * VPX_CODEC_ALG_ABI_VERSION,
michael@0: * ...
michael@0: * };
michael@0: *
michael@0: *
michael@0: * An application instantiates a specific decoder instance by using
michael@0: * vpx_codec_init() and a pointer to the algorithm's interface structure:
michael@0: *
michael@0: * my_app.c:
michael@0: * extern vpx_codec_iface_t my_codec;
michael@0: * {
michael@0: * vpx_codec_ctx_t algo;
michael@0: * res = vpx_codec_init(&algo, &my_codec);
michael@0: * }
michael@0: *
michael@0: *
michael@0: * Once initialized, the instance is manged using other functions from
michael@0: * the vpx_codec_* family.
michael@0: */
michael@0: #ifndef VPX_CODEC_INTERNAL_H
michael@0: #define VPX_CODEC_INTERNAL_H
michael@0: #include "../vpx_decoder.h"
michael@0: #include "../vpx_encoder.h"
michael@0: #include
michael@0:
michael@0:
michael@0: /*!\brief Current ABI version number
michael@0: *
michael@0: * \internal
michael@0: * If this file is altered in any way that changes the ABI, this value
michael@0: * must be bumped. Examples include, but are not limited to, changing
michael@0: * types, removing or reassigning enums, adding/removing/rearranging
michael@0: * fields to structures
michael@0: */
michael@0: #define VPX_CODEC_INTERNAL_ABI_VERSION (4) /**<\hideinitializer*/
michael@0:
michael@0: typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t;
michael@0: typedef struct vpx_codec_priv_enc_mr_cfg vpx_codec_priv_enc_mr_cfg_t;
michael@0:
michael@0: /*!\brief init function pointer prototype
michael@0: *
michael@0: * Performs algorithm-specific initialization of the decoder context. This
michael@0: * function is called by the generic vpx_codec_init() wrapper function, so
michael@0: * plugins implementing this interface may trust the input parameters to be
michael@0: * properly initialized.
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \retval #VPX_CODEC_OK
michael@0: * The input stream was recognized and decoder initialized.
michael@0: * \retval #VPX_CODEC_MEM_ERROR
michael@0: * Memory operation failed.
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_init_fn_t)(vpx_codec_ctx_t *ctx,
michael@0: vpx_codec_priv_enc_mr_cfg_t *data);
michael@0:
michael@0: /*!\brief destroy function pointer prototype
michael@0: *
michael@0: * Performs algorithm-specific destruction of the decoder context. This
michael@0: * function is called by the generic vpx_codec_destroy() wrapper function,
michael@0: * so plugins implementing this interface may trust the input parameters
michael@0: * to be properly initialized.
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \retval #VPX_CODEC_OK
michael@0: * The input stream was recognized and decoder initialized.
michael@0: * \retval #VPX_CODEC_MEM_ERROR
michael@0: * Memory operation failed.
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)(vpx_codec_alg_priv_t *ctx);
michael@0:
michael@0: /*!\brief parse stream info function pointer prototype
michael@0: *
michael@0: * Performs high level parsing of the bitstream. This function is called by the
michael@0: * generic vpx_codec_peek_stream_info() wrapper function, so plugins
michael@0: * implementing this interface may trust the input parameters to be properly
michael@0: * initialized.
michael@0: *
michael@0: * \param[in] data Pointer to a block of data to parse
michael@0: * \param[in] data_sz Size of the data buffer
michael@0: * \param[in,out] si Pointer to stream info to update. The size member
michael@0: * \ref MUST be properly initialized, but \ref MAY be
michael@0: * clobbered by the algorithm. This parameter \ref MAY
michael@0: * be NULL.
michael@0: *
michael@0: * \retval #VPX_CODEC_OK
michael@0: * Bitstream is parsable and stream information updated
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_peek_si_fn_t)(const uint8_t *data,
michael@0: unsigned int data_sz,
michael@0: vpx_codec_stream_info_t *si);
michael@0:
michael@0: /*!\brief Return information about the current stream.
michael@0: *
michael@0: * Returns information about the stream that has been parsed during decoding.
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \param[in,out] si Pointer to stream info to update. The size member
michael@0: * \ref MUST be properly initialized, but \ref MAY be
michael@0: * clobbered by the algorithm. This parameter \ref MAY
michael@0: * be NULL.
michael@0: *
michael@0: * \retval #VPX_CODEC_OK
michael@0: * Bitstream is parsable and stream information updated
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_get_si_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: vpx_codec_stream_info_t *si);
michael@0:
michael@0: /*!\brief control function pointer prototype
michael@0: *
michael@0: * This function is used to exchange algorithm specific data with the decoder
michael@0: * instance. This can be used to implement features specific to a particular
michael@0: * algorithm.
michael@0: *
michael@0: * This function is called by the generic vpx_codec_control() wrapper
michael@0: * function, so plugins implementing this interface may trust the input
michael@0: * parameters to be properly initialized. However, this interface does not
michael@0: * provide type safety for the exchanged data or assign meanings to the
michael@0: * control codes. Those details should be specified in the algorithm's
michael@0: * header file. In particular, the ctrl_id parameter is guaranteed to exist
michael@0: * in the algorithm's control mapping table, and the data parameter may be NULL.
michael@0: *
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \param[in] ctrl_id Algorithm specific control identifier
michael@0: * \param[in,out] data Data to exchange with algorithm instance.
michael@0: *
michael@0: * \retval #VPX_CODEC_OK
michael@0: * The internal state data was deserialized.
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_control_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: int ctrl_id,
michael@0: va_list ap);
michael@0:
michael@0: /*!\brief control function pointer mapping
michael@0: *
michael@0: * This structure stores the mapping between control identifiers and
michael@0: * implementing functions. Each algorithm provides a list of these
michael@0: * mappings. This list is searched by the vpx_codec_control() wrapper
michael@0: * function to determine which function to invoke. The special
michael@0: * value {0, NULL} is used to indicate end-of-list, and must be
michael@0: * present. The special value {0, } can be used as a catch-all
michael@0: * mapping. This implies that ctrl_id values chosen by the algorithm
michael@0: * \ref MUST be non-zero.
michael@0: */
michael@0: typedef const struct vpx_codec_ctrl_fn_map {
michael@0: int ctrl_id;
michael@0: vpx_codec_control_fn_t fn;
michael@0: } vpx_codec_ctrl_fn_map_t;
michael@0:
michael@0: /*!\brief decode data function pointer prototype
michael@0: *
michael@0: * Processes a buffer of coded data. If the processing results in a new
michael@0: * decoded frame becoming available, #VPX_CODEC_CB_PUT_SLICE and
michael@0: * #VPX_CODEC_CB_PUT_FRAME events are generated as appropriate. This
michael@0: * function is called by the generic vpx_codec_decode() wrapper function,
michael@0: * so plugins implementing this interface may trust the input parameters
michael@0: * to be properly initialized.
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \param[in] data Pointer to this block of new coded data. If
michael@0: * NULL, a #VPX_CODEC_CB_PUT_FRAME event is posted
michael@0: * for the previously decoded frame.
michael@0: * \param[in] data_sz Size of the coded data, in bytes.
michael@0: *
michael@0: * \return Returns #VPX_CODEC_OK if the coded data was processed completely
michael@0: * and future pictures can be decoded without error. Otherwise,
michael@0: * see the descriptions of the other error codes in ::vpx_codec_err_t
michael@0: * for recoverability capabilities.
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: const uint8_t *data,
michael@0: unsigned int data_sz,
michael@0: void *user_priv,
michael@0: long deadline);
michael@0:
michael@0: /*!\brief Decoded frames iterator
michael@0: *
michael@0: * Iterates over a list of the frames available for display. The iterator
michael@0: * storage should be initialized to NULL to start the iteration. Iteration is
michael@0: * complete when this function returns NULL.
michael@0: *
michael@0: * The list of available frames becomes valid upon completion of the
michael@0: * vpx_codec_decode call, and remains valid until the next call to vpx_codec_decode.
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \param[in out] iter Iterator storage, initialized to NULL
michael@0: *
michael@0: * \return Returns a pointer to an image, if one is ready for display. Frames
michael@0: * produced will always be in PTS (presentation time stamp) order.
michael@0: */
michael@0: typedef vpx_image_t *(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: vpx_codec_iter_t *iter);
michael@0:
michael@0:
michael@0: /*\brief eXternal Memory Allocation memory map get iterator
michael@0: *
michael@0: * Iterates over a list of the memory maps requested by the decoder. The
michael@0: * iterator storage should be initialized to NULL to start the iteration.
michael@0: * Iteration is complete when this function returns NULL.
michael@0: *
michael@0: * \param[in out] iter Iterator storage, initialized to NULL
michael@0: *
michael@0: * \return Returns a pointer to an memory segment descriptor, or NULL to
michael@0: * indicate end-of-list.
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_get_mmap_fn_t)(const vpx_codec_ctx_t *ctx,
michael@0: vpx_codec_mmap_t *mmap,
michael@0: vpx_codec_iter_t *iter);
michael@0:
michael@0:
michael@0: /*\brief eXternal Memory Allocation memory map set iterator
michael@0: *
michael@0: * Sets a memory descriptor inside the decoder instance.
michael@0: *
michael@0: * \param[in] ctx Pointer to this instance's context
michael@0: * \param[in] mmap Memory map to store.
michael@0: *
michael@0: * \retval #VPX_CODEC_OK
michael@0: * The memory map was accepted and stored.
michael@0: * \retval #VPX_CODEC_MEM_ERROR
michael@0: * The memory map was rejected.
michael@0: */
michael@0: typedef vpx_codec_err_t (*vpx_codec_set_mmap_fn_t)(vpx_codec_ctx_t *ctx,
michael@0: const vpx_codec_mmap_t *mmap);
michael@0:
michael@0:
michael@0: typedef vpx_codec_err_t (*vpx_codec_encode_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: const vpx_image_t *img,
michael@0: vpx_codec_pts_t pts,
michael@0: unsigned long duration,
michael@0: vpx_enc_frame_flags_t flags,
michael@0: unsigned long deadline);
michael@0: typedef const vpx_codec_cx_pkt_t *(*vpx_codec_get_cx_data_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: vpx_codec_iter_t *iter);
michael@0:
michael@0: typedef vpx_codec_err_t
michael@0: (*vpx_codec_enc_config_set_fn_t)(vpx_codec_alg_priv_t *ctx,
michael@0: const vpx_codec_enc_cfg_t *cfg);
michael@0: typedef vpx_fixed_buf_t *
michael@0: (*vpx_codec_get_global_headers_fn_t)(vpx_codec_alg_priv_t *ctx);
michael@0:
michael@0: typedef vpx_image_t *
michael@0: (*vpx_codec_get_preview_frame_fn_t)(vpx_codec_alg_priv_t *ctx);
michael@0:
michael@0: typedef vpx_codec_err_t
michael@0: (*vpx_codec_enc_mr_get_mem_loc_fn_t)(const vpx_codec_enc_cfg_t *cfg,
michael@0: void **mem_loc);
michael@0:
michael@0: /*!\brief usage configuration mapping
michael@0: *
michael@0: * This structure stores the mapping between usage identifiers and
michael@0: * configuration structures. Each algorithm provides a list of these
michael@0: * mappings. This list is searched by the vpx_codec_enc_config_default()
michael@0: * wrapper function to determine which config to return. The special value
michael@0: * {-1, {0}} is used to indicate end-of-list, and must be present. At least
michael@0: * one mapping must be present, in addition to the end-of-list.
michael@0: *
michael@0: */
michael@0: typedef const struct vpx_codec_enc_cfg_map {
michael@0: int usage;
michael@0: vpx_codec_enc_cfg_t cfg;
michael@0: } vpx_codec_enc_cfg_map_t;
michael@0:
michael@0: #define NOT_IMPLEMENTED 0
michael@0:
michael@0: /*!\brief Decoder algorithm interface interface
michael@0: *
michael@0: * All decoders \ref MUST expose a variable of this type.
michael@0: */
michael@0: struct vpx_codec_iface {
michael@0: const char *name; /**< Identification String */
michael@0: int abi_version; /**< Implemented ABI version */
michael@0: vpx_codec_caps_t caps; /**< Decoder capabilities */
michael@0: vpx_codec_init_fn_t init; /**< \copydoc ::vpx_codec_init_fn_t */
michael@0: vpx_codec_destroy_fn_t destroy; /**< \copydoc ::vpx_codec_destroy_fn_t */
michael@0: vpx_codec_ctrl_fn_map_t *ctrl_maps; /**< \copydoc ::vpx_codec_ctrl_fn_map_t */
michael@0: vpx_codec_get_mmap_fn_t get_mmap; /**< \copydoc ::vpx_codec_get_mmap_fn_t */
michael@0: vpx_codec_set_mmap_fn_t set_mmap; /**< \copydoc ::vpx_codec_set_mmap_fn_t */
michael@0: struct vpx_codec_dec_iface {
michael@0: vpx_codec_peek_si_fn_t peek_si; /**< \copydoc ::vpx_codec_peek_si_fn_t */
michael@0: vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_get_si_fn_t */
michael@0: vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */
michael@0: vpx_codec_get_frame_fn_t get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */
michael@0: } dec;
michael@0: struct vpx_codec_enc_iface {
michael@0: vpx_codec_enc_cfg_map_t *cfg_maps; /**< \copydoc ::vpx_codec_enc_cfg_map_t */
michael@0: vpx_codec_encode_fn_t encode; /**< \copydoc ::vpx_codec_encode_fn_t */
michael@0: vpx_codec_get_cx_data_fn_t get_cx_data; /**< \copydoc ::vpx_codec_get_cx_data_fn_t */
michael@0: vpx_codec_enc_config_set_fn_t cfg_set; /**< \copydoc ::vpx_codec_enc_config_set_fn_t */
michael@0: vpx_codec_get_global_headers_fn_t get_glob_hdrs; /**< \copydoc ::vpx_codec_get_global_headers_fn_t */
michael@0: vpx_codec_get_preview_frame_fn_t get_preview; /**< \copydoc ::vpx_codec_get_preview_frame_fn_t */
michael@0: vpx_codec_enc_mr_get_mem_loc_fn_t mr_get_mem_loc; /**< \copydoc ::vpx_codec_enc_mr_get_mem_loc_fn_t */
michael@0: } enc;
michael@0: };
michael@0:
michael@0: /*!\brief Callback function pointer / user data pair storage */
michael@0: typedef struct vpx_codec_priv_cb_pair {
michael@0: union {
michael@0: vpx_codec_put_frame_cb_fn_t put_frame;
michael@0: vpx_codec_put_slice_cb_fn_t put_slice;
michael@0: } u;
michael@0: void *user_priv;
michael@0: } vpx_codec_priv_cb_pair_t;
michael@0:
michael@0:
michael@0: /*!\brief Instance private storage
michael@0: *
michael@0: * This structure is allocated by the algorithm's init function. It can be
michael@0: * extended in one of two ways. First, a second, algorithm specific structure
michael@0: * can be allocated and the priv member pointed to it. Alternatively, this
michael@0: * structure can be made the first member of the algorithm specific structure,
michael@0: * and the pointer cast to the proper type.
michael@0: */
michael@0: struct vpx_codec_priv {
michael@0: unsigned int sz;
michael@0: vpx_codec_iface_t *iface;
michael@0: struct vpx_codec_alg_priv *alg_priv;
michael@0: const char *err_detail;
michael@0: vpx_codec_flags_t init_flags;
michael@0: struct {
michael@0: vpx_codec_priv_cb_pair_t put_frame_cb;
michael@0: vpx_codec_priv_cb_pair_t put_slice_cb;
michael@0: } dec;
michael@0: struct {
michael@0: int tbd;
michael@0: struct vpx_fixed_buf cx_data_dst_buf;
michael@0: unsigned int cx_data_pad_before;
michael@0: unsigned int cx_data_pad_after;
michael@0: vpx_codec_cx_pkt_t cx_data_pkt;
michael@0: unsigned int total_encoders;
michael@0: } enc;
michael@0: };
michael@0:
michael@0: /*
michael@0: * Multi-resolution encoding internal configuration
michael@0: */
michael@0: struct vpx_codec_priv_enc_mr_cfg
michael@0: {
michael@0: unsigned int mr_total_resolutions;
michael@0: unsigned int mr_encoder_id;
michael@0: struct vpx_rational mr_down_sampling_factor;
michael@0: void* mr_low_res_mode_info;
michael@0: };
michael@0:
michael@0: #undef VPX_CTRL_USE_TYPE
michael@0: #define VPX_CTRL_USE_TYPE(id, typ) \
michael@0: static typ id##__value(va_list args) {return va_arg(args, typ);} \
michael@0: static typ id##__convert(void *x)\
michael@0: {\
michael@0: union\
michael@0: {\
michael@0: void *x;\
michael@0: typ d;\
michael@0: } u;\
michael@0: u.x = x;\
michael@0: return u.d;\
michael@0: }
michael@0:
michael@0:
michael@0: #undef VPX_CTRL_USE_TYPE_DEPRECATED
michael@0: #define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \
michael@0: static typ id##__value(va_list args) {return va_arg(args, typ);} \
michael@0: static typ id##__convert(void *x)\
michael@0: {\
michael@0: union\
michael@0: {\
michael@0: void *x;\
michael@0: typ d;\
michael@0: } u;\
michael@0: u.x = x;\
michael@0: return u.d;\
michael@0: }
michael@0:
michael@0: #define CAST(id, arg) id##__value(arg)
michael@0: #define RECAST(id, x) id##__convert(x)
michael@0:
michael@0:
michael@0: /* CODEC_INTERFACE convenience macro
michael@0: *
michael@0: * By convention, each codec interface is a struct with extern linkage, where
michael@0: * the symbol is suffixed with _algo. A getter function is also defined to
michael@0: * return a pointer to the struct, since in some cases it's easier to work
michael@0: * with text symbols than data symbols (see issue #169). This function has
michael@0: * the same name as the struct, less the _algo suffix. The CODEC_INTERFACE
michael@0: * macro is provided to define this getter function automatically.
michael@0: */
michael@0: #define CODEC_INTERFACE(id)\
michael@0: vpx_codec_iface_t* id(void) { return &id##_algo; }\
michael@0: vpx_codec_iface_t id##_algo
michael@0:
michael@0:
michael@0: /* Internal Utility Functions
michael@0: *
michael@0: * The following functions are intended to be used inside algorithms as
michael@0: * utilities for manipulating vpx_codec_* data structures.
michael@0: */
michael@0: struct vpx_codec_pkt_list {
michael@0: unsigned int cnt;
michael@0: unsigned int max;
michael@0: struct vpx_codec_cx_pkt pkts[1];
michael@0: };
michael@0:
michael@0: #define vpx_codec_pkt_list_decl(n)\
michael@0: union {struct vpx_codec_pkt_list head;\
michael@0: struct {struct vpx_codec_pkt_list head;\
michael@0: struct vpx_codec_cx_pkt pkts[n];} alloc;}
michael@0:
michael@0: #define vpx_codec_pkt_list_init(m)\
michael@0: (m)->alloc.head.cnt = 0,\
michael@0: (m)->alloc.head.max = sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0])
michael@0:
michael@0: int
michael@0: vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *,
michael@0: const struct vpx_codec_cx_pkt *);
michael@0:
michael@0: const vpx_codec_cx_pkt_t *
michael@0: vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
michael@0: vpx_codec_iter_t *iter);
michael@0:
michael@0:
michael@0: #include
michael@0: #include
michael@0: struct vpx_internal_error_info {
michael@0: vpx_codec_err_t error_code;
michael@0: int has_detail;
michael@0: char detail[80];
michael@0: int setjmp;
michael@0: jmp_buf jmp;
michael@0: };
michael@0:
michael@0: static void vpx_internal_error(struct vpx_internal_error_info *info,
michael@0: vpx_codec_err_t error,
michael@0: const char *fmt,
michael@0: ...) {
michael@0: va_list ap;
michael@0:
michael@0: info->error_code = error;
michael@0: info->has_detail = 0;
michael@0:
michael@0: if (fmt) {
michael@0: size_t sz = sizeof(info->detail);
michael@0:
michael@0: info->has_detail = 1;
michael@0: va_start(ap, fmt);
michael@0: vsnprintf(info->detail, sz - 1, fmt, ap);
michael@0: va_end(ap);
michael@0: info->detail[sz - 1] = '\0';
michael@0: }
michael@0:
michael@0: if (info->setjmp)
michael@0: longjmp(info->jmp, info->error_code);
michael@0: }
michael@0:
michael@0: //------------------------------------------------------------------------------
michael@0: // mmap interface
michael@0:
michael@0: typedef struct {
michael@0: unsigned int id;
michael@0: unsigned long sz;
michael@0: unsigned int align;
michael@0: unsigned int flags;
michael@0: unsigned long (*calc_sz)(const vpx_codec_dec_cfg_t *, vpx_codec_flags_t);
michael@0: } mem_req_t;
michael@0:
michael@0: // Allocates mmap.priv and sets mmap.base based on mmap.sz/align/flags
michael@0: // requirements.
michael@0: // Returns #VPX_CODEC_OK on success, #VPX_CODEC_MEM_ERROR otherwise.
michael@0: vpx_codec_err_t vpx_mmap_alloc(vpx_codec_mmap_t *mmap);
michael@0:
michael@0: // Frees mmap.base allocated by a call to vpx_mmap_alloc().
michael@0: void vpx_mmap_dtor(vpx_codec_mmap_t *mmap);
michael@0:
michael@0: // Checks each mmap has the size requirement specificied by mem_reqs.
michael@0: // Returns #VPX_CODEC_OK on success, #VPX_CODEC_MEM_ERROR otherwise.
michael@0: vpx_codec_err_t vpx_validate_mmaps(const vpx_codec_stream_info_t *si,
michael@0: const vpx_codec_mmap_t *mmaps,
michael@0: const mem_req_t *mem_reqs, int nreqs,
michael@0: vpx_codec_flags_t init_flags);
michael@0: #endif