[Libva] [PATCH 3/4] Addin the implementation into i965_ouput_xv module.

ykzhao yakui.zhao at intel.com
Thu Sep 12 22:41:57 PDT 2013


On Thu, 2013-09-12 at 20:16 -0600, Ung, Teng En wrote:
> Signed-off-by: Ung, Teng En <teng.en.ung at intel.com>
> ---
>  src/i965_output_xv.c | 203 +++++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 198 insertions(+), 5 deletions(-)
> 
> diff --git a/src/i965_output_xv.c b/src/i965_output_xv.c
> index 8b361da..0138e99 100644
> --- a/src/i965_output_xv.c
> +++ b/src/i965_output_xv.c
> @@ -30,26 +30,92 @@
>  #include "i965_drv_video.h"
>  #include "i965_output_xv.h"
>  
> +#include "va_xv.h"
> +
> +#define NUM_VAXV_BUF     3
> +
>  struct va_xv_output {
>      int vaxv_port;
>      unsigned int vaxv_format;
> +    unsigned int vaxv_caps;
> +    int vaxv_format_index;
> +    
> +    int current_buf;
> +    VASurfaceID va_surf_id[NUM_VAXV_BUF];
> +};
> +
> +static struct vaxv_formats {
> +    unsigned int fourcc;
> +    unsigned int va_format;
> +    unsigned int subsample;
> +} vaxv_formats_list[] = {
> +    { VA_FOURCC('Y', 'U', 'Y', '2'), VA_RT_FORMAT_YUV422, SUBSAMPLE_YUV422H },
> +    { VA_FOURCC('U', 'Y', 'V', 'Y'), VA_RT_FORMAT_YUV422, SUBSAMPLE_YUV422H },
>  };
>  
> 
> +VAStatus
> +i965_DestroySurfaces(VADriverContextP ctx,
> +                     VASurfaceID *surface_list,
> +                     int num_surfaces);
> +VAStatus
> +i965_CreateSurfaces(VADriverContextP ctx,
> +                    int width,
> +                    int height,
> +                    int format,
> +                    int num_surfaces,
> +                    VASurfaceID *surfaces);
> +
> +static void i965_CreateVAXVBuffer(VADriverContextP ctx,
> +                                  struct va_xv_output *xv_output,
> +                                  int width,
> +                                  int height,
> +                                  int fmt_idx,
> +                                  int index)
> +{
> +    struct i965_driver_data *i965 = i965_driver_data(ctx);
> +    struct object_surface *obj_surface;
> +
> +    i965_CreateSurfaces(ctx, width, height, vaxv_formats_list[fmt_idx].va_format, 1, &xv_output->va_surf_id[index]);
> +    obj_surface = SURFACE(xv_output->va_surf_id[index]);
> +    i965_check_alloc_surface_bo(ctx, obj_surface, 0, vaxv_formats_list[fmt_idx].fourcc, vaxv_formats_list[fmt_idx].subsample);
> +}
> +
> +static void i965_DestroyVAXVBuffer(VADriverContextP ctx,
> +                                struct va_xv_output *xv_output,
> +                                int index)
> +{
> +    if (xv_output->va_surf_id[index] != 0) {
> +        i965_DestroySurfaces(ctx, &xv_output->va_surf_id[index], 1);
> +        xv_output->va_surf_id[index] = 0;
> +    }
> +}
> +
>  bool
>  i965_output_xv_init(VADriverContextP ctx)
>  {
>      struct i965_driver_data * const i965 = i965_driver_data(ctx);
> +    unsigned short major = 0, minor = 0;
> +    int port_id = 0;
> +
> +    if (va_xvQueryVersion(ctx, &major, &minor) != VA_XV_STATUS_SUCCESS)
> +        goto error;
> +
> +    if ((major != VAXV_MAJOR) || (minor != VAXV_MINOR))
> +        goto error;
>  
>      i965->xv_output = calloc(1, sizeof(struct va_xv_output));
>      if (!i965->xv_output) {
>          goto error;
> +    } else {
> +        i965->xv_output->vaxv_format_index = -1;
>      }
>  
> -    /* Need to addin implementation, currently just disable all those 
> -     * overlay and render attributes.
> -     */
> -    i965->num_display_attributes = 1;
> +    if ((va_xvFindAndReservePort(ctx, &port_id) != VA_XV_STATUS_SUCCESS) && 
> +        (!port_id)) 
> +        goto error;
> +
> +    i965->xv_output->vaxv_port = port_id;
>  
>      return true;
>  
> @@ -65,10 +131,23 @@ void
>  i965_output_xv_terminate(VADriverContextP ctx)
>  {
>      struct i965_driver_data * const i965 = i965_driver_data(ctx);
> +    struct va_xv_output * const xv_output = i965->xv_output;
> +    int i = 0;
>  
>      if (!xv_output)
>          return;
>  
> +    if (xv_output->vaxv_port) {
> +        va_xvFreePort(ctx, xv_output->vaxv_port);
> +        xv_output->vaxv_port = 0;
> +    }
> +
> +    for (i = 0; i < (NUM_VAXV_BUF - 1); ++i) {
> +        if (xv_output->va_surf_id[i]) {
> +             i965_DestroyVAXVBuffer(ctx, xv_output, i);
> +        }
> +    }
> +
>      free(xv_output);
>      i965->xv_output = NULL;
>  }
> @@ -87,6 +166,120 @@ i965_put_surface_xv(
>  {
>      struct i965_driver_data * const i965 = i965_driver_data(ctx);
>      struct va_xv_output * const xv_output = i965->xv_output;
> +    VARectangle dest_rect;
> +    struct i965_surface src_surface;
> +    struct i965_surface dst_surface;
> +    struct object_surface *obj_surface;
> +    int next, width, height, ret, i;
> +    va_xv_buf_t buf_out;
> +
> +    _i965LockMutex(&i965->render_mutex);
> +
> +    if (xv_output->current_buf >= (NUM_VAXV_BUF - 1)) {
> +        next = 0;
> +    } else {
> +        next = xv_output->current_buf;
> +        ++next;
> +    }
> +
> +    if (!xv_output->vaxv_format) {
> +        if (va_xvQueryPortFormat(ctx, xv_output->vaxv_port, &xv_output->vaxv_format)
> +            != VA_XV_STATUS_SUCCESS)
> +            goto error;
> +
> +        if (va_xvQueryPortCapabilities(ctx, xv_output->vaxv_port, &xv_output->vaxv_caps)
> +            != VA_XV_STATUS_SUCCESS)
> +            goto error;
> +
> +        if (xv_output->vaxv_format != VA_FOURCC('N', 'V', '1', '2')) {
> +            for (i = 0; i < ARRAY_ELEMS(vaxv_formats_list); ++i) {
> +                if (xv_output->vaxv_format == vaxv_formats_list[i].fourcc) break;
> +            }
> +            xv_output->vaxv_format_index = i;
> +        }
> +    }
> +
> +    if (xv_output->vaxv_format_index > -1) {
> +        /* Currently only support YUY2 buffer. */
> +        if (xv_output->vaxv_format_index >= ARRAY_ELEMS(vaxv_formats_list))
> +            goto error;
> +
> +        buf_out.pixel_format = vaxv_formats_list[xv_output->vaxv_format_index].fourcc;
> +
> +        /* Use the if statement, future may need more checkings for different formats */
> +        if (buf_out.pixel_format == VA_FOURCC('Y', 'U', 'Y', '2')) {
> +            width = ALIGN(dst_rect->width, 32);
> +            height = ALIGN(dst_rect->height, 2);
> +
> +            buf_out.pitches[0] = width * 2;
> +            buf_out.pitches[1] = buf_out.pitches[2] = 0;
> +
> +            buf_out.offsets[0] = buf_out.offsets[1] = buf_out.offsets[2] = 0;
> +        }
> +
> +        buf_out.buf_width = width;
> +        buf_out.buf_height = height;
> + 
> +        /* Create the surface buffer if it does not exist or different size.  We
> +         * are using triple buffering.
> +         */
> +        if (xv_output->va_surf_id[next]) {
> +            obj_surface = SURFACE(xv_output->va_surf_id[next]);
> +
> +            if ((obj_surface->orig_width != width) ||
> +                (obj_surface->orig_height != height)) {
> +                i965_DestroyVAXVBuffer(ctx, xv_output, next);
> +                i965_CreateVAXVBuffer(ctx, xv_output, width, height, xv_output->vaxv_format_index, next);
> +            }
> +        } else {
> +            i965_CreateVAXVBuffer(ctx, xv_output, width, height, xv_output->vaxv_format_index, next);
> +        }
> +
> +        obj_surface = SURFACE(surface);
> +        src_surface.base = (struct object_base *) obj_surface;
> +        src_surface.type = I965_SURFACE_TYPE_SURFACE;
> +        src_surface.flags = I965_SURFACE_FLAG_FRAME;
> +
> +        obj_surface = SURFACE(xv_output->va_surf_id[next]);
> +        dst_surface.base = (struct object_base *) obj_surface;
> +        dst_surface.type = I965_SURFACE_TYPE_SURFACE;
> +        dst_surface.flags = I965_SURFACE_FLAG_FRAME;
> +
> +        dest_rect.x = 0;
> +        dest_rect.y = 0;
> +
> +        /* Scale the image to output size. */
> +        dest_rect.width = dst_rect->width;
> +        dest_rect.height = dst_rect->height;
> +
> +        /* Use VPP features to convert and scale. */
> +        i965_image_processing(ctx,
> +                              &src_surface,
> +                              src_rect,
> +                              &dst_surface,
> +                              &dest_rect);
> +    } else {
> +        goto error;  /* Currently there is no direct support for NV12 */
> +    }
> +
> +    drm_intel_bo_flink(obj_surface->bo, &buf_out.buf_handle);

it seems that dri_bo_flink is more generic than the drm_intel_bo_flink.

> +
> +    ret = va_xvPutImage(ctx, xv_output->vaxv_port, draw, &buf_out,
> +                        dest_rect.x, dest_rect.y, dest_rect.width, dest_rect.height,
> +                        dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height, flags);
> +
> +    if (ret == VA_XV_STATUS_SUCCESS) {
> +       xv_output->current_buf = next;
> +    } else {
> +       goto error;
> +    }
> +
> +    _i965UnlockMutex(&i965->render_mutex);
> +
> +    return VA_STATUS_SUCCESS;
> +
> +error:
> +    _i965UnlockMutex(&i965->render_mutex);
>  
> -    return VA_STATUS_ERROR_UNIMPLEMENTED;
> +    return VA_STATUS_ERROR_UNKNOWN;
>  }




More information about the Libva mailing list