On Thu, 2013-09-19 at 16:07 +0800, Ung, Teng En wrote: > Signed-off-by: Ung, Teng En <teng.en....@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) {
The invalid id for VA surface is VA_INVALID_SURFACE (the alias of VA_INVALID_ID) > + 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; We will add other display attributes in the future, the setting of i965->num_display_attributes in the error path will disable all attributes except the first attribute. It would be better to refine the first patch to fix it. > + 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; width/height aren't initialized for UYVY. > + > + /* Create the surface buffer if it does not exist or different size. > We > + * are using triple buffering. > + */ > + if (xv_output->va_surf_id[next]) { Should check xv_output->va_surf_id[next] against VA_INVALID_SURFACE > + 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); > + > + 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; > } _______________________________________________ Libva mailing list Libva@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libva