[Libva] [PATCH 5/6 v2] add YUY2 format support in getimage/putimage

Zhao halley halley.zhao at intel.com
Thu May 31 02:00:28 PDT 2012


---
 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);
-- 
1.7.5.4



More information about the Libva mailing list