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

Xiang, Haihao haihao.xiang at intel.com
Wed May 30 22:46:29 PDT 2012


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