diff --git a/doc/APIchanges b/doc/APIchanges index 1b6891108d..aa92b69f79 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,10 @@ libavutil: 2014-08-09 API changes, most recent first: +2015-xx-xx - lavc 56.58.100 - vaapi.h + Deprecate old VA-API context (vaapi_context) fields that were only + set and used by libavcodec. They are all managed internally now. + 2015-xx-xx - lavu 54.31.100 - pixfmt.h Add a unique pixel format for VA-API (AV_PIX_FMT_VAAPI) that indicates the nature of the underlying storage: a VA surface. This diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c index 6ac22e64fa..5dc43e1d14 100644 --- a/libavcodec/vaapi.c +++ b/libavcodec/vaapi.c @@ -21,6 +21,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/log.h" #include "h264.h" #include "vaapi_internal.h" @@ -41,7 +42,28 @@ static void destroy_buffers(VADisplay display, VABufferID *buffers, unsigned int } } -int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface) +int ff_vaapi_context_init(AVCodecContext *avctx) +{ + FFVAContext * const vactx = ff_vaapi_get_context(avctx); + const struct vaapi_context * const user_vactx = avctx->hwaccel_context; + + if (!user_vactx) { + av_log(avctx, AV_LOG_ERROR, "Hardware acceleration context (hwaccel_context) does not exist.\n"); + return AVERROR(ENOSYS); + } + + vactx->display = user_vactx->display; + vactx->config_id = user_vactx->config_id; + vactx->context_id = user_vactx->context_id; + return 0; +} + +int ff_vaapi_context_fini(AVCodecContext *avctx) +{ + return 0; +} + +int ff_vaapi_render_picture(FFVAContext *vactx, VASurfaceID surface) { VABufferID va_buffers[3]; unsigned int n_va_buffers = 0; @@ -81,7 +103,7 @@ int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface) return 0; } -int ff_vaapi_commit_slices(struct vaapi_context *vactx) +int ff_vaapi_commit_slices(FFVAContext *vactx) { VABufferID *slice_buf_ids; VABufferID slice_param_buf_id, slice_data_buf_id; @@ -121,7 +143,7 @@ int ff_vaapi_commit_slices(struct vaapi_context *vactx) return 0; } -static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int size, uint32_t *buf_id) +static void *alloc_buffer(FFVAContext *vactx, int type, unsigned int size, uint32_t *buf_id) { void *data = NULL; @@ -133,22 +155,22 @@ static void *alloc_buffer(struct vaapi_context *vactx, int type, unsigned int si return data; } -void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size) +void *ff_vaapi_alloc_pic_param(FFVAContext *vactx, unsigned int size) { return alloc_buffer(vactx, VAPictureParameterBufferType, size, &vactx->pic_param_buf_id); } -void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size) +void *ff_vaapi_alloc_iq_matrix(FFVAContext *vactx, unsigned int size) { return alloc_buffer(vactx, VAIQMatrixBufferType, size, &vactx->iq_matrix_buf_id); } -uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size) +uint8_t *ff_vaapi_alloc_bitplane(FFVAContext *vactx, uint32_t size) { return alloc_buffer(vactx, VABitPlaneBufferType, size, &vactx->bitplane_buf_id); } -VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size) +VASliceParameterBufferBase *ff_vaapi_alloc_slice(FFVAContext *vactx, const uint8_t *buffer, uint32_t size) { uint8_t *slice_params; VASliceParameterBufferBase *slice_param; @@ -181,7 +203,7 @@ VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, co void ff_vaapi_common_end_frame(AVCodecContext *avctx) { - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); ff_dlog(avctx, "ff_vaapi_common_end_frame()\n"); @@ -202,7 +224,7 @@ void ff_vaapi_common_end_frame(AVCodecContext *avctx) CONFIG_VC1_VAAPI_HWACCEL || CONFIG_WMV3_VAAPI_HWACCEL int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx) { - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); MpegEncContext *s = avctx->priv_data; int ret; diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h index 815a27e226..4448a2ec2f 100644 --- a/libavcodec/vaapi.h +++ b/libavcodec/vaapi.h @@ -31,6 +31,8 @@ */ #include +#include +#include "version.h" /** * @defgroup lavc_codec_hwaccel_vaapi VA API Decoding @@ -72,12 +74,14 @@ struct vaapi_context { */ uint32_t context_id; +#if FF_API_VAAPI_CONTEXT /** * VAPictureParameterBuffer ID * * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated uint32_t pic_param_buf_id; /** @@ -86,6 +90,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated uint32_t iq_matrix_buf_id; /** @@ -94,6 +99,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated uint32_t bitplane_buf_id; /** @@ -102,6 +108,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated uint32_t *slice_buf_ids; /** @@ -110,6 +117,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated unsigned int n_slice_buf_ids; /** @@ -118,6 +126,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated unsigned int slice_buf_ids_alloc; /** @@ -126,6 +135,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated void *slice_params; /** @@ -134,6 +144,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated unsigned int slice_param_size; /** @@ -142,6 +153,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated unsigned int slice_params_alloc; /** @@ -150,6 +162,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated unsigned int slice_count; /** @@ -157,6 +170,7 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated const uint8_t *slice_data; /** @@ -165,7 +179,9 @@ struct vaapi_context { * - encoding: unused * - decoding: Set by libavcodec */ + attribute_deprecated uint32_t slice_data_size; +#endif }; /* @} */ diff --git a/libavcodec/vaapi_h264.c b/libavcodec/vaapi_h264.c index 55ee2fc233..ded2cb3d49 100644 --- a/libavcodec/vaapi_h264.c +++ b/libavcodec/vaapi_h264.c @@ -227,7 +227,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, av_unused uint32_t size) { H264Context * const h = avctx->priv_data; - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VAPictureParameterBufferH264 *pic_param; VAIQMatrixBufferH264 *iq_matrix; @@ -292,7 +292,7 @@ static int vaapi_h264_start_frame(AVCodecContext *avctx, /** End a hardware decoding based frame. */ static int vaapi_h264_end_frame(AVCodecContext *avctx) { - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); H264Context * const h = avctx->priv_data; H264SliceContext *sl = &h->slice_ctx[0]; int ret; @@ -318,6 +318,7 @@ static int vaapi_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { + FFVAContext * const vactx = ff_vaapi_get_context(avctx); H264Context * const h = avctx->priv_data; H264SliceContext *sl = &h->slice_ctx[0]; VASliceParameterBufferH264 *slice_param; @@ -326,7 +327,7 @@ static int vaapi_h264_decode_slice(AVCodecContext *avctx, buffer, size); /* Fill in VASliceParameterBufferH264. */ - slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); + slice_param = (VASliceParameterBufferH264 *)ff_vaapi_alloc_slice(vactx, buffer, size); if (!slice_param) return -1; slice_param->slice_data_bit_offset = get_bits_count(&sl->gb) + 8; /* bit buffer started beyond nal_unit_type */ @@ -363,4 +364,7 @@ AVHWAccel ff_h264_vaapi_hwaccel = { .start_frame = vaapi_h264_start_frame, .end_frame = vaapi_h264_end_frame, .decode_slice = vaapi_h264_decode_slice, + .init = ff_vaapi_context_init, + .uninit = ff_vaapi_context_fini, + .priv_data_size = sizeof(FFVAContext), }; diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h index 918c718d14..29f46ab430 100644 --- a/libavcodec/vaapi_internal.h +++ b/libavcodec/vaapi_internal.h @@ -35,23 +35,53 @@ * @{ */ +typedef struct { + VADisplay display; ///< Windowing system dependent handle + VAConfigID config_id; ///< Configuration ID + VAContextID context_id; ///< Context ID (video decode pipeline) + VABufferID pic_param_buf_id; ///< Picture parameter buffer + VABufferID iq_matrix_buf_id; ///< Inverse quantiser matrix buffer + VABufferID bitplane_buf_id; ///< Bitplane buffer (for VC-1 decoding) + VABufferID *slice_buf_ids; ///< Slice parameter/data buffers + unsigned int n_slice_buf_ids; ///< Number of effective slice buffers + unsigned int slice_buf_ids_alloc; ///< Number of allocated slice buffers + void *slice_params; ///< Pointer to slice parameter buffers + unsigned int slice_param_size; ///< Size of a slice parameter element + unsigned int slice_params_alloc; ///< Number of allocated slice parameters + unsigned int slice_count; ///< Number of slices currently filled in + const uint8_t *slice_data; ///< Pointer to slice data buffer base + unsigned int slice_data_size; ///< Current size of slice data +} FFVAContext; + +/** Extract vaapi_context from an AVCodecContext */ +static inline FFVAContext *ff_vaapi_get_context(AVCodecContext *avctx) +{ + return avctx->internal->hwaccel_priv_data; +} + /** Extract VASurfaceID from an AVFrame */ static inline VASurfaceID ff_vaapi_get_surface_id(AVFrame *pic) { return (uintptr_t)pic->data[3]; } +/** Common AVHWAccel.init() implementation */ +int ff_vaapi_context_init(AVCodecContext *avctx); + +/** Common AVHWAccel.uninit() implementation */ +int ff_vaapi_context_fini(AVCodecContext *avctx); + /** Common AVHWAccel.end_frame() implementation */ void ff_vaapi_common_end_frame(AVCodecContext *avctx); /** Allocate a new picture parameter buffer */ -void *ff_vaapi_alloc_pic_param(struct vaapi_context *vactx, unsigned int size); +void *ff_vaapi_alloc_pic_param(FFVAContext *vactx, unsigned int size); /** Allocate a new IQ matrix buffer */ -void *ff_vaapi_alloc_iq_matrix(struct vaapi_context *vactx, unsigned int size); +void *ff_vaapi_alloc_iq_matrix(FFVAContext *vactx, unsigned int size); /** Allocate a new bit-plane buffer */ -uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size); +uint8_t *ff_vaapi_alloc_bitplane(FFVAContext *vactx, uint32_t size); /** * Allocate a new slice descriptor for the input slice. @@ -61,11 +91,11 @@ uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size); * @param size the size of the slice in bytes * @return the newly allocated slice parameter */ -VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size); +VASliceParameterBufferBase *ff_vaapi_alloc_slice(FFVAContext *vactx, const uint8_t *buffer, uint32_t size); int ff_vaapi_mpeg_end_frame(AVCodecContext *avctx); -int ff_vaapi_commit_slices(struct vaapi_context *vactx); -int ff_vaapi_render_picture(struct vaapi_context *vactx, VASurfaceID surface); +int ff_vaapi_commit_slices(FFVAContext *vactx); +int ff_vaapi_render_picture(FFVAContext *vactx, VASurfaceID surface); /* @} */ diff --git a/libavcodec/vaapi_mpeg2.c b/libavcodec/vaapi_mpeg2.c index 27c69cde14..a3deab124b 100644 --- a/libavcodec/vaapi_mpeg2.c +++ b/libavcodec/vaapi_mpeg2.c @@ -40,7 +40,7 @@ static inline int mpeg2_get_is_frame_start(MpegEncContext *s) static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) { struct MpegEncContext * const s = avctx->priv_data; - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VAPictureParameterBufferMPEG2 *pic_param; VAIQMatrixBufferMPEG2 *iq_matrix; int i; @@ -103,6 +103,7 @@ static int vaapi_mpeg2_start_frame(AVCodecContext *avctx, av_unused const uint8_ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { MpegEncContext * const s = avctx->priv_data; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VASliceParameterBufferMPEG2 *slice_param; GetBitContext gb; uint32_t quantiser_scale_code, intra_slice_flag, macroblock_offset; @@ -123,7 +124,7 @@ static int vaapi_mpeg2_decode_slice(AVCodecContext *avctx, const uint8_t *buffer macroblock_offset = get_bits_count(&gb); /* Fill in VASliceParameterBufferMPEG2 */ - slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); + slice_param = (VASliceParameterBufferMPEG2 *)ff_vaapi_alloc_slice(vactx, buffer, size); if (!slice_param) return -1; slice_param->macroblock_offset = macroblock_offset; @@ -142,4 +143,7 @@ AVHWAccel ff_mpeg2_vaapi_hwaccel = { .start_frame = vaapi_mpeg2_start_frame, .end_frame = ff_vaapi_mpeg_end_frame, .decode_slice = vaapi_mpeg2_decode_slice, + .init = ff_vaapi_context_init, + .uninit = ff_vaapi_context_fini, + .priv_data_size = sizeof(FFVAContext), }; diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c index 5b2e9d4446..426bef2646 100644 --- a/libavcodec/vaapi_mpeg4.c +++ b/libavcodec/vaapi_mpeg4.c @@ -45,7 +45,7 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_ { Mpeg4DecContext *ctx = avctx->priv_data; MpegEncContext * const s = &ctx->m; - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VAPictureParameterBufferMPEG4 *pic_param; VAIQMatrixBufferMPEG4 *iq_matrix; int i; @@ -121,12 +121,13 @@ static int vaapi_mpeg4_start_frame(AVCodecContext *avctx, av_unused const uint8_ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { MpegEncContext * const s = avctx->priv_data; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VASliceParameterBufferMPEG4 *slice_param; ff_dlog(avctx, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer, size); /* Fill in VASliceParameterBufferMPEG4 */ - slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); + slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(vactx, buffer, size); if (!slice_param) return -1; slice_param->macroblock_offset = get_bits_count(&s->gb) % 8; @@ -145,6 +146,9 @@ AVHWAccel ff_mpeg4_vaapi_hwaccel = { .start_frame = vaapi_mpeg4_start_frame, .end_frame = ff_vaapi_mpeg_end_frame, .decode_slice = vaapi_mpeg4_decode_slice, + .init = ff_vaapi_context_init, + .uninit = ff_vaapi_context_fini, + .priv_data_size = sizeof(FFVAContext), }; #endif @@ -157,5 +161,8 @@ AVHWAccel ff_h263_vaapi_hwaccel = { .start_frame = vaapi_mpeg4_start_frame, .end_frame = ff_vaapi_mpeg_end_frame, .decode_slice = vaapi_mpeg4_decode_slice, + .init = ff_vaapi_context_init, + .uninit = ff_vaapi_context_fini, + .priv_data_size = sizeof(FFVAContext), }; #endif diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c index 63d514d54e..5ded5dba89 100644 --- a/libavcodec/vaapi_vc1.c +++ b/libavcodec/vaapi_vc1.c @@ -148,7 +148,7 @@ static int vaapi_vc1_start_frame(AVCodecContext *avctx, av_unused const uint8_t { VC1Context * const v = avctx->priv_data; MpegEncContext * const s = &v->s; - struct vaapi_context * const vactx = avctx->hwaccel_context; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VAPictureParameterBufferVC1 *pic_param; ff_dlog(avctx, "vaapi_vc1_start_frame()\n"); @@ -315,6 +315,7 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, { VC1Context * const v = avctx->priv_data; MpegEncContext * const s = &v->s; + FFVAContext * const vactx = ff_vaapi_get_context(avctx); VASliceParameterBufferVC1 *slice_param; ff_dlog(avctx, "vaapi_vc1_decode_slice(): buffer %p, size %d\n", buffer, size); @@ -326,7 +327,7 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, } /* Fill in VASliceParameterBufferVC1 */ - slice_param = (VASliceParameterBufferVC1 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size); + slice_param = (VASliceParameterBufferVC1 *)ff_vaapi_alloc_slice(vactx, buffer, size); if (!slice_param) return -1; slice_param->macroblock_offset = get_bits_count(&s->gb); @@ -343,6 +344,9 @@ AVHWAccel ff_wmv3_vaapi_hwaccel = { .start_frame = vaapi_vc1_start_frame, .end_frame = ff_vaapi_mpeg_end_frame, .decode_slice = vaapi_vc1_decode_slice, + .init = ff_vaapi_context_init, + .uninit = ff_vaapi_context_fini, + .priv_data_size = sizeof(FFVAContext), }; #endif @@ -354,4 +358,7 @@ AVHWAccel ff_vc1_vaapi_hwaccel = { .start_frame = vaapi_vc1_start_frame, .end_frame = ff_vaapi_mpeg_end_frame, .decode_slice = vaapi_vc1_decode_slice, + .init = ff_vaapi_context_init, + .uninit = ff_vaapi_context_fini, + .priv_data_size = sizeof(FFVAContext), }; diff --git a/libavcodec/version.h b/libavcodec/version.h index 2e7cf40961..a118d5b223 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,8 +29,8 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 56 -#define LIBAVCODEC_VERSION_MINOR 57 -#define LIBAVCODEC_VERSION_MICRO 101 +#define LIBAVCODEC_VERSION_MINOR 58 +#define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -181,6 +181,9 @@ #ifndef FF_API_AUDIOENC_DELAY #define FF_API_AUDIOENC_DELAY (LIBAVCODEC_VERSION_MAJOR < 58) #endif +#ifndef FF_API_VAAPI_CONTEXT +#define FF_API_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 58) +#endif #ifndef FF_API_AVCTX_TIMEBASE #define FF_API_AVCTX_TIMEBASE (LIBAVCODEC_VERSION_MAJOR < 59) #endif