[Libva] [PATCH 3/4] Addin the implementation into i965_ouput_xv module.
Ung, Teng En
teng.en.ung at intel.com
Mon Sep 16 21:04:20 PDT 2013
>> + 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.
Hi Yakui
Thanks for reviewing this. Using drm_intel_bo_flink because thinking the driver are more intel specific. Anyway, dri_bo_flink is more generic though.
Thanks
Teng
-----Original Message-----
From: Zhao, Yakui
Sent: Friday, September 13, 2013 1:42 PM
To: Ung, Teng En
Cc: libva at lists.freedesktop.org
Subject: Re: [Libva] [PATCH 3/4] Addin the implementation into i965_ouput_xv module.
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