<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On 19 October 2015 at 16:55, Emil Velikov <span dir="ltr"><<a href="mailto:emil.l.velikov@gmail.com" target="_blank">emil.l.velikov@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 17 October 2015 at 00:14, Julien Isorce <<a href="mailto:julien.isorce@gmail.com">julien.isorce@gmail.com</a>> wrote:<br>
> Inspired from <a href="http://cgit.freedesktop.org/vaapi/intel-driver/tree/src/i965_drv_video.c" rel="noreferrer" target="_blank">http://cgit.freedesktop.org/vaapi/intel-driver/tree/src/i965_drv_video.c</a><br>
><br>
Please mention the actual usecase here and/or how you've tested this.<br></blockquote><div><br></div><div>Thx for the review.<br></div><div><br></div><div>All right I'll amend commit message that this is to support gstreamer-vaapi.<br></div><div>Also the first advantage to use VaCreateSurfaces2 over existing VaCreateSurfaces, is that you can select which pixel format you want for the surface. Pixel format that you can query with new function: <span class="">vlVaQuerySurfaceAttributes</span></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
> Signed-off-by: Julien Isorce <<a href="mailto:j.isorce@samsung.com">j.isorce@samsung.com</a>><br>
> ---<br>
>  src/gallium/state_trackers/va/context.c    |   5 +-<br>
>  src/gallium/state_trackers/va/surface.c    | 288 ++++++++++++++++++++++++-----<br>
>  src/gallium/state_trackers/va/va_private.h |   7 +<br>
>  3 files changed, 249 insertions(+), 51 deletions(-)<br>
><br>
> diff --git a/src/gallium/state_trackers/va/context.c b/src/gallium/state_trackers/va/context.c<br>
> index 8b003ae..8949d42 100644<br>
> --- a/src/gallium/state_trackers/va/context.c<br>
> +++ b/src/gallium/state_trackers/va/context.c<br>
> @@ -81,7 +81,10 @@ static struct VADriverVTable vtable =<br>
>     &vlVaSetDisplayAttributes,<br>
>     &vlVaBufferInfo,<br>
>     &vlVaLockSurface,<br>
> -   &vlVaUnlockSurface<br>
> +   &vlVaUnlockSurface,<br>
> +   &vlVaGetSurfaceAttributes,<br>
> +   &vlVaCreateSurfaces2,<br>
> +   &vlVaQuerySurfaceAttributes<br>
>  };<br>
><br>
>  PUBLIC VAStatus<br>
> diff --git a/src/gallium/state_trackers/va/surface.c b/src/gallium/state_trackers/va/surface.c<br>
> index 8d4487b..be435cb 100644<br>
> --- a/src/gallium/state_trackers/va/surface.c<br>
> +++ b/src/gallium/state_trackers/va/surface.c<br>
> @@ -29,6 +29,8 @@<br>
>  #include "pipe/p_screen.h"<br>
>  #include "pipe/p_video_codec.h"<br>
><br>
> +#include "state_tracker/drm_driver.h"<br>
> +<br>
>  #include "util/u_memory.h"<br>
>  #include "util/u_handle_table.h"<br>
>  #include "util/u_rect.h"<br>
> @@ -36,6 +38,7 @@<br>
>  #include "util/u_surface.h"<br>
><br>
>  #include "vl/vl_compositor.h"<br>
> +#include "vl/vl_video_buffer.h"<br>
>  #include "vl/vl_winsys.h"<br>
><br>
>  #include "va_private.h"<br>
> @@ -44,56 +47,8 @@ VAStatus<br>
>  vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int format,<br>
>                     int num_surfaces, VASurfaceID *surfaces)<br>
>  {<br>
> -   struct pipe_video_buffer templat = {};<br>
> -   struct pipe_screen *pscreen;<br>
> -   vlVaDriver *drv;<br>
> -   int i;<br>
> -<br>
> -   if (!ctx)<br>
> -      return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
> -<br>
> -   if (!(width && height))<br>
> -      return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;<br>
> -<br>
> -   drv = VL_VA_DRIVER(ctx);<br>
> -   pscreen = VL_VA_PSCREEN(ctx);<br>
> -<br>
> -   templat.buffer_format = pscreen->get_video_param<br>
> -   (<br>
> -      pscreen,<br>
> -      PIPE_VIDEO_PROFILE_UNKNOWN,<br>
> -      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,<br>
> -      PIPE_VIDEO_CAP_PREFERED_FORMAT<br>
> -   );<br>
> -   templat.chroma_format = ChromaToPipe(format);<br>
> -   templat.width = width;<br>
> -   templat.height = height;<br>
> -   templat.interlaced = pscreen->get_video_param<br>
> -   (<br>
> -      pscreen,<br>
> -      PIPE_VIDEO_PROFILE_UNKNOWN,<br>
> -      PIPE_VIDEO_ENTRYPOINT_BITSTREAM,<br>
> -      PIPE_VIDEO_CAP_PREFERS_INTERLACED<br>
> -   );<br>
> -<br>
> -   for (i = 0; i < num_surfaces; ++i) {<br>
> -      vlVaSurface *surf = CALLOC(1, sizeof(vlVaSurface));<br>
> -      if (!surf)<br>
> -         goto no_res;<br>
> -<br>
> -      surf->templat = templat;<br>
> -      surf->buffer = drv->pipe->create_video_buffer(drv->pipe, &templat);<br>
> -      util_dynarray_init(&surf->subpics);<br>
> -      surfaces[i] = handle_table_add(drv->htab, surf);<br>
> -   }<br>
> -<br>
> -   return VA_STATUS_SUCCESS;<br>
> -<br>
> -no_res:<br>
> -   if (i)<br>
> -      vlVaDestroySurfaces(ctx, surfaces, i);<br>
> -<br>
> -   return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
> +    return vlVaCreateSurfaces2(ctx, format, width, height, surfaces, num_surfaces,<br>
> +                               NULL, 0);<br>
>  }<br>
><br>
>  VAStatus<br>
> @@ -349,3 +304,236 @@ vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface)<br>
><br>
>     return VA_STATUS_ERROR_UNIMPLEMENTED;<br>
>  }<br>
> +<br>
> +VAStatus<br>
> +vlVaGetSurfaceAttributes(VADriverContextP ctx, VAConfigID config,<br>
> +                         VASurfaceAttrib *attrib_list, unsigned int num_attribs)<br>
> +{<br>
> +    return VA_STATUS_ERROR_UNIMPLEMENTED; /* DEPRECATED */<br>
> +}<br>
</div></div>Hmm implemented only to return ENOIMPL. Why ?<br></blockquote><div><br></div><div>2 reasons, first that I do not know how to set it in "VADriverVTable vtable" otherwise, mhh actually maybe I can just set NULL in place of "&vlVaGetSurfaceAttributes" :) libva indeed checks for its presence. And also to make it clear in mesa st/va  code that this function is deprecated, see libva/va_backend.h. It is replaced by <span class="">VaQuerySurfaceAttributes.</span></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<span class=""><br>
> +<br>
> +VAStatus<br>
> +vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config,<br>
> +                           VASurfaceAttrib *attrib_list, unsigned int *num_attribs)<br>
> +{<br>
> +    VAStatus vaStatus = VA_STATUS_SUCCESS;<br>
> +    vlVaDriver *drv = NULL;<br>
> +    VASurfaceAttrib *attribs = NULL;<br>
> +    struct pipe_screen *pscreen = NULL;<br>
> +    int i = 0;<br>
> +<br>
</span>You don't need most of these variable initializers. st/va doesn't seem<br>
to follow this approach either.<br>
<span class=""><br></span></blockquote><div>ok <br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
> +    if (config == VA_INVALID_ID)<br>
> +        return VA_STATUS_ERROR_INVALID_CONFIG;<br>
> +<br>
> +    if (!attrib_list && !num_attribs)<br>
> +        return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
> +<br>
> +    if (attrib_list == NULL) {<br>
> +        *num_attribs = VASurfaceAttribCount;<br>
> +        return VA_STATUS_SUCCESS;<br>
> +    }<br>
> +<br>
> +    attribs = CALLOC(VASurfaceAttribCount, sizeof(VASurfaceAttrib));<br>
> +<br>
> +    if (attribs == NULL)<br>
> +        return VA_STATUS_ERROR_ALLOCATION_FAILED;<br>
> +<br>
</span>Push the calloc/check further down, where it's needed ? Otherwise you<br>
leak on the memory on the next three return statements.<br></blockquote><div><br></div><div>I see, thx.<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
> +    if (!ctx)<br>
> +       return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
> +<br>
> +    drv = VL_VA_DRIVER(ctx);<br>
> +<br>
> +    if (!drv)<br>
> +        return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
> +<br>
> +    pscreen = VL_VA_PSCREEN(ctx);<br>
> +<br>
> +    if (!pscreen)<br>
> +       return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
> +<br>
> +    if (config == PIPE_VIDEO_PROFILE_UNKNOWN) {<br>
> +       /* Assume VAEntrypointVideoProc for now. */<br>
> +       attribs[i].type = VASurfaceAttribPixelFormat;<br>
> +       attribs[i].value.type = VAGenericValueTypeInteger;<br>
> +       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
> +       attribs[i].value.value.i = VA_FOURCC_BGRA;<br>
> +       i++;<br>
> +<br>
> +       attribs[i].type = VASurfaceAttribPixelFormat;<br>
> +       attribs[i].value.type = VAGenericValueTypeInteger;<br>
> +       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
> +       attribs[i].value.value.i = VA_FOURCC_RGBA;<br>
> +       i++;<br>
> +    } else {<br>
> +       /* Assume VAEntrypointVLD for now. */<br>
> +       attribs[i].type = VASurfaceAttribPixelFormat;<br>
> +       attribs[i].value.type = VAGenericValueTypeInteger;<br>
> +       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
> +       attribs[i].value.value.i = VA_FOURCC_NV12;<br>
> +       i++;<br>
> +    }<br>
> +<br>
> +    attribs[i].type = VASurfaceAttribMemoryType;<br>
> +    attribs[i].value.type = VAGenericValueTypeInteger;<br>
> +    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;<br>
> +    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA;<br>
> +    i++;<br>
> +<br>
> +    attribs[i].type = VASurfaceAttribExternalBufferDescriptor;<br>
> +    attribs[i].value.type = VAGenericValueTypePointer;<br>
> +    attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;<br>
> +    attribs[i].value.value.p = NULL; /* ignore */<br>
> +    i++;<br>
> +<br>
> +    attribs[i].type = VASurfaceAttribMaxWidth;<br>
> +    attribs[i].value.type = VAGenericValueTypeInteger;<br>
> +    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;<br>
> +    attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);<br>
> +    i++;<br>
> +<br>
> +    attribs[i].type = VASurfaceAttribMaxHeight;<br>
> +    attribs[i].value.type = VAGenericValueTypeInteger;<br>
> +    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;<br>
> +    attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);<br>
> +    i++;<br>
> +<br>
> +    if (i > *num_attribs) {<br>
> +        *num_attribs = i;<br>
> +        FREE(attribs);<br>
> +        return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;<br>
> +    }<br>
> +<br>
> +    *num_attribs = i;<br>
> +    memcpy(attrib_list, attribs, i * sizeof(VASurfaceAttrib));<br>
> +    FREE(attribs);<br>
> +<br>
> +    return vaStatus;<br>
> +}<br>
> +<br>
> +VAStatus<br>
> +vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,<br>
> +                    unsigned int width, unsigned int height,<br>
> +                    VASurfaceID *surfaces, unsigned int num_surfaces,<br>
> +                    VASurfaceAttrib *attrib_list, unsigned int num_attribs)<br>
> +{<br>
> +    vlVaDriver *drv = NULL;<br>
> +    VASurfaceAttribExternalBuffers *memory_attibute = NULL;<br>
> +    VAStatus vaStatus = VA_STATUS_SUCCESS;<br>
> +    struct pipe_video_buffer templat = {};<br>
> +    struct pipe_screen *pscreen = NULL;<br>
> +    int memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;<br>
> +    int expected_fourcc = 0;<br>
> +    int i = 0;<br>
> +<br>
</div></div>Please drop the initializers, unless needed.<br></blockquote><div><br></div><div>ok<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div><div class="h5"><br>
> +    if (!ctx)<br>
> +       return VA_STATUS_ERROR_INVALID_CONTEXT;<br>
> +<br>
> +    if (!(width && height))<br>
> +       return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;<br>
> +<br>
> +    drv = VL_VA_DRIVER(ctx);<br>
> +    pscreen = VL_VA_PSCREEN(ctx);<br>
> +<br>
> +    for (i = 0; i < num_attribs && attrib_list; i++) {<br>
> +        if ((attrib_list[i].type == VASurfaceAttribPixelFormat) &&<br>
> +            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {<br>
> +            if (attrib_list[i].value.type != VAGenericValueTypeInteger)<br>
> +                return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
> +            expected_fourcc = attrib_list[i].value.value.i;<br>
> +        }<br>
> +<br>
> +        if ((attrib_list[i].type == VASurfaceAttribMemoryType) &&<br>
> +            (attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE)) {<br>
> +<br>
> +            if (attrib_list[i].value.type != VAGenericValueTypeInteger)<br>
> +                return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
> +<br>
> +            switch (attrib_list[i].value.value.i) {<br>
> +                case VA_SURFACE_ATTRIB_MEM_TYPE_VA:<br>
> +                default:{<br>
> +                    return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;}<br>
> +            }<br>
> +        }<br>
> +<br>
> +        if ((attrib_list[i].type == VASurfaceAttribExternalBufferDescriptor) &&<br>
> +            (attrib_list[i].flags == VA_SURFACE_ATTRIB_SETTABLE)) {<br>
> +            if (attrib_list[i].value.type != VAGenericValueTypePointer)<br>
> +                return VA_STATUS_ERROR_INVALID_PARAMETER;<br>
> +            memory_attibute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;<br>
> +        }<br>
> +    }<br>
> +<br>
> +    /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used<br>
> +     * for post-processing (including color conversion) */<br>
> +    if (VA_RT_FORMAT_YUV420 != format &&<br>
> +        VA_RT_FORMAT_YUV422 != format &&<br>
> +        VA_RT_FORMAT_YUV444 != format &&<br>
> +        VA_RT_FORMAT_YUV411 != format &&<br>
> +        VA_RT_FORMAT_YUV400 != format &&<br>
</div></div>We don't have any support for 400 or 411. Why are they in the list ?<br></blockquote><div><br>Just a copy past, oups :)<br><br></div><div>Thx<br></div><div>Julien<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Cheers,<br>
Emil<br>
</blockquote></div><br></div></div>