diff options
author | Frank Galligan <fgalligan@google.com> | 2014-02-06 17:13:08 -0800 |
---|---|---|
committer | Frank Galligan <fgalligan@google.com> | 2014-02-13 13:14:19 -0800 |
commit | a4f30a5023b0216bf3681f87c7f35a8ee09027a4 (patch) | |
tree | cd2edfb5192b99423b263b9e921cbc3e5e358718 /vpx | |
parent | f8604089118a66086c4b2b2b6e09939910c636ea (diff) | |
download | libvpx-a4f30a5023b0216bf3681f87c7f35a8ee09027a4.tar.gz libvpx-a4f30a5023b0216bf3681f87c7f35a8ee09027a4.tar.bz2 libvpx-a4f30a5023b0216bf3681f87c7f35a8ee09027a4.zip |
Add VP9 decoder support for external frame buffers
Added support for external frame buffers to libvpx's VP9 decoder.
If the external frame buffer functions are set then libvpx will
call the get function whenever it needs a new frame buffer to
decode a frame into. And it will call the release function
whenever there are no more references to that buffer.
Change-Id: Id2934d005f606af6e052fb6db0d5b7c02f567522
Diffstat (limited to 'vpx')
-rw-r--r-- | vpx/exports_dec | 1 | ||||
-rw-r--r-- | vpx/internal/vpx_codec_internal.h | 33 | ||||
-rw-r--r-- | vpx/src/vpx_decoder.c | 18 | ||||
-rw-r--r-- | vpx/vpx_decoder.h | 50 | ||||
-rw-r--r-- | vpx/vpx_frame_buffer.h | 10 | ||||
-rw-r--r-- | vpx/vpx_image.h | 4 |
6 files changed, 109 insertions, 7 deletions
diff --git a/vpx/exports_dec b/vpx/exports_dec index ed121f7ec..3ce1499b7 100644 --- a/vpx/exports_dec +++ b/vpx/exports_dec @@ -6,4 +6,5 @@ text vpx_codec_get_stream_info text vpx_codec_peek_stream_info text vpx_codec_register_put_frame_cb text vpx_codec_register_put_slice_cb +text vpx_codec_set_frame_buffer_functions text vpx_codec_set_mem_map diff --git a/vpx/internal/vpx_codec_internal.h b/vpx/internal/vpx_codec_internal.h index 0f42a1d20..51ca65e9f 100644 --- a/vpx/internal/vpx_codec_internal.h +++ b/vpx/internal/vpx_codec_internal.h @@ -59,7 +59,7 @@ extern "C" { * types, removing or reassigning enums, adding/removing/rearranging * fields to structures */ -#define VPX_CODEC_INTERNAL_ABI_VERSION (4) /**<\hideinitializer*/ +#define VPX_CODEC_INTERNAL_ABI_VERSION (5) /**<\hideinitializer*/ typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t; typedef struct vpx_codec_priv_enc_mr_cfg vpx_codec_priv_enc_mr_cfg_t; @@ -218,6 +218,36 @@ typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)(vpx_codec_alg_priv_t *ctx, typedef vpx_image_t *(*vpx_codec_get_frame_fn_t)(vpx_codec_alg_priv_t *ctx, vpx_codec_iter_t *iter); +/*!\brief Pass in external frame buffers for the decoder to use. + * + * Registers functions to be called when libvpx needs a frame buffer + * to decode the current frame and a function to be called when libvpx does + * not internally reference the frame buffer. This set function must + * be called before the first call to decode or libvpx will assume the + * default behavior of allocating frame buffers internally. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb_get Pointer to the get callback function + * \param[in] cb_release Pointer to the release callback function + * \param[in] cb_priv Callback's private data + * + * \retval #VPX_CODEC_OK + * External frame buffers will be used by libvpx. + * \retval #VPX_CODEC_INVALID_PARAM + * One or more of the callbacks were NULL. + * \retval #VPX_CODEC_ERROR + * Decoder context not initialized, or algorithm not capable of + * using external frame buffers. + * + * \note + * When decoding VP9, the application may be required to pass in at least + * #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS external frame + * buffers. + */ +typedef vpx_codec_err_t (*vpx_codec_set_fb_fn_t)( + vpx_codec_alg_priv_t *ctx, + vpx_get_frame_buffer_cb_fn_t cb_get, + vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv); /*\brief eXternal Memory Allocation memory map get iterator * @@ -308,6 +338,7 @@ struct vpx_codec_iface { vpx_codec_get_si_fn_t get_si; /**< \copydoc ::vpx_codec_get_si_fn_t */ vpx_codec_decode_fn_t decode; /**< \copydoc ::vpx_codec_decode_fn_t */ vpx_codec_get_frame_fn_t get_frame; /**< \copydoc ::vpx_codec_get_frame_fn_t */ + vpx_codec_set_fb_fn_t set_fb_fn; /**< \copydoc ::vpx_codec_set_fb_fn_t */ } dec; struct vpx_codec_enc_iface { vpx_codec_enc_cfg_map_t *cfg_maps; /**< \copydoc ::vpx_codec_enc_cfg_map_t */ diff --git a/vpx/src/vpx_decoder.c b/vpx/src/vpx_decoder.c index a99e48f88..63fdaf308 100644 --- a/vpx/src/vpx_decoder.c +++ b/vpx/src/vpx_decoder.c @@ -226,3 +226,21 @@ vpx_codec_err_t vpx_codec_set_mem_map(vpx_codec_ctx_t *ctx, return SAVE_STATUS(ctx, res); } + +vpx_codec_err_t vpx_codec_set_frame_buffer_functions( + vpx_codec_ctx_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get, + vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { + vpx_codec_err_t res; + + if (!ctx || !cb_get || !cb_release) { + res = VPX_CODEC_INVALID_PARAM; + } else if (!ctx->iface || !ctx->priv || + !(ctx->iface->caps & VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER)) { + res = VPX_CODEC_ERROR; + } else { + res = ctx->iface->dec.set_fb_fn(ctx->priv->alg_priv, cb_get, cb_release, + cb_priv); + } + + return SAVE_STATUS(ctx, res); +} diff --git a/vpx/vpx_decoder.h b/vpx/vpx_decoder.h index 7356baea3..ba183283e 100644 --- a/vpx/vpx_decoder.h +++ b/vpx/vpx_decoder.h @@ -30,6 +30,7 @@ extern "C" { #endif #include "./vpx_codec.h" +#include "./vpx_frame_buffer.h" /*!\brief Current ABI version number * @@ -39,7 +40,7 @@ extern "C" { * types, removing or reassigning enums, adding/removing/rearranging * fields to structures */ -#define VPX_DECODER_ABI_VERSION (2 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/ +#define VPX_DECODER_ABI_VERSION (3 + VPX_CODEC_ABI_VERSION) /**<\hideinitializer*/ /*! \brief Decoder capabilities bitfield * @@ -66,6 +67,8 @@ extern "C" { */ #define VPX_CODEC_CAP_FRAME_THREADING 0x200000 /**< Can support frame-based multi-threading */ +#define VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER 0x400000 /**< Can support external + frame buffers */ #define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded frame */ #define VPX_CODEC_USE_ERROR_CONCEALMENT 0x20000 /**< Conceal errors in decoded @@ -326,6 +329,51 @@ extern "C" { /*!@} - end defgroup cap_put_slice*/ + /*!\defgroup cap_external_frame_buffer External Frame Buffer Functions + * + * The following section is required to be implemented for all decoders + * that advertise the VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER capability. + * Calling this function for codecs that don't advertise this capability + * will result in an error code being returned, usually VPX_CODEC_ERROR. + * + * \note + * Currently this only works with VP9. + * @{ + */ + + /*!\brief Pass in external frame buffers for the decoder to use. + * + * Registers functions to be called when libvpx needs a frame buffer + * to decode the current frame and a function to be called when libvpx does + * not internally reference the frame buffer. This set function must + * be called before the first call to decode or libvpx will assume the + * default behavior of allocating frame buffers internally. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb_get Pointer to the get callback function + * \param[in] cb_release Pointer to the release callback function + * \param[in] cb_priv Callback's private data + * + * \retval #VPX_CODEC_OK + * External frame buffers will be used by libvpx. + * \retval #VPX_CODEC_INVALID_PARAM + * One or more of the callbacks were NULL. + * \retval #VPX_CODEC_ERROR + * Decoder context not initialized, or algorithm not capable of + * using external frame buffers. + * + * \note + * When decoding VP9, the application may be required to pass in at least + * #VP9_MAXIMUM_REF_BUFFERS + #VPX_MAXIMUM_WORK_BUFFERS external frame + * buffers. + */ + vpx_codec_err_t vpx_codec_set_frame_buffer_functions( + vpx_codec_ctx_t *ctx, + vpx_get_frame_buffer_cb_fn_t cb_get, + vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv); + + /*!@} - end defgroup cap_external_frame_buffer */ + /*!@} - end defgroup decoder*/ #ifdef __cplusplus } diff --git a/vpx/vpx_frame_buffer.h b/vpx/vpx_frame_buffer.h index b5489b41b..6803759d7 100644 --- a/vpx/vpx_frame_buffer.h +++ b/vpx/vpx_frame_buffer.h @@ -45,8 +45,9 @@ typedef struct vpx_codec_frame_buffer { * decoder needs a frame buffer to decode a compressed image into. This * function may be called more than once for every call to vpx_codec_decode. * The application may set fb->priv to some data which will be passed - * back in the ximage and the release function call. On success the callback - * must return 0. Any failure the callback must return a value less than 0. + * back in the ximage and the release function call. |fb| is guaranteed to + * not be NULL. On success the callback must return 0. Any failure the + * callback must return a value less than 0. * * \param[in] priv Callback's private data * \param[in] new_size Size in bytes needed by the buffer @@ -58,8 +59,9 @@ typedef int (*vpx_get_frame_buffer_cb_fn_t)( /*!\brief release frame buffer callback prototype * * This callback is invoked by the decoder when the frame buffer is not - * referenced by any other buffers. On success the callback must return 0. - * Any failure the callback must return a value less than 0. + * referenced by any other buffers. |fb| is guaranteed to not be NULL. On + * success the callback must return 0. Any failure the callback must return + * a value less than 0. * * \param[in] priv Callback's private data * \param[in] fb Pointer to vpx_codec_frame_buffer_t diff --git a/vpx/vpx_image.h b/vpx/vpx_image.h index d27325cad..8d0f4ec8c 100644 --- a/vpx/vpx_image.h +++ b/vpx/vpx_image.h @@ -28,7 +28,7 @@ extern "C" { * types, removing or reassigning enums, adding/removing/rearranging * fields to structures */ -#define VPX_IMAGE_ABI_VERSION (1) /**<\hideinitializer*/ +#define VPX_IMAGE_ABI_VERSION (2) /**<\hideinitializer*/ #define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar format */ @@ -139,6 +139,8 @@ extern "C" { unsigned char *img_data; /**< private */ int img_data_owner; /**< private */ int self_allocd; /**< private */ + + void *fb_priv; /**< Frame buffer data associated with the image. */ } vpx_image_t; /**< alias for struct vpx_image */ /**\brief Representation of a rectangle on a surface */ |