From c2958105d075fd0f91cea8b684703fe5a418a004 Mon Sep 17 00:00:00 2001 From: Jian Cao Date: Fri, 17 May 2019 22:39:59 +0800 Subject: [PATCH] ge2d: add option for rgb_to_yuv to 709 or 601 [1/1] PD#OTT-3711 Problem: color parameters are wrong while displaying images on NativeImagePlayer Solution: add a macro BT_STANDARD for 709 or 601 Verify: verified on W400 Change-Id: I0703ef17748c8267b86e85a4366cac88d3e41ee1 Signed-off-by: Jian Cao --- drivers/amlogic/media/common/ge2d/ge2d_hw.c | 50 ++++++++++++++-------- drivers/amlogic/media/common/ge2d/ge2dgen.c | 6 +++ .../amlogic/media/video_processor/pic_dev/picdec.c | 33 +++++++++----- include/linux/amlogic/media/ge2d/ge2d.h | 15 +++++-- 4 files changed, 73 insertions(+), 31 deletions(-) diff --git a/drivers/amlogic/media/common/ge2d/ge2d_hw.c b/drivers/amlogic/media/common/ge2d/ge2d_hw.c index 85d5657..ad0a01d 100644 --- a/drivers/amlogic/media/common/ge2d/ge2d_hw.c +++ b/drivers/amlogic/media/common/ge2d/ge2d_hw.c @@ -624,7 +624,7 @@ void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg) ); } else ge2d_reg_set_bits(GE2D_ANTIFLICK_CTRL0, 0, 31, 1); - if (cfg->use_matrix_default == MATRIX_YCC_TO_RGB) { + if (cfg->use_matrix_default & MATRIX_YCC_TO_RGB) { /* ycbcr(16-235) to rgb(0-255) */ cfg->matrix_coef[0] = 0x4a8; cfg->matrix_coef[1] = 0; @@ -641,27 +641,43 @@ void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg) cfg->matrix_sat_in_en = 1; cfg->matrix_minus_16_ctrl = 0x4; cfg->matrix_sign_ctrl = 0x3; - } else if (cfg->use_matrix_default == MATRIX_RGB_TO_YCC) { - /* rgb(0-255) to ycbcr(16-235) */ - /* 0.257 0.504 0.098 */ - /* -0.148 -0.291 0.439 */ - /* 0.439 -0.368 -0.071 */ - cfg->matrix_coef[0] = 0x107; - cfg->matrix_coef[1] = 0x204; - cfg->matrix_coef[2] = 0x64; - cfg->matrix_coef[3] = 0x1f68; - cfg->matrix_coef[4] = 0x1ed6; - cfg->matrix_coef[5] = 0x1c2; - cfg->matrix_coef[6] = 0x1c2; - cfg->matrix_coef[7] = 0x1e87; - cfg->matrix_coef[8] = 0x1fb7; + } else if (cfg->use_matrix_default & MATRIX_RGB_TO_YCC) { + if (cfg->use_matrix_default & MATRIX_BT_709) { + /* VDIN_MATRIX_RGB_YUV709 */ + /* 0 0.183 0.614 0.062 16 */ + /* 0 -0.101 -0.338 0.439 128 */ + /* 0 0.439 -0.399 -0.04 128 */ + cfg->matrix_coef[0] = 0xbb; + cfg->matrix_coef[1] = 0x275; + cfg->matrix_coef[2] = 0x3f; + cfg->matrix_coef[3] = 0x1f99; + cfg->matrix_coef[4] = 0x1ea6; + cfg->matrix_coef[5] = 0x1c2; + cfg->matrix_coef[6] = 0x1c2; + cfg->matrix_coef[7] = 0x1e67; + cfg->matrix_coef[8] = 0x1fd7; + } else { + /* rgb(0-255) to ycbcr(16-235) */ + /* 0.257 0.504 0.098 */ + /* -0.148 -0.291 0.439 */ + /* 0.439 -0.368 -0.071 */ + cfg->matrix_coef[0] = 0x107; + cfg->matrix_coef[1] = 0x204; + cfg->matrix_coef[2] = 0x64; + cfg->matrix_coef[3] = 0x1f68; + cfg->matrix_coef[4] = 0x1ed6; + cfg->matrix_coef[5] = 0x1c2; + cfg->matrix_coef[6] = 0x1c2; + cfg->matrix_coef[7] = 0x1e87; + cfg->matrix_coef[8] = 0x1fb7; + } cfg->matrix_offset[0] = 16; cfg->matrix_offset[1] = 128; cfg->matrix_offset[2] = 128; cfg->matrix_sat_in_en = 0; cfg->matrix_minus_16_ctrl = 0; cfg->matrix_sign_ctrl = 0; - } else if (cfg->use_matrix_default == MATRIX_FULL_RANGE_YCC_TO_RGB) { + } else if (cfg->use_matrix_default & MATRIX_FULL_RANGE_YCC_TO_RGB) { /* ycbcr (0-255) to rgb(0-255) */ /* 1, 0, 1.402 */ /* 1, -0.34414, -0.71414 */ @@ -681,7 +697,7 @@ void ge2d_set_dp_gen(struct ge2d_dp_gen_s *cfg) cfg->matrix_sat_in_en = 0; cfg->matrix_minus_16_ctrl = 0; cfg->matrix_sign_ctrl = 0x3; - } else if (cfg->use_matrix_default == MATRIX_RGB_TO_FULL_RANGE_YCC) { + } else if (cfg->use_matrix_default & MATRIX_RGB_TO_FULL_RANGE_YCC) { cfg->matrix_coef[0] = 0x132; cfg->matrix_coef[1] = 0x259; cfg->matrix_coef[2] = 0x75; diff --git a/drivers/amlogic/media/common/ge2d/ge2dgen.c b/drivers/amlogic/media/common/ge2d/ge2dgen.c index fd6f63c..5918d3b 100644 --- a/drivers/amlogic/media/common/ge2d/ge2dgen.c +++ b/drivers/amlogic/media/common/ge2d/ge2dgen.c @@ -57,6 +57,9 @@ static inline void _set_src1_format(struct ge2d_src1_data_s *src1_data_cfg, dp_gen_cfg->use_matrix_default = (format_dst & GE2D_FORMAT_FULL_RANGE) ? MATRIX_RGB_TO_FULL_RANGE_YCC : MATRIX_RGB_TO_YCC; + dp_gen_cfg->use_matrix_default |= + ((format_dst & GE2D_FORMAT_BT_STANDARD) ? + MATRIX_BT_709 : MATRIX_BT_601); dp_gen_cfg->conv_matrix_en = 1; } else dp_gen_cfg->conv_matrix_en = 0; @@ -108,6 +111,9 @@ static inline void _set_dst_format( dp_gen_cfg->use_matrix_default = (format_dst & GE2D_FORMAT_FULL_RANGE) ? MATRIX_RGB_TO_FULL_RANGE_YCC : MATRIX_RGB_TO_YCC; + dp_gen_cfg->use_matrix_default |= + ((format_dst & GE2D_FORMAT_BT_STANDARD) ? + MATRIX_BT_709 : MATRIX_BT_601); dp_gen_cfg->conv_matrix_en = 1; } else dp_gen_cfg->conv_matrix_en = 0; diff --git a/drivers/amlogic/media/video_processor/pic_dev/picdec.c b/drivers/amlogic/media/video_processor/pic_dev/picdec.c index 7d28ea3..7673c1f3 100644 --- a/drivers/amlogic/media/video_processor/pic_dev/picdec.c +++ b/drivers/amlogic/media/video_processor/pic_dev/picdec.c @@ -449,16 +449,25 @@ static int render_frame_block(void) new_vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21 | VIDTYPE_PIC; - /* indicate the vframe is a full range frame */ + /* indicate the vframe is a limited range frame */ new_vf->signal_type = - /* HD default 709 limit */ - (1 << 29) /* video available */ - | (5 << 26) /* unspecified */ - | (1 << 25) /* full */ - | (1 << 24) /* color available */ - | (1 << 16) /* bt709 */ - | (1 << 8) /* bt709 */ - | (1 << 0); /* bt709 */ + (1 << 29) /* video available */ + | (5 << 26) /* unspecified */ + | (0 << 25) /* limited */ + | (1 << 24); /* color available */ + if (dev->disp_width >= ZOOM_WIDTH && dev->disp_height >= ZOOM_HEIGHT) { + /* >= 720p, use 709 */ + new_vf->signal_type |= + (1 << 16) /* bt709 */ + | (1 << 8) /* bt709 */ + | (1 << 0); /* bt709 */ + } else { + /* < 720p, use 709 */ + new_vf->signal_type |= + (3 << 16) /* bt601 */ + | (3 << 8) /* bt601 */ + | (3 << 0); /* bt601 */ + } new_vf->duration_pulldown = 0; new_vf->index = index; new_vf->pts = 0; @@ -976,7 +985,11 @@ int picdec_fill_buffer(struct vframe_s *vf, struct ge2d_context_s *context, aml_pr_info(1, "dst 2 addr is %x\n", (unsigned int)cs2.addr); ge2d_config->dst_para.mem_type = CANVAS_TYPE_INVALID; if (picdec_device.output_format_mode) - ge2d_config->dst_para.format = GE2D_FORMAT_S24_YUV444; + /* set dst format with bt601 or bt709 */ + ge2d_config->dst_para.format = + GE2D_FORMAT_S24_YUV444 | + ((vf->signal_type & (0xff << 16)) == (1 << 16) ? + GE2D_FORMAT_BT709 : GE2D_FORMAT_BT601); else ge2d_config->dst_para.format = GE2D_FORMAT_M24_NV21; ge2d_config->dst_para.fill_color_en = 0; diff --git a/include/linux/amlogic/media/ge2d/ge2d.h b/include/linux/amlogic/media/ge2d/ge2d.h index bdd8968..0855b65 100644 --- a/include/linux/amlogic/media/ge2d/ge2d.h +++ b/include/linux/amlogic/media/ge2d/ge2d.h @@ -128,10 +128,17 @@ enum ge2d_memtype_s { #define FILTER_TYPE_GAU0_BOT 5 #define FILTER_TYPE_GAU1 6 -#define MATRIX_YCC_TO_RGB 1 -#define MATRIX_RGB_TO_YCC 2 -#define MATRIX_FULL_RANGE_YCC_TO_RGB 3 -#define MATRIX_RGB_TO_FULL_RANGE_YCC 4 +#define MATRIX_YCC_TO_RGB (1 << 0) +#define MATRIX_RGB_TO_YCC (1 << 1) +#define MATRIX_FULL_RANGE_YCC_TO_RGB (1 << 2) +#define MATRIX_RGB_TO_FULL_RANGE_YCC (1 << 3) +#define MATRIX_BT_STANDARD (1 << 4) +#define MATRIX_BT_601 (0 << 4) +#define MATRIX_BT_709 (1 << 4) + +#define GE2D_FORMAT_BT_STANDARD (1 << 28) +#define GE2D_FORMAT_BT601 (0 << 28) +#define GE2D_FORMAT_BT709 (1 << 28) #define GE2D_ENDIAN_SHIFT 24 -- 2.7.4