[Libva] [PATCH 5/6] add YUY2 format support in getimage/putimage
Zhao, Halley
halley.zhao at intel.com
Thu May 31 01:32:18 PDT 2012
I just did some unit test, it works well.
Thanks for your reminder.
> -----Original Message-----
> From: Xiang, Haihao
> Sent: Thursday, May 31, 2012 1:46 PM
> To: Zhao, Halley
> Cc: libva at lists.freedesktop.org
> Subject: Re: [Libva] [PATCH 5/6] add YUY2 format support in
> getimage/putimage
>
>
> The software path for getimage/putimage on SNB is disabled, are you
> sure it really work ?
>
> Thanks
> Haihao
>
>
> > ---
> > src/i965_drv_video.c | 129
> > ++++++++++++++++++++++++++++++++++++++++++++++++-
> > 1 files changed, 126 insertions(+), 3 deletions(-)
> >
> > diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c index
> > 519d8a3..fdf517b 100755
> > --- a/src/i965_drv_video.c
> > +++ b/src/i965_drv_video.c
> > @@ -84,6 +84,7 @@
> >
> > IS_GEN7((ctx)->intel.device_id))
> >
> > #define HAS_ACCELERATED_PUTIMAGE(ctx) HAS_VPP(ctx)
> > +static int get_sampling_from_fourcc(unsigned int fourcc);
> >
> > enum {
> > I965_SURFACETYPE_RGBA = 1,
> > @@ -2051,6 +2052,12 @@ i965_CreateImage(VADriverContextP ctx,
> > image->offsets[1] = size;
> > image->data_size = size + 2 * size2;
> > break;
> > + case VA_FOURCC('Y','U','Y','2'):
> > + image->num_planes = 1;
> > + image->pitches[0] = width * 2;
> > + image->offsets[0] = 0;
> > + image->data_size = size * 2;
> > + break;
> > default:
> > goto error;
> > }
> > @@ -2287,7 +2294,8 @@ VAStatus i965_DeriveImage(VADriverContextP ctx,
> > unsigned int is_tiled = 0;
> > unsigned int fourcc = VA_FOURCC('Y', 'V', '1', '2');
> > i965_guess_surface_format(ctx, surface, &fourcc, &is_tiled);
> > - i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled,
> fourcc, SUBSAMPLE_YUV420);
> > + int sampling = get_sampling_from_fourcc(fourcc);
> > + i965_check_alloc_surface_bo(ctx, obj_surface, is_tiled,
> > + fourcc, sampling);
> > }
> >
> > assert(obj_surface->fourcc);
> > @@ -2460,6 +2468,27 @@ i965_SetImagePalette(VADriverContextP ctx,
> > return VA_STATUS_SUCCESS;
> > }
> >
> > +static int
> > +get_sampling_from_fourcc(unsigned int fourcc) {
> > + int surface_sampling = -1;
> > + switch (fourcc) {
> > + case VA_FOURCC('N', 'V', '1', '2'):
> > + case VA_FOURCC('Y', 'V', '1', '2'):
> > + case VA_FOURCC('I', '4', '2', '0'):
> > + case VA_FOURCC('I', 'M', 'C', '1'):
> > + case VA_FOURCC('I', 'M', 'C', '3'):
> > + surface_sampling = SUBSAMPLE_YUV420;
> > + break;
> > + case VA_FOURCC('Y', 'U', 'Y', '2'):
> > + surface_sampling = SUBSAMPLE_YUV422H;
> > + break;
> > + default:
> > + break;
> > + }
> > + return surface_sampling;
> > +}
> > +
> > static inline void
> > memcpy_pic(uint8_t *dst, unsigned int dst_stride,
> > const uint8_t *src, unsigned int src_stride, @@ -2583,6
> > +2612,45 @@ get_image_nv12(struct object_image *obj_image, uint8_t
> *image_data,
> > dri_bo_unmap(obj_surface->bo); }
> >
> > +static void
> > +get_image_yuy2(struct object_image *obj_image, uint8_t *image_data,
> > + struct object_surface *obj_surface,
> > + const VARectangle *rect) {
> > + uint8_t *dst, *src;
> > + unsigned int tiling, swizzle;
> > +
> > + if (!obj_surface->bo)
> > + return;
> > +
> > + assert(obj_surface->fourcc);
> > + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
> > +
> > + if (tiling != I915_TILING_NONE)
> > + drm_intel_gem_bo_map_gtt(obj_surface->bo);
> > + else
> > + dri_bo_map(obj_surface->bo, 0);
> > +
> > + if (!obj_surface->bo->virtual)
> > + return;
> > +
> > + /* Both dest VA image and source surface have YUYV format */
> > + dst = image_data + obj_image->image.offsets[0];
> > + src = (uint8_t *)obj_surface->bo->virtual;
> > +
> > + /* Y plane */
> > + dst += rect->y * obj_image->image.pitches[0] + rect->x*2;
> > + src += rect->y * obj_surface->width + rect->x*2;
> > + memcpy_pic(dst, obj_image->image.pitches[0],
> > + src, obj_surface->width*2,
> > + rect->width*2, rect->height);
> > +
> > + if (tiling != I915_TILING_NONE)
> > + drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
> > + else
> > + dri_bo_unmap(obj_surface->bo); }
> > +
> > static VAStatus
> > i965_sw_getimage(VADriverContextP ctx,
> > VASurfaceID surface, @@ -2612,6 +2680,9 @@
> > i965_sw_getimage(VADriverContextP ctx,
> > y + height > obj_image->image.height)
> > return VA_STATUS_ERROR_INVALID_PARAMETER;
> >
> > + if (obj_surface->fourcc != obj_image->image.format.fourcc)
> > + return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
> > +
> > VAStatus va_status;
> > void *image_data = NULL;
> >
> > @@ -2639,6 +2710,10 @@ i965_sw_getimage(VADriverContextP ctx,
> > goto operation_failed;
> > get_image_nv12(obj_image, image_data, obj_surface, &rect);
> > break;
> > + case VA_FOURCC('Y','U','Y','2'):
> > + /* YUY2 is the format supported by overlay plane */
> > + get_image_yuy2(obj_image, image_data, obj_surface, &rect);
> > + break;
> > default:
> > operation_failed:
> > va_status = VA_STATUS_ERROR_OPERATION_FAILED; @@ -2683,6
> > +2758,7 @@ i965_hw_getimage(VADriverContextP ctx,
> >
> > if (!obj_surface->bo)
> > return VA_STATUS_SUCCESS;
> > + assert(obj_image->bo); // image bo is always created, see
> > + i965_CreateImage()
> >
> > rect.x = x;
> > rect.y = y;
> > @@ -2850,6 +2926,49 @@ put_image_nv12(struct object_surface
> *obj_surface,
> > dri_bo_unmap(obj_surface->bo); }
> >
> > +static void
> > +put_image_yuy2(struct object_surface *obj_surface,
> > + const VARectangle *dst_rect,
> > + struct object_image *obj_image, uint8_t *image_data,
> > + const VARectangle *src_rect) {
> > + uint8_t *dst, *src;
> > + unsigned int tiling, swizzle;
> > +
> > + if (!obj_surface->bo)
> > + return;
> > +
> > + assert(obj_surface->fourcc);
> > + assert(dst_rect->width == src_rect->width);
> > + assert(dst_rect->height == src_rect->height);
> > + dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
> > +
> > + if (tiling != I915_TILING_NONE)
> > + drm_intel_gem_bo_map_gtt(obj_surface->bo);
> > + else
> > + dri_bo_map(obj_surface->bo, 0);
> > +
> > + if (!obj_surface->bo->virtual)
> > + return;
> > +
> > + /* Both dest VA image and source surface have YUY2 format */
> > + dst = (uint8_t *)obj_surface->bo->virtual;
> > + src = image_data + obj_image->image.offsets[0];
> > +
> > + /* YUYV packed plane */
> > + dst += dst_rect->y * obj_surface->width + dst_rect->x*2;
> > + src += src_rect->y * obj_image->image.pitches[0] + src_rect->x*2;
> > + memcpy_pic(dst, obj_surface->width*2,
> > + src, obj_image->image.pitches[0],
> > + src_rect->width*2, src_rect->height);
> > +
> > + if (tiling != I915_TILING_NONE)
> > + drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
> > + else
> > + dri_bo_unmap(obj_surface->bo); }
> > +
> > +
> > static VAStatus
> > i965_sw_putimage(VADriverContextP ctx,
> > VASurfaceID surface, @@ -2901,7 +3020,7 @@
> > i965_sw_putimage(VADriverContextP ctx,
> > obj_surface,
> > 0, /* XXX: don't use tiled surface */
> > obj_image->image.format.fourcc,
> > - SUBSAMPLE_YUV420);
> > + get_sampling_from_fourcc
> > + (obj_image->image.format.fourcc));
> > }
> >
> > VAStatus va_status;
> > @@ -2929,6 +3048,9 @@ i965_sw_putimage(VADriverContextP ctx,
> > case VA_FOURCC('N','V','1','2'):
> > put_image_nv12(obj_surface, &dest_rect, obj_image,
> image_data, &src_rect);
> > break;
> > + case VA_FOURCC('Y','U','Y','2'):
> > + put_image_yuy2(obj_surface, &dest_rect, obj_image,
> image_data, &src_rect);
> > + break;
> > default:
> > va_status = VA_STATUS_ERROR_OPERATION_FAILED;
> > break;
> > @@ -2978,13 +3100,14 @@ i965_hw_putimage(VADriverContextP ctx,
> >
> > if (!obj_surface->bo) {
> > unsigned int tiling, swizzle;
> > + int surface_sampling = get_sampling_from_fourcc
> > + (obj_image->image.format.fourcc);;
> > dri_bo_get_tiling(obj_image->bo, &tiling, &swizzle);
> >
> > i965_check_alloc_surface_bo(ctx,
> > obj_surface,
> > !!tiling,
> > obj_image->image.format.fourcc,
> > - SUBSAMPLE_YUV420);
> > + surface_sampling);
> > }
> >
> > assert(obj_surface->fourcc);
>
More information about the Libva
mailing list