[Mesa-dev] [PATCH v2 4/7] st/va: implement VaCreateSurfaces2 and VaQuerySurfaceAttributes
Julien Isorce
julien.isorce at gmail.com
Fri Oct 23 00:43:09 PDT 2015
This patch is missing "memset(&templat, 0, sizeof(templat));" so I am going
to submit a v3 for this one.
On 20 October 2015 at 17:34, Julien Isorce <j.isorce at samsung.com> wrote:
> Inspired from http://cgit.freedesktop.org/vaapi/intel-driver/
> especially src/i965_drv_video.c::i965_CreateSurfaces2.
>
> This patch is mainly to support gstreamer-vaapi and tools that uses
> this newer libva API. The first advantage of using VaCreateSurfaces2
> over existing VaCreateSurfaces, is that it is possible to select which
> the pixel format for the surface. Indeed with the simple VaCreateSurfaces
> function it is only possible to create a NV12 surface. It can be useful
> to create a RGBA surface to use with video post processing.
>
> The avaible pixel formats can be query with VaQuerySurfaceAttributes.
>
> Signed-off-by: Julien Isorce <j.isorce at samsung.com>
> ---
> src/gallium/state_trackers/va/context.c | 5 +-
> src/gallium/state_trackers/va/surface.c | 294
> ++++++++++++++++++++++++-----
> src/gallium/state_trackers/va/va_private.h | 6 +-
> 3 files changed, 253 insertions(+), 52 deletions(-)
>
> diff --git a/src/gallium/state_trackers/va/context.c
> b/src/gallium/state_trackers/va/context.c
> index 8b003ae..9be9085 100644
> --- a/src/gallium/state_trackers/va/context.c
> +++ b/src/gallium/state_trackers/va/context.c
> @@ -81,7 +81,10 @@ static struct VADriverVTable vtable =
> &vlVaSetDisplayAttributes,
> &vlVaBufferInfo,
> &vlVaLockSurface,
> - &vlVaUnlockSurface
> + &vlVaUnlockSurface,
> + NULL, /* DEPRECATED VaGetSurfaceAttributes */
> + &vlVaCreateSurfaces2,
> + &vlVaQuerySurfaceAttributes
> };
>
> PUBLIC VAStatus
> diff --git a/src/gallium/state_trackers/va/surface.c
> b/src/gallium/state_trackers/va/surface.c
> index 8d4487b..62fdf3c 100644
> --- a/src/gallium/state_trackers/va/surface.c
> +++ b/src/gallium/state_trackers/va/surface.c
> @@ -36,6 +36,7 @@
> #include "util/u_surface.h"
>
> #include "vl/vl_compositor.h"
> +#include "vl/vl_video_buffer.h"
> #include "vl/vl_winsys.h"
>
> #include "va_private.h"
> @@ -44,56 +45,8 @@ VAStatus
> vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int
> format,
> int num_surfaces, VASurfaceID *surfaces)
> {
> - struct pipe_video_buffer templat = {};
> - struct pipe_screen *pscreen;
> - vlVaDriver *drv;
> - int i;
> -
> - if (!ctx)
> - return VA_STATUS_ERROR_INVALID_CONTEXT;
> -
> - if (!(width && height))
> - return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
> -
> - drv = VL_VA_DRIVER(ctx);
> - pscreen = VL_VA_PSCREEN(ctx);
> -
> - templat.buffer_format = pscreen->get_video_param
> - (
> - pscreen,
> - PIPE_VIDEO_PROFILE_UNKNOWN,
> - PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
> - PIPE_VIDEO_CAP_PREFERED_FORMAT
> - );
> - templat.chroma_format = ChromaToPipe(format);
> - templat.width = width;
> - templat.height = height;
> - templat.interlaced = pscreen->get_video_param
> - (
> - pscreen,
> - PIPE_VIDEO_PROFILE_UNKNOWN,
> - PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
> - PIPE_VIDEO_CAP_PREFERS_INTERLACED
> - );
> -
> - for (i = 0; i < num_surfaces; ++i) {
> - vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
> - if (!surf)
> - goto no_res;
> -
> - surf->templat = templat;
> - surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);
> - util_dynarray_init(&surf->subpics);
> - surfaces[i] = handle_table_add(drv->htab, surf);
> - }
> -
> - return VA_STATUS_SUCCESS;
> -
> -no_res:
> - if (i)
> - vlVaDestroySurfaces(ctx, surfaces, i);
> -
> - return VA_STATUS_ERROR_ALLOCATION_FAILED;
> + return vlVaCreateSurfaces2(ctx, format, width, height, surfaces,
> num_surfaces,
> + NULL, 0);
> }
>
> VAStatus
> @@ -349,3 +302,244 @@ vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID
> surface)
>
> return VA_STATUS_ERROR_UNIMPLEMENTED;
> }
> +
> +VAStatus
> +vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config,
> + VASurfaceAttrib *attrib_list, unsigned int
> *num_attribs)
> +{
> + vlVaDriver *drv;
> + VASurfaceAttrib *attribs;
> + struct pipe_screen *pscreen;
> + int i;
> +
> + if (config == VA_INVALID_ID)
> + return VA_STATUS_ERROR_INVALID_CONFIG;
> +
> + if (!attrib_list && !num_attribs)
> + return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> + if (!attrib_list) {
> + *num_attribs = VASurfaceAttribCount;
> + return VA_STATUS_SUCCESS;
> + }
> +
> + if (!ctx)
> + return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> + drv = VL_VA_DRIVER(ctx);
> +
> + if (!drv)
> + return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> + pscreen = VL_VA_PSCREEN(ctx);
> +
> + if (!pscreen)
> + return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> + attribs = CALLOC(VASurfaceAttribCount, sizeof(VASurfaceAttrib));
> +
> + if (!attribs)
> + return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +
> + i = 0;
> +
> + if (config == PIPE_VIDEO_PROFILE_UNKNOWN) {
> + /* Assume VAEntrypointVideoProc for now. */
> + attribs[i].type = VASurfaceAttribPixelFormat;
> + attribs[i].value.type = VAGenericValueTypeInteger;
> + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE |
> VA_SURFACE_ATTRIB_SETTABLE;
> + attribs[i].value.value.i = VA_FOURCC_BGRA;
> + i++;
> +
> + attribs[i].type = VASurfaceAttribPixelFormat;
> + attribs[i].value.type = VAGenericValueTypeInteger;
> + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE |
> VA_SURFACE_ATTRIB_SETTABLE;
> + attribs[i].value.value.i = VA_FOURCC_RGBA;
> + i++;
> + } else {
> + /* Assume VAEntrypointVLD for now. */
> + attribs[i].type = VASurfaceAttribPixelFormat;
> + attribs[i].value.type = VAGenericValueTypeInteger;
> + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE |
> VA_SURFACE_ATTRIB_SETTABLE;
> + attribs[i].value.value.i = VA_FOURCC_NV12;
> + i++;
> + }
> +
> + attribs[i].type = VASurfaceAttribMemoryType;
> + attribs[i].value.type = VAGenericValueTypeInteger;
> + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE |
> VA_SURFACE_ATTRIB_SETTABLE;
> + attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
> + i++;
> +
> + attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
> + attribs[i].value.type = VAGenericValueTypePointer;
> + attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
> + attribs[i].value.value.p = NULL; /* ignore */
> + i++;
> +
> + attribs[i].type = VASurfaceAttribMaxWidth;
> + attribs[i].value.type = VAGenericValueTypeInteger;
> + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
> + attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
> + i++;
> +
> + attribs[i].type = VASurfaceAttribMaxHeight;
> + attribs[i].value.type = VAGenericValueTypeInteger;
> + attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
> + attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
> + i++;
> +
> + if (i > *num_attribs) {
> + *num_attribs = i;
> + FREE(attribs);
> + return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
> + }
> +
> + *num_attribs = i;
> + memcpy(attrib_list, attribs, i * sizeof(VASurfaceAttrib));
> + FREE(attribs);
> +
> + return VA_STATUS_SUCCESS;
> +}
> +
> +VAStatus
> +vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
> + unsigned int width, unsigned int height,
> + VASurfaceID *surfaces, unsigned int num_surfaces,
> + VASurfaceAttrib *attrib_list, unsigned int
> num_attribs)
> +{
> + vlVaDriver *drv;
> + VASurfaceAttribExternalBuffers *memory_attibute;
> + struct pipe_video_buffer templat;
> + struct pipe_screen *pscreen;
> + int i;
> + int memory_type;
> + int expected_fourcc;
> +
> + if (!ctx)
> + return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> + if (!(width && height))
> + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
> +
> + drv = VL_VA_DRIVER(ctx);
> +
> + if (!drv)
> + return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> + pscreen = VL_VA_PSCREEN(ctx);
> +
> + if (!pscreen)
> + return VA_STATUS_ERROR_INVALID_CONTEXT;
> +
> + /* Default. */
> + memory_attibute = NULL;
> + memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
> + expected_fourcc = 0;
> +
> + for (i = 0; i < num_attribs && attrib_list; i++) {
> + if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&
> + (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
> + if (attrib_list[i].value.type != VAGenericValueTypeInteger)
> + return VA_STATUS_ERROR_INVALID_PARAMETER;
> + expected_fourcc = attrib_list[i].value.value.i;
> + }
> +
> + if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&
> + (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {
> +
> + if (attrib_list[i].value.type != VAGenericValueTypeInteger)
> + return VA_STATUS_ERROR_INVALID_PARAMETER;
> +
> + switch (attrib_list[i].value.value.i) {
> + case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
> + memory_type = attrib_list[i].value.value.i;
> + break;
> + default:
> + return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
> + }
> + }
> +
> + if ((attrib_list[i].type ==
> VASurfaceAttribExternalBufferDescriptor) &&
> + (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {
> + if (attrib_list[i].value.type != VAGenericValueTypePointer)
> + return VA_STATUS_ERROR_INVALID_PARAMETER;
> + memory_attibute = (VASurfaceAttribExternalBuffers
> *)attrib_list[i].value.value.p;
> + }
> + }
> +
> + if (VA_RT_FORMAT_YUV400 != format &&
> + VA_RT_FORMAT_YUV420 != format &&
> + VA_RT_FORMAT_YUV422 != format &&
> + VA_RT_FORMAT_YUV444 != format &&
> + VA_RT_FORMAT_RGB32 != format) {
> + return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
> + }
> +
> + switch (memory_type) {
> + case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
> + if (memory_attibute)
> + return VA_STATUS_ERROR_UNIMPLEMENTED;
> + break;
> + default:
> + assert(0);
> + }
> +
> + if (expected_fourcc) {
> + templat.buffer_format = YCbCrToPipe(expected_fourcc);
> + templat.interlaced = 0;
> + } else {
> + templat.buffer_format = pscreen->get_video_param
> + (
> + pscreen,
> + PIPE_VIDEO_PROFILE_UNKNOWN,
> + PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
> + PIPE_VIDEO_CAP_PREFERED_FORMAT
> + );
> + templat.interlaced = pscreen->get_video_param
> + (
> + pscreen,
> + PIPE_VIDEO_PROFILE_UNKNOWN,
> + PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
> + PIPE_VIDEO_CAP_PREFERS_INTERLACED
> + );
> + }
> +
> + if (format != VA_RT_FORMAT_RGB32)
> + templat.chroma_format = ChromaToPipe(format);
> +
> + templat.width = width;
> + templat.height = height;
> +
> + memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));
> +
> + for (i = 0; i < num_surfaces; i++) {
> + vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));
> + if (!surf)
> + goto no_res;
> +
> + surf->templat = templat;
> +
> + switch (memory_type) {
> + case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
> + surf->buffer = drv->pipe->create_video_buffer(drv->pipe,
> &templat);
> + if (!surf->buffer)
> + goto no_res;
> + util_dynarray_init(&surf->subpics);
> + surfaces[i] = handle_table_add(drv->htab, surf);
> + break;
> + default:
> + assert(0);
> + }
> + }
> +
> + return VA_STATUS_SUCCESS;
> +
> +no_res:
> + for (i = 0; i < num_surfaces; i++) {
> + if (surfaces[i] != VA_INVALID_ID)
> + vlVaDestroySurfaces(ctx, surfaces, i);
> + }
> +
> + return VA_STATUS_ERROR_ALLOCATION_FAILED;
> +}
> diff --git a/src/gallium/state_trackers/va/va_private.h
> b/src/gallium/state_trackers/va/va_private.h
> index 303b0c6..c0287e7 100644
> --- a/src/gallium/state_trackers/va/va_private.h
> +++ b/src/gallium/state_trackers/va/va_private.h
> @@ -311,5 +311,9 @@ VAStatus vlVaLockSurface(VADriverContextP ctx,
> VASurfaceID surface, unsigned int
> unsigned int *luma_offset, unsigned int
> *chroma_u_offset, unsigned int *chroma_v_offset,
> unsigned int *buffer_name, void **buffer);
> VAStatus vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface);
> -
> +VAStatus vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
> unsigned int width, unsigned int height,
> + VASurfaceID *surfaces, unsigned int
> num_surfaces, VASurfaceAttrib *attrib_list,
> + unsigned int num_attribs);
> +VAStatus vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID
> config, VASurfaceAttrib *attrib_list,
> + unsigned int *num_attribs);
> #endif //VA_PRIVATE_H
> --
> 1.9.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20151023/5b6bcd62/attachment-0001.html>
More information about the mesa-dev
mailing list