On 17 October 2015 at 00:14, Julien Isorce <julien.iso...@gmail.com> wrote: > Inspired from > http://cgit.freedesktop.org/vaapi/intel-driver/tree/src/i965_drv_video.c > Please mention the actual usecase here and/or how you've tested this.
> Signed-off-by: Julien Isorce <j.iso...@samsung.com> > --- > src/gallium/state_trackers/va/context.c | 5 +- > src/gallium/state_trackers/va/surface.c | 288 > ++++++++++++++++++++++++----- > src/gallium/state_trackers/va/va_private.h | 7 + > 3 files changed, 249 insertions(+), 51 deletions(-) > > diff --git a/src/gallium/state_trackers/va/context.c > b/src/gallium/state_trackers/va/context.c > index 8b003ae..8949d42 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, > + &vlVaGetSurfaceAttributes, > + &vlVaCreateSurfaces2, > + &vlVaQuerySurfaceAttributes > }; > > PUBLIC VAStatus > diff --git a/src/gallium/state_trackers/va/surface.c > b/src/gallium/state_trackers/va/surface.c > index 8d4487b..be435cb 100644 > --- a/src/gallium/state_trackers/va/surface.c > +++ b/src/gallium/state_trackers/va/surface.c > @@ -29,6 +29,8 @@ > #include "pipe/p_screen.h" > #include "pipe/p_video_codec.h" > > +#include "state_tracker/drm_driver.h" > + > #include "util/u_memory.h" > #include "util/u_handle_table.h" > #include "util/u_rect.h" > @@ -36,6 +38,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 +47,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 +304,236 @@ vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID > surface) > > return VA_STATUS_ERROR_UNIMPLEMENTED; > } > + > +VAStatus > +vlVaGetSurfaceAttributes(VADriverContextP ctx, VAConfigID config, > + VASurfaceAttrib *attrib_list, unsigned int > num_attribs) > +{ > + return VA_STATUS_ERROR_UNIMPLEMENTED; /* DEPRECATED */ > +} Hmm implemented only to return ENOIMPL. Why ? > + > +VAStatus > +vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config, > + VASurfaceAttrib *attrib_list, unsigned int > *num_attribs) > +{ > + VAStatus vaStatus = VA_STATUS_SUCCESS; > + vlVaDriver *drv = NULL; > + VASurfaceAttrib *attribs = NULL; > + struct pipe_screen *pscreen = NULL; > + int i = 0; > + You don't need most of these variable initializers. st/va doesn't seem to follow this approach either. > + 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 == NULL) { > + *num_attribs = VASurfaceAttribCount; > + return VA_STATUS_SUCCESS; > + } > + > + attribs = CALLOC(VASurfaceAttribCount, sizeof(VASurfaceAttrib)); > + > + if (attribs == NULL) > + return VA_STATUS_ERROR_ALLOCATION_FAILED; > + Push the calloc/check further down, where it's needed ? Otherwise you leak on the memory on the next three return statements. > + 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; > + > + 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 vaStatus; > +} > + > +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 = NULL; > + VASurfaceAttribExternalBuffers *memory_attibute = NULL; > + VAStatus vaStatus = VA_STATUS_SUCCESS; > + struct pipe_video_buffer templat = {}; > + struct pipe_screen *pscreen = NULL; > + int memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA; > + int expected_fourcc = 0; > + int i = 0; > + Please drop the initializers, unless needed. > + 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); > + > + 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: > + 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; > + } > + } > + > + /* support 420 & 422 & RGB32 format, 422 and RGB32 are only used > + * for post-processing (including color conversion) */ > + if (VA_RT_FORMAT_YUV420 != format && > + VA_RT_FORMAT_YUV422 != format && > + VA_RT_FORMAT_YUV444 != format && > + VA_RT_FORMAT_YUV411 != format && > + VA_RT_FORMAT_YUV400 != format && We don't have any support for 400 or 411. Why are they in the list ? Cheers, Emil _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev