Home | History | Annotate | Download | only in internal
      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 decoder_impl.h
     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 e_xternal 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 e_xternal 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     };
    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 casted 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 /* Internal Utility Functions
    393  *
    394  * The following functions are indended to be used inside algorithms as
    395  * utilities for manipulating vpx_codec_* data structures.
    396  */
    397 struct vpx_codec_pkt_list
    398 {
    399     unsigned int            cnt;
    400     unsigned int            max;
    401     struct vpx_codec_cx_pkt pkts[1];
    402 };
    403 
    404 #define vpx_codec_pkt_list_decl(n)\
    405     union {struct vpx_codec_pkt_list head;\
    406         struct {struct vpx_codec_pkt_list head;\
    407             struct vpx_codec_cx_pkt    pkts[n];} alloc;}
    408 
    409 #define vpx_codec_pkt_list_init(m)\
    410     (m)->alloc.head.cnt = 0,\
    411                           (m)->alloc.head.max = sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0])
    412 
    413 int
    414 vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *,
    415                        const struct vpx_codec_cx_pkt *);
    416 
    417 const vpx_codec_cx_pkt_t*
    418 vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list,
    419                        vpx_codec_iter_t           *iter);
    420 
    421 
    422 #include <stdio.h>
    423 #include <setjmp.h>
    424 struct vpx_internal_error_info
    425 {
    426     vpx_codec_err_t  error_code;
    427     int              has_detail;
    428     char             detail[80];
    429     int              setjmp;
    430     jmp_buf          jmp;
    431 };
    432 
    433 static void vpx_internal_error(struct vpx_internal_error_info *info,
    434                                vpx_codec_err_t                 error,
    435                                const char                     *fmt,
    436                                ...)
    437 {
    438     va_list ap;
    439 
    440     info->error_code = error;
    441     info->has_detail = 0;
    442 
    443     if (fmt)
    444     {
    445         size_t  sz = sizeof(info->detail);
    446 
    447         info->has_detail = 1;
    448         va_start(ap, fmt);
    449         vsnprintf(info->detail, sz - 1, fmt, ap);
    450         va_end(ap);
    451         info->detail[sz-1] = '\0';
    452     }
    453 
    454     if (info->setjmp)
    455         longjmp(info->jmp, info->error_code);
    456 }
    457 #endif
    458