From 3ac4256d3aba3db757d086a7e7496d95cd8b0da4 Mon Sep 17 00:00:00 2001 From: "Li, Xiaowei A" Date: Tue, 27 Nov 2012 10:28:41 +0800 Subject: [PATCH] Fix H264 YUV400 surface render issue 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 --- src/gen6_mfd.c | 11 +++++++++++ src/gen75_mfd.c | 11 +++++++++++ src/i965_avc_bsd.c | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c index 25f74ad..11489dd 100755 --- a/src/gen6_mfd.c +++ b/src/gen6_mfd.c @@ -964,6 +964,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); diff --git a/src/gen75_mfd.c b/src/gen75_mfd.c index 2278a29..1b0857a 100644 --- a/src/gen75_mfd.c +++ b/src/gen75_mfd.c @@ -1260,6 +1260,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); diff --git a/src/i965_avc_bsd.c b/src/i965_avc_bsd.c index 8921275..5246c88 100644 --- a/src/i965_avc_bsd.c +++ b/src/i965_avc_bsd.c @@ -465,6 +465,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; -- 2.7.4