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