Fix H264 YUV400 surface render issue
authorLi, Xiaowei A <xiaowei.a.li@intel.com>
Tue, 27 Nov 2012 02:28:41 +0000 (10:28 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Fri, 14 Dec 2012 05:24:10 +0000 (13:24 +0800)
All decoded frame are considered as NV12 format in driver's,
for YUV400 format senerios, we need set the chroma component
of NV12 to a constant value(0x80), otherwise the converted ARGB
from NV12 format is not correct and cause render issue.

Signed-off-by: Li Xiaowei <xiaowei.a.li@intel.com>
(cherry picked from commit 3ac4256d3aba3db757d086a7e7496d95cd8b0da4)

src/gen6_mfd.c
src/gen75_mfd.c
src/i965_avc_bsd.c

index 9c110c6..1eb75e4 100755 (executable)
@@ -926,6 +926,17 @@ gen6_mfd_avc_decode_init(VADriverContextP ctx,
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
+
+    /* initial uv component for YUV400 case */
+    if (pic_param->seq_fields.bits.chroma_format_idc == 0) {
+         unsigned int uv_offset = obj_surface->width * obj_surface->height; 
+         unsigned int uv_size   = obj_surface->width * obj_surface->height / 2; 
+
+         drm_intel_gem_bo_map_gtt(obj_surface->bo);
+         memset(obj_surface->bo->virtual + uv_offset, 0x80, uv_size);
+         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
+    }
+
     gen6_mfd_init_avc_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen6_mfd_context->post_deblocking_output.bo);
index 78cb73b..82d9955 100644 (file)
@@ -1216,6 +1216,17 @@ gen75_mfd_avc_decode_init(VADriverContextP ctx,
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
     i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
+
+    /* initial uv component for YUV400 case */
+    if (pic_param->seq_fields.bits.chroma_format_idc == 0) {
+         unsigned int uv_offset = obj_surface->width * obj_surface->height; 
+         unsigned int uv_size   = obj_surface->width * obj_surface->height / 2; 
+
+         drm_intel_gem_bo_map_gtt(obj_surface->bo);
+         memset(obj_surface->bo->virtual + uv_offset, 0x80, uv_size);
+         drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
+    }
+
     gen75_mfd_init_avc_surface(ctx, pic_param, obj_surface);
 
     dri_bo_unreference(gen7_mfd_context->post_deblocking_output.bo);
index a118076..77bc221 100644 (file)
@@ -468,6 +468,17 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
     obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
     i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
+
+    /* initial uv component for YUV400 case */
+    if (pic_param->seq_fields.bits.chroma_format_idc == 0) {
+         unsigned int uv_offset = obj_surface->width * obj_surface->height; 
+         unsigned int uv_size   = obj_surface->width * obj_surface->height / 2; 
+
+         dri_bo_map(obj_surface->bo, 1);
+         memset(obj_surface->bo->virtual + uv_offset, 0x80, uv_size);
+         dri_bo_unmap(obj_surface->bo);
+    }
+
     i965_avc_bsd_init_avc_bsd_surface(ctx, obj_surface, pic_param, i965_h264_context);
     avc_bsd_surface = obj_surface->private_data;