[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