summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhao halley <halley.zhao@intel.com>2012-05-31 17:00:28 +0800
committerXiang, Haihao <haihao.xiang@intel.com>2012-06-25 08:59:55 +0800
commitf1952f99b665037e4d5a9fb98eda95a797e0b9eb (patch)
treedc76624d2a867beea94420bd3cfa10409fd3c557
parent7392d3eeb86d28ac39b8e5490a775bb7a66cac76 (diff)
downloadvaapi-intel-driver-f1952f99b665037e4d5a9fb98eda95a797e0b9eb.tar.gz
vaapi-intel-driver-f1952f99b665037e4d5a9fb98eda95a797e0b9eb.tar.bz2
vaapi-intel-driver-f1952f99b665037e4d5a9fb98eda95a797e0b9eb.zip
add YUY2 format support in getimage/putimage
-rwxr-xr-xsrc/i965_drv_video.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index c6ca50e..02dfacc 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,
@@ -2107,6 +2108,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;
}
@@ -2343,7 +2350,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);
@@ -2516,6 +2524,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,
@@ -2639,6 +2668,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,
@@ -2668,6 +2736,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;
@@ -2695,6 +2766,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;
@@ -2739,6 +2814,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;
@@ -2906,6 +2982,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,
@@ -2957,7 +3076,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;
@@ -2985,6 +3104,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;
@@ -3034,13 +3156,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);