Hi, 2015-08-17 19:17 GMT+02:00 Gwenole Beauchesne <gb.de...@gmail.com>: > Add av_vaapi_context_init() and av_vaapi_context_alloc() helper functions > so that to properly initialize the vaapi_context structure, and allow for > future extensions without breaking the API/ABI. > > The new version and flags fields are inserted after the last known user > initialized field, and actually useful field at all, i.e. VA context_id. > This is safe because the vaapi_context structure was required to be zero > initialized in the past. And, since those new helper functions and changes > cause the AV_VAAPI_CONTEXT_VERSION to be bumped, we can track older struct > requirements from within libavcodec. > > Besides, it is now required by design, and actual usage, that the vaapi > context structure be completely initialized once and for all before the > AVCodecContext.get_format() function ever completes. > > Signed-off-by: Gwenole Beauchesne <gwenole.beauche...@intel.com> > --- > libavcodec/vaapi.c | 30 +++++++++++++++++++++++ > libavcodec/vaapi.h | 59 > +++++++++++++++++++++++++++++++++++++++++---- > libavcodec/vaapi_internal.h | 1 + > 3 files changed, 85 insertions(+), 5 deletions(-) > > diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c > index 1ae71a5..4d3e2f3 100644 > --- a/libavcodec/vaapi.c > +++ b/libavcodec/vaapi.c > @@ -41,11 +41,41 @@ static void destroy_buffers(VADisplay display, VABufferID > *buffers, unsigned int > } > } > > +/* Allocates a vaapi_context structure */ > +struct vaapi_context *av_vaapi_context_alloc(unsigned int flags) > +{ > + struct vaapi_context *vactx; > + > + vactx = av_malloc(sizeof(*vactx)); > + if (!vactx) > + return NULL; > + > + av_vaapi_context_init(vactx, AV_VAAPI_CONTEXT_VERSION, flags); > + return vactx; > +} > + > +/* Initializes a vaapi_context structure with safe defaults */ > +void av_vaapi_context_init(struct vaapi_context *vactx, unsigned int version, > + unsigned int flags) > +{ > + vactx->display = NULL; > + vactx->config_id = VA_INVALID_ID; > + vactx->context_id = VA_INVALID_ID; > + > + if (version > 0) { > + vactx->version = version; > + vactx->flags = flags; > + } > +} > + > 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->version > 0) > + vactx->flags = user_vactx->flags; > + > vactx->display = user_vactx->display; > vactx->config_id = user_vactx->config_id; > vactx->context_id = user_vactx->context_id; > diff --git a/libavcodec/vaapi.h b/libavcodec/vaapi.h > index 4448a2e..1f032a0 100644 > --- a/libavcodec/vaapi.h > +++ b/libavcodec/vaapi.h > @@ -40,14 +40,16 @@ > * @{ > */ > > +#define AV_VAAPI_CONTEXT_VERSION 1 > + > /** > * This structure is used to share data between the FFmpeg library and > * the client video application. > - * This shall be zero-allocated and available as > - * AVCodecContext.hwaccel_context. All user members can be set once > - * during initialization or through each AVCodecContext.get_buffer() > - * function call. In any case, they must be valid prior to calling > - * decoding functions. > + * > + * This shall be initialized with av_vaapi_context_init(), or > + * indirectly through av_vaapi_context_alloc(), and made available as > + * AVCodecContext.hwaccel_context. All user members must be properly > + * initialized before AVCodecContext.get_format() completes. > */ > struct vaapi_context { > /** > @@ -74,6 +76,29 @@ struct vaapi_context { > */ > uint32_t context_id; > > + /** > + * This field must be set to AV_VAAPI_CONTEXT_VERSION > + * > + * @since Version 1. > + * > + * - encoding: unused > + * - decoding: Set by user, through av_vaapi_context_init() > + */ > + unsigned int version; > + > + /** > + * A bit field configuring the internal context used by libavcodec > + * > + * This is a combination of flags from common AV_HWACCEL_FLAG_xxx and > + * from VA-API specific AV_VAAPI_FLAG_xxx. > + * > + * @since Version 1. > + * > + * - encoding: unused > + * - decoding: Set by user, through av_vaapi_context_init() > + */ > + unsigned int flags; > + > #if FF_API_VAAPI_CONTEXT > /** > * VAPictureParameterBuffer ID > @@ -184,6 +209,30 @@ struct vaapi_context { > #endif > }; > > +/** > + * Allocates a vaapi_context structure. > + * > + * This function allocates and initializes a vaapi_context with safe > + * defaults, e.g. with proper invalid ids for VA config and context. > + * > + * The resulting structure can be deallocated with av_freep(). > + * > + * @param[in] flags zero, or a combination of AV_HWACCEL_FLAG_xxx or > + * AV_VAAPI_FLAG_xxx flags OR'd altogether. > + * @return Newly-allocated struct vaapi_context, or NULL on failure > + */ > +struct vaapi_context *av_vaapi_context_alloc(unsigned int flags); > + > +/** > + * Initializes a vaapi_context structure with safe defaults. > + * > + * @param[in] version this must be set to AV_VAAPI_CONTEXT_VERSION > + * @param[in] flags zero, or a combination of AV_HWACCEL_FLAG_xxx or > + * AV_VAAPI_FLAG_xxx flags OR'd altogether. > + */ > +void av_vaapi_context_init(struct vaapi_context *vactx, unsigned int version, > + unsigned int flags); > + > /* @} */
For this one, I am not terribly decided yet. The new trend is that I'd now prefer flags to be zero'ed by default and explicitly set through the structure, and not through that helper. Rationale: cosmetically, due to the name of the probable options here, it looks better to OR those afterwards. :) Opinions welcome. Thanks. > > #endif /* AVCODEC_VAAPI_H */ > diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h > index 29f46ab..a7c69e6 100644 > --- a/libavcodec/vaapi_internal.h > +++ b/libavcodec/vaapi_internal.h > @@ -36,6 +36,7 @@ > */ > > typedef struct { > + unsigned int flags; ///< Configuration flags > VADisplay display; ///< Windowing system dependent > handle > VAConfigID config_id; ///< Configuration ID > VAContextID context_id; ///< Context ID (video decode > pipeline) > -- > 1.9.1 > -- Gwenole Beauchesne Intel Corporation SAS / 2 rue de Paris, 92196 Meudon Cedex, France Registration Number (RCS): Nanterre B 302 456 199 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel