From 21ce5107db67827b265cc9241a8247df2c137055 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Wed, 4 Dec 2013 00:00:57 +0100 Subject: [PATCH] API: add support for buffer exports. Add interfaces for low-level buffer exports to suport interop with external APIs like EGL or OpenCL (OCL). Theory of operations: - vaAcquireBufferHandle(): locks buffer for external API usage. This is a synchronization point. Upon successful return, useful buffer details are returned in a somewhat implementation-specific way to support interop with external APIs. - vaReleaseBufferHandle(): unlocks buffer after usage from external API, and deallocates any resources that were needed. Signed-off-by: Gwenole Beauchesne (cherry picked from commit 544d31d2fc096a838c21f4684cec05746cfdd7b6) Conflicts: va/va.h --- va/va.c | 28 +++++++++++++++ va/va.h | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- va/va_backend.h | 13 +++++++ 3 files changed, 147 insertions(+), 1 deletion(-) diff --git a/va/va.c b/va/va.c index 4f3be28..3ef01fa 100644 --- a/va/va.c +++ b/va/va.c @@ -1059,6 +1059,34 @@ VAStatus vaBufferInfo ( return ctx->vtable->vaBufferInfo( ctx, buf_id, type, size, num_elements ); } +/* Locks buffer for external API usage */ +VAStatus +vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info) +{ + VADriverContextP ctx; + + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + if (!ctx->vtable->vaAcquireBufferHandle) + return VA_STATUS_ERROR_UNIMPLEMENTED; + return ctx->vtable->vaAcquireBufferHandle(ctx, buf_id, buf_info); +} + +/* Unlocks buffer after usage from external API */ +VAStatus +vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id) +{ + VADriverContextP ctx; + + CHECK_DISPLAY(dpy); + ctx = CTX(dpy); + + if (!ctx->vtable->vaReleaseBufferHandle) + return VA_STATUS_ERROR_UNIMPLEMENTED; + return ctx->vtable->vaReleaseBufferHandle(ctx, buf_id); +} + VAStatus vaBeginPicture ( VADisplay dpy, VAContextID context, diff --git a/va/va.h b/va/va.h index a11cdfe..127ad49 100644 --- a/va/va.h +++ b/va/va.h @@ -78,6 +78,7 @@ #ifndef _VA_H_ #define _VA_H_ +#include #include #include @@ -178,7 +179,9 @@ typedef int VAStatus; /** Return status type from functions */ /** \brief An invalid filter chain was supplied. */ #define VA_STATUS_ERROR_INVALID_FILTER_CHAIN 0x00000021 /** \brief Indicate HW busy (e.g. run multiple encoding simultaneously). */ -#define VA_STATUS_ERROR_HW_BUSY 0x00000022 +#define VA_STATUS_ERROR_HW_BUSY 0x00000022 +/** \brief An unsupported memory type was supplied. */ +#define VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE 0x00000024 #define VA_STATUS_ERROR_UNKNOWN 0xFFFFFFFF /** De-interlacing flags for vaPutSurface() */ @@ -1900,6 +1903,108 @@ VAStatus vaDestroyBuffer ( VABufferID buffer_id ); +/** \brief VA buffer information */ +typedef struct { + /** \brief Buffer handle */ + uintptr_t handle; + /** \brief Buffer type (See \ref VABufferType). */ + uint32_t type; + /** + * \brief Buffer memory type (See \ref VASurfaceAttribMemoryType). + * + * On input to vaAcquireBufferHandle(), this field can serve as a hint + * to specify the set of memory types the caller is interested in. + * On successful return from vaAcquireBufferHandle(), the field is + * updated with the best matching memory type. + */ + uint32_t mem_type; + /** \brief Size of the underlying buffer. */ + size_t mem_size; +} VABufferInfo; + +/** + * \brief Acquires buffer handle for external API usage + * + * Locks the VA buffer object \ref buf_id for external API usage like + * EGL or OpenCL (OCL). This function is a synchronization point. This + * means that any pending operation is guaranteed to be completed + * prior to returning from the function. + * + * If the referenced VA buffer object is the backing store of a VA + * surface, then this function acts as if vaSyncSurface() on the + * parent surface was called first. + * + * The \ref VABufferInfo argument shall be zero'ed on input. On + * successful output, the data structure is filled in with all the + * necessary buffer level implementation details like handle, type, + * memory type and memory size. + * + * Note: the external API implementation, or the application, can + * express the memory types it is interested in by filling in the \ref + * mem_type field accordingly. On successful output, the memory type + * that fits best the request and that was used is updated in the \ref + * VABufferInfo data structure. If none of the supplied memory types + * is supported, then a \ref VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE + * error is returned. + * + * The \ref VABufferInfo data is valid until vaReleaseBufferHandle() + * is called. Besides, no additional operation is allowed on any of + * the buffer parent object until vaReleaseBufferHandle() is called. + * e.g. decoding into a VA surface backed with the supplied VA buffer + * object \ref buf_id would fail with a \ref VA_STATUS_ERROR_SURFACE_BUSY + * error. + * + * Possible errors: + * - \ref VA_STATUS_ERROR_UNIMPLEMENTED: the VA driver implementation + * does not support this interface + * - \ref VA_STATUS_ERROR_INVALID_DISPLAY: an invalid display was supplied + * - \ref VA_STATUS_ERROR_INVALID_BUFFER: an invalid buffer was supplied + * - \ref VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: the implementation + * does not support exporting buffers of the specified type + * - \ref VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE: none of the requested + * memory types in \ref VABufferInfo.mem_type was supported + * + * @param[in] dpy the VA display + * @param[in] buf_id the VA buffer + * @param[in,out] buf_info the associated VA buffer information + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaAcquireBufferHandle(VADisplay dpy, VABufferID buf_id, VABufferInfo *buf_info); + +/** + * \brief Releases buffer after usage from external API + * + * Unlocks the VA buffer object \ref buf_id from external API usage like + * EGL or OpenCL (OCL). This function is a synchronization point. This + * means that any pending operation is guaranteed to be completed + * prior to returning from the function. + * + * The \ref VABufferInfo argument shall point to the original data + * structure that was obtained from vaAcquireBufferHandle(), unaltered. + * This is necessary so that the VA driver implementation could + * deallocate any resources that were needed. + * + * In any case, returning from this function invalidates any contents + * in \ref VABufferInfo. i.e. the underlyng buffer handle is no longer + * valid. Therefore, VA driver implementations are free to reset this + * data structure to safe defaults. + * + * Possible errors: + * - \ref VA_STATUS_ERROR_UNIMPLEMENTED: the VA driver implementation + * does not support this interface + * - \ref VA_STATUS_ERROR_INVALID_DISPLAY: an invalid display was supplied + * - \ref VA_STATUS_ERROR_INVALID_BUFFER: an invalid buffer was supplied + * - \ref VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE: the implementation + * does not support exporting buffers of the specified type + * + * @param[in] dpy the VA display + * @param[in] buf_id the VA buffer + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaReleaseBufferHandle(VADisplay dpy, VABufferID buf_id); + /* Render (Decode) Pictures diff --git a/va/va_backend.h b/va/va_backend.h index bd82849..5e8dc42 100644 --- a/va/va_backend.h +++ b/va/va_backend.h @@ -420,6 +420,19 @@ struct VADriverVTable VASurfaceAttrib *attrib_list, unsigned int *num_attribs ); + + VAStatus + (*vaAcquireBufferHandle)( + VADriverContextP ctx, + VABufferID buf_id, /* in */ + VABufferInfo * buf_info /* in/out */ + ); + + VAStatus + (*vaReleaseBufferHandle)( + VADriverContextP ctx, + VABufferID buf_id /* in */ + ); }; struct VADriverContext -- 2.11.0