From 238dc24e90725ca09ba430f03441318eee39b39e Mon Sep 17 00:00:00 2001 From: MingLiang Dong Date: Thu, 17 Oct 2019 19:08:23 +0800 Subject: [PATCH] hdr: correct hdr10+ process path [1/1] PD#SWPL-16139 Problem: 1. hdr10+ gen ebz curve error 2. hdr10+ process error Solution: 1. fix hdr10+ ebz gen 2. correct hdr10+ process path Verify: verify on TL1 Change-Id: Ia33488ada2e0ebfe9b156f9f667188cf02164089 Signed-off-by: MingLiang Dong --- .../amlogic/media/enhancement/amvecm/amcsc.c | 77 +- .../amlogic/media/enhancement/amvecm/amcsc.h | 3 + .../media/enhancement/amvecm/amcsc_pip.c | 27 +- .../enhancement/amvecm/arch/vpp_hdr_regs.h | 1 + .../enhancement/amvecm/hdr/am_hdr10_plus.c | 197 ++-- .../amvecm/hdr/am_hdr10_plus_ootf.c | 961 +++++++++++------- .../amvecm/hdr/am_hdr10_plus_ootf.h | 47 +- .../media/enhancement/amvecm/set_hdr2_v0.c | 417 +++++++- .../media/enhancement/amvecm/set_hdr2_v0.h | 24 +- 9 files changed, 1298 insertions(+), 456 deletions(-) diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.c b/drivers/amlogic/media/enhancement/amvecm/amcsc.c index b148d0e230a5..6835d8565d35 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.c +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.c @@ -664,6 +664,14 @@ static uint customer_master_display_param[12] = { /* content lumin and frame average */ }; +static int customer_panel_lumin = 380; +module_param(customer_panel_lumin, int, 0664); +MODULE_PARM_DESC(customer_panel_lumin, "\n customer_panel_lumin\n"); + +int customer_hdr_clipping; +module_param(customer_hdr_clipping, int, 0664); +MODULE_PARM_DESC(customer_hdr_clipping, "\n customer_hdr_clipping\n"); + module_param(customer_matrix_en, bool, 0664); MODULE_PARM_DESC(customer_matrix_en, "\n if enable customer matrix\n"); @@ -4679,6 +4687,23 @@ static void vpp_lut_curve_set(enum vpp_lut_sel_e lut_sel, CSC_ON); } } + +static int hdr10p_process( + struct vinfo_s *vinfo, + struct vframe_master_display_colour_s *master_info, + enum vd_path_e vd_path) +{ + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { + hdr_func(OSD1_HDR, HDR_BYPASS, vinfo); + if (vd_path == VD1_PATH) + hdr10p_func(VD1_HDR, HDR10P_SDR, vinfo); + else + hdr10p_func(VD2_HDR, HDR10P_SDR, vinfo); + } + + return 0; +} + static int hdr_process( enum vpp_matrix_csc_e csc_type, struct vinfo_s *vinfo, @@ -6381,6 +6406,12 @@ static int sink_support_hlg(const struct vinfo_s *vinfo) static int sink_support_hdr10_plus(const struct vinfo_s *vinfo) { + /* panel output and TL1 and TM2 */ + if ((vinfo->viu_color_fmt == COLOR_FMT_RGB444) && + ((get_cpu_type() == MESON_CPU_MAJOR_ID_TL1) || + (get_cpu_type() == MESON_CPU_MAJOR_ID_TM2))) + return 1; + /* hdmi */ if ((vinfo->hdr_info.hdr10plus_info.ieeeoui == 0x90848B) && (vinfo->hdr_info.hdr10plus_info.application_version @@ -6415,11 +6446,13 @@ static enum hdr_type_e get_source_type(enum vd_path_e vd_path) return HDRTYPE_HLG; else if ((signal_transfer_characteristic == 0x30) && (signal_color_primaries == 9)) { - if (sink_support_hdr10_plus(get_current_vinfo())) + if (sink_support_hdr10_plus(get_current_vinfo()) && + (vd_path == VD1_PATH)) return HDRTYPE_HDR10PLUS; else return HDRTYPE_HDR10; - } else if ((signal_transfer_characteristic == 16) || + } else if ( + (signal_transfer_characteristic == 16) || (signal_color_primaries == 9)) return HDRTYPE_HDR10; else @@ -6455,19 +6488,18 @@ bool is_video_layer_on(enum vd_path_e vd_path) video_layer_wait_on[vd_path]; } -static void hdr10_plus_metadata_update(struct vframe_s *vf, +static bool hdr10_plus_metadata_update( + struct vframe_s *vf, enum vpp_matrix_csc_e csc_type, struct hdr10plus_para *p) { if (!vf) - return; + return false; if (csc_type != VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) - return; + return false; hdr10_plus_parser_metadata(vf); - hdr10_plus_ootf_gen(); - if (tx_hdr10_plus_support) { hdr10_plus_hdmitx_vsif_parser(p, vf); pr_csc(0x10, @@ -6501,8 +6533,21 @@ static void hdr10_plus_metadata_update(struct vframe_s *vf, ((p->graphics_overlay_flag & 0x1) << 7) | ((p->no_delay_flag & 0x1) << 6)); } + //TODO: return false if meta not changed + return true; } +static struct hdr10pgen_param_s hdr10pgen_param; +void hdr10_plus_process_update(int force_source_lumin) +{ + hdr10_plus_ootf_gen( + customer_panel_lumin, + force_source_lumin, + &hdr10pgen_param); + hdr10p_ebzcurve_update(VD1_HDR, HDR10P_SDR, &hdr10pgen_param); +} +EXPORT_SYMBOL(hdr10_plus_process_update); + static struct hdr10plus_para hdmitx_hdr10plus_params[VD_PATH_MAX]; static int hdr10_plus_pkt_update; static bool hdr10_plus_pkt_on; @@ -6971,7 +7016,7 @@ static void video_process( VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC)) { // TODO: hdr10_plus_process(vf, mode, vd_path); if (hdr10_plus_process_mode[vd_path] == PROC_MATCH) { - hdr_process(csc_type, vinfo, p, vd_path); + hdr10p_process(vinfo, p, vd_path); /* hdr10_plus_process(vf); */ } else { bypass_hdr_process( @@ -7220,9 +7265,17 @@ static int vpp_matrix_update( } if ((vf != NULL) && (flags & CSC_FLAG_TOGGLE_FRAME)) { - hdr10_plus_metadata_update(vf, csc_type, + hdr10p_meta_updated = hdr10_plus_metadata_update( + vf, csc_type, &hdmitx_hdr10plus_params[vd_path]); - hdr10p_meta_updated = true; + + if ((csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB_DYNAMIC) || + (csc_type == VPP_MATRIX_BT2020YUV_BT2020RGB)) { + if ((vd_path == VD1_PATH) && + (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A))) + get_hist(VD1_HDR, HIST_O_BEFORE); + } + } if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { @@ -7270,6 +7323,10 @@ static int vpp_matrix_update( cur_hdr_policy = get_hdr_policy(); } + if (hdr10p_meta_updated && + hdr10_plus_process_mode[vd_path] == PROC_MATCH) + hdr10_plus_process_update(0); + /* eye protection mode */ if (signal_change_flag & SIG_WB_CHG) vpp_eye_protection_process(csc_type, vinfo, vd_path); diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc.h b/drivers/amlogic/media/enhancement/amvecm/amcsc.h index f71a14ca40a3..b5aeb23863c3 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc.h +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc.h @@ -232,5 +232,8 @@ extern void send_hdr10_plus_pkt(enum vd_path_e vd_path); #define HDRPLUS_PKT_REPEAT 1 #define HDRPLUS_PKT_IDLE 0 +void hdr10_plus_process_update(int force_source_lumin); +extern int customer_hdr_clipping; + #endif /* AM_CSC_H */ diff --git a/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c index b684bce84bf4..3402fe0c901c 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c +++ b/drivers/amlogic/media/enhancement/amvecm/amcsc_pip.c @@ -37,7 +37,7 @@ static const char *module_str[7] = { "DI" }; -static const char *process_str[15] = { +static const char *process_str[16] = { "UNKNOWN", "HDR_BYPASS", "HDR_SDR", @@ -52,7 +52,8 @@ static const char *process_str[15] = { "HDR_HLG", "RGB_YUV", "RGB_HDR", - "RGB_HLG" + "RGB_HLG", + "HDR10P_SDR" }; static const char *policy_str[3] = { @@ -865,6 +866,8 @@ static void prepare_hdr_info( } } +static unsigned int content_max_lumin[VD_PATH_MAX]; + void hdmi_packet_process( int signal_change_flag, struct vinfo_s *vinfo, @@ -876,6 +879,15 @@ void hdmi_packet_process( struct master_display_info_s send_info; enum output_format_e cur_output_format = output_format; + if (customer_hdr_clipping) + content_max_lumin[vd_path] = + customer_hdr_clipping; + else if (p && p->luminance[0]) + content_max_lumin[vd_path] = + p->luminance[0] / 10000; + else + content_max_lumin[vd_path] = 1250; + if (!vinfo) return; if (!vinfo->vout_device) { @@ -1067,10 +1079,13 @@ void video_post_process( hdr_proc(VD2_HDR, HDR_BYPASS, vinfo); hdr_proc(OSD1_HDR, SDR_HDR, vinfo); } else if (hdr_process_mode[vd_path] == PROC_HDR_TO_SDR) { - if (vd_path == VD1_PATH) + if (vd_path == VD1_PATH) { hdr_proc(VD1_HDR, HDR_SDR, vinfo); - else + hdr10_plus_process_update( + content_max_lumin[vd_path]); + } else { hdr_proc(VD2_HDR, HDR_SDR, vinfo); + } hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo); } else if (hdr_process_mode[vd_path] == PROC_HDR_TO_HLG) { if (vd_path == VD1_PATH) @@ -1124,9 +1139,9 @@ void video_post_process( } else if (hdr10_plus_process_mode[vd_path] == PROC_HDRP_TO_SDR) { if (vd_path == VD1_PATH) - hdr_proc(VD1_HDR, HDR_SDR, vinfo); + hdr_proc(VD1_HDR, HDR10P_SDR, vinfo); else - hdr_proc(VD2_HDR, HDR_SDR, vinfo); + hdr_proc(VD2_HDR, HDR10P_SDR, vinfo); hdr_proc(OSD1_HDR, HDR_BYPASS, vinfo); } else if (hdr10_plus_process_mode[vd_path] == PROC_HDRP_TO_HLG) { diff --git a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_hdr_regs.h b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_hdr_regs.h index abee62e70d98..360bc17115cd 100644 --- a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_hdr_regs.h +++ b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_hdr_regs.h @@ -96,6 +96,7 @@ extern struct am_regs_s r_lut_hdr_sdr_level3; #define VD1_HDR2_PROC_WIN2 0x383a #define VD1_HDR2_MATRIXI_EN_CTRL 0x383b #define VD1_HDR2_MATRIXO_EN_CTRL 0x383c +#define VD1_HDR2_HIST_CTRL 0x383d #define VD2_HDR2_CTRL 0x3850 #define VD2_HDR2_CLK_GATE 0x3851 diff --git a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c index 5976b9efe712..81a43811d34e 100644 --- a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c +++ b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus.c @@ -136,6 +136,8 @@ void parser_hdr10_plus_medata(char *metadata, uint32_t size) unsigned int num_bezier_curve_anchors = 0; unsigned int color_saturation_mapping_flag = 0; + memset(&hdr_plus_sei, 0, sizeof(struct vframe_hdr_plus_sei)); + GetBits(metadata, totbitoffset, &value, size, sei_md_bits.len_itu_t_t35_country_code); hdr_plus_sei.itu_t_t35_country_code = (u16)value; @@ -506,69 +508,142 @@ static void hdr10_plus_vf_md_parse(struct vframe_s *vf) hdr10p_md_param.application_version = vf->prop.hdr10p_data.pb4_st.app_ver; + pr_hdr("vf:app_ver = 0x%x\n", vf->prop.hdr10p_data.pb4_st.app_ver); + hdr10p_md_param.targeted_max_lum = vf->prop.hdr10p_data.pb4_st.max_lumin; + pr_hdr( + "vf:target_max_lumin = 0x%x\n", + vf->prop.hdr10p_data.pb4_st.max_lumin); + hdr10p_md_param.average_maxrgb = vf->prop.hdr10p_data.average_maxrgb; + pr_hdr( + "vf:average_maxrgb = 0x%x\n", + vf->prop.hdr10p_data.average_maxrgb); + /*distribution value*/ memcpy(&hdr10p_md_param.distribution_values[0], &vf->prop.hdr10p_data.distrib_valus0, sizeof(uint8_t) * 9); + for (i = 0; i < 9; i++) + pr_hdr( + "vf:hdr10p_md_param.distribution_values[%d] = 0x%x\n", + i, hdr10p_md_param.distribution_values[i]); hdr10p_md_param.num_bezier_curve_anchors = vf->prop.hdr10p_data.pb15_18_st.num_bezier_curve_anchors; + pr_hdr( + "vf:num_bezier_curve_anchors = 0x%x\n", + vf->prop.hdr10p_data.pb15_18_st.num_bezier_curve_anchors); + + /*if (!hdr10p_md_param.num_bezier_curve_anchors) {*/ + /* hdr10p_md_param.num_bezier_curve_anchors = 9;*/ + /* pr_hdr("hdr10p_md_param.num_bezier_curve_anchors = 0\n");*/ + /*}*/ hdr10p_md_param.knee_point_x = (vf->prop.hdr10p_data.pb15_18_st.knee_point_x_9_6 << 6) | vf->prop.hdr10p_data.pb15_18_st.knee_point_x_5_0; + pr_hdr( + "vf:knee_point_x_5_0 = 0x%x, knee_point_x_9_6 = 0x%x\n", + vf->prop.hdr10p_data.pb15_18_st.knee_point_x_5_0, + vf->prop.hdr10p_data.pb15_18_st.knee_point_x_9_6); + hdr10p_md_param.knee_point_y = (vf->prop.hdr10p_data.pb15_18_st.knee_point_y_9_8 << 8) | vf->prop.hdr10p_data.pb15_18_st.knee_point_y_7_0; + pr_hdr( + "vf:knee_point_y_7_0 = 0x%x, knee_point_y_9_8 = 0x%x\n", + vf->prop.hdr10p_data.pb15_18_st.knee_point_y_7_0, + vf->prop.hdr10p_data.pb15_18_st.knee_point_y_9_8); + /*bezier curve*/ hdr10p_md_param.bezier_curve_anchors[0] = vf->prop.hdr10p_data.pb15_18_st.bezier_curve_anchors0; + memcpy(&hdr10p_md_param.bezier_curve_anchors[1], &vf->prop.hdr10p_data.bezier_curve_anchors1, sizeof(uint8_t) * 8); + for (i = 0; i < 9; i++) + pr_hdr( + "vf:hdr10p_md_param.bezier_curve_anchors[%d] = 0x%x\n", + i, hdr10p_md_param.bezier_curve_anchors[i]); hdr10p_md_param.graphics_overlay_flag = vf->prop.hdr10p_data.pb27_st.overlay_flag; hdr10p_md_param.no_delay_flag = vf->prop.hdr10p_data.pb27_st.no_delay_flag; + pr_hdr( + "vf:overlay_flag = 0x%x\n", + vf->prop.hdr10p_data.pb27_st.overlay_flag); + pr_hdr( + "vf:no_delay_flag = 0x%x\n", + vf->prop.hdr10p_data.pb27_st.no_delay_flag); + hdr_plus_sei.application_identifier = hdr10p_md_param.application_version; + pr_hdr( + "hdr_plus_sei.application_identifier = %d\n", + hdr_plus_sei.application_identifier); + /*hdr10 plus default one window*/ hdr_plus_sei.num_windows = 1; hdr_plus_sei.tgt_sys_disp_max_lumi = hdr10p_md_param.targeted_max_lum << 5; + pr_hdr( + "hdr_plus_sei.tgt_sys_disp_max_lumi = %d\n", + hdr_plus_sei.tgt_sys_disp_max_lumi); hdr_plus_sei.average_maxrgb[0] = - hdr10p_md_param.average_maxrgb << 4; + (hdr10p_md_param.average_maxrgb << 4) * 10; + pr_hdr( + "hdr_plus_sei.average_maxrgb[0] = %d\n", + hdr_plus_sei.average_maxrgb[0]); for (i = 0; i < 9; i++) { if (i == 2) { hdr_plus_sei.distribution_maxrgb_percentiles[0][2] = hdr10p_md_param.distribution_values[2]; + pr_hdr( + "hdr_plus_sei.distribution_maxrgb_percentiles[0][%d] = %d\n", + i, hdr_plus_sei.distribution_maxrgb_percentiles[0][i]); continue; } hdr_plus_sei.distribution_maxrgb_percentiles[0][i] = (hdr10p_md_param.distribution_values[i] << 4) * 10; + pr_hdr( + "hdr_plus_sei.distribution_maxrgb_percentiles[0][%d] = %d\n", + i, hdr_plus_sei.distribution_maxrgb_percentiles[0][i]); } hdr_plus_sei.num_bezier_curve_anchors[0] = hdr10p_md_param.num_bezier_curve_anchors; + pr_hdr( + "hdr_plus_sei.num_bezier_curve_anchors[0] = %d\n", + hdr_plus_sei.num_bezier_curve_anchors[0]); hdr_plus_sei.knee_point_x[0] = hdr10p_md_param.knee_point_x << 2; hdr_plus_sei.knee_point_y[0] = hdr10p_md_param.knee_point_y << 2; + pr_hdr( + "hdr_plus_sei.knee_point_x[0] = %d\n", + hdr_plus_sei.knee_point_x[0]); + pr_hdr( + "hdr_plus_sei.knee_point_y[0] = %d\n", + hdr_plus_sei.knee_point_y[0]); - for (i = 0; i < 9; i++) + for (i = 0; i < 9; i++) { hdr_plus_sei.bezier_curve_anchors[0][i] = hdr10p_md_param.bezier_curve_anchors[i] << 2; + pr_hdr( + "hdr_plus_sei.bezier_curve_anchors[0][%d] = %d\n", + i, hdr_plus_sei.bezier_curve_anchors[0][i]); + } for (i = 0; i < 9; i++) { if (hdr_plus_sei.bezier_curve_anchors[0][i] != 0) { @@ -624,6 +699,9 @@ void hdr10_plus_parser_metadata(struct vframe_s *vf) } } } + + if (debug_hdr >= 1) + debug_hdr--; } struct hdr10plus_para dbg_hdr10plus_pkt; @@ -780,57 +858,50 @@ void hdr10_plus_hdmitx_vsif_parser( sizeof(struct hdr10plus_para)); } -void hdr10_plus_process(struct vframe_s *vf) -{ - if (!vf) - return; - hdr10_plus_ootf_gen(); -} - void hdr10_plus_debug(void) { int i = 0; int j = 0; - pr_hdr("itu_t_t35_country_code = 0x%x\n", + pr_info("itu_t_t35_country_code = 0x%x\n", hdr_plus_sei.itu_t_t35_country_code); - pr_hdr("itu_t_t35_terminal_provider_code = 0x%x\n", + pr_info("itu_t_t35_terminal_provider_code = 0x%x\n", hdr_plus_sei.itu_t_t35_terminal_provider_code); - pr_hdr("itu_t_t35_terminal_provider_oriented_code = 0x%x\n", + pr_info("itu_t_t35_terminal_provider_oriented_code = 0x%x\n", hdr_plus_sei.itu_t_t35_terminal_provider_oriented_code); - pr_hdr("application_identifier = 0x%x\n", + pr_info("application_identifier = 0x%x\n", hdr_plus_sei.application_identifier); - pr_hdr("application_version = 0x%x\n", + pr_info("application_version = 0x%x\n", hdr_plus_sei.application_version); - pr_hdr("num_windows = 0x%x\n", + pr_info("num_windows = 0x%x\n", hdr_plus_sei.num_windows); for (i = 1; i < hdr_plus_sei.num_windows; i++) { - pr_hdr("window_upper_left_corner_x[%d] = 0x%x\n", + pr_info("window_upper_left_corner_x[%d] = 0x%x\n", i, hdr_plus_sei.window_upper_left_corner_x[i]); - pr_hdr("window_upper_left_corner_y[%d] = 0x%x\n", + pr_info("window_upper_left_corner_y[%d] = 0x%x\n", i, hdr_plus_sei.window_upper_left_corner_y[i]); - pr_hdr("window_lower_right_corner_x[%d] = 0x%x\n", + pr_info("window_lower_right_corner_x[%d] = 0x%x\n", i, hdr_plus_sei.window_lower_right_corner_x[i]); - pr_hdr("window_lower_right_corner_y[%d] = 0x%x\n", + pr_info("window_lower_right_corner_y[%d] = 0x%x\n", i, hdr_plus_sei.window_lower_right_corner_y[i]); - pr_hdr("center_of_ellipse_x[%d] = 0x%x\n", + pr_info("center_of_ellipse_x[%d] = 0x%x\n", i, hdr_plus_sei.center_of_ellipse_x[i]); - pr_hdr("center_of_ellipse_y[%d] = 0x%x\n", + pr_info("center_of_ellipse_y[%d] = 0x%x\n", i, hdr_plus_sei.center_of_ellipse_y[i]); - pr_hdr("rotation_angle[%d] = 0x%x\n", + pr_info("rotation_angle[%d] = 0x%x\n", i, hdr_plus_sei.rotation_angle[i]); - pr_hdr("semimajor_axis_internal_ellipse[%d] = 0x%x\n", + pr_info("semimajor_axis_internal_ellipse[%d] = 0x%x\n", i, hdr_plus_sei.semimajor_axis_internal_ellipse[i]); - pr_hdr("semimajor_axis_external_ellipse[%d] = 0x%x\n", + pr_info("semimajor_axis_external_ellipse[%d] = 0x%x\n", i, hdr_plus_sei.semimajor_axis_external_ellipse[i]); - pr_hdr("semiminor_axis_external_ellipse[%d] = 0x%x\n", + pr_info("semiminor_axis_external_ellipse[%d] = 0x%x\n", i, hdr_plus_sei.semiminor_axis_external_ellipse[i]); - pr_hdr("overlap_process_option[%d] = 0x%x\n", + pr_info("overlap_process_option[%d] = 0x%x\n", i, hdr_plus_sei.overlap_process_option[i]); } - pr_hdr("targeted_system_display_maximum_luminance = 0x%x\n", + pr_info("targeted_system_display_maximum_luminance = 0x%x\n", hdr_plus_sei.tgt_sys_disp_max_lumi); - pr_hdr("targeted_system_display_actual_peak_luminance_flag = 0x%x\n", + pr_info("targeted_system_display_actual_peak_luminance_flag = 0x%x\n", hdr_plus_sei.tgt_sys_disp_act_pk_lumi_flag); if (hdr_plus_sei.tgt_sys_disp_act_pk_lumi_flag) { for (i = 0; @@ -839,8 +910,9 @@ void hdr10_plus_debug(void) for (j = 0; j < hdr_plus_sei.num_cols_tgt_sys_disp_act_pk_lumi; j++) { - pr_hdr("tgt_sys_disp_act_pk_lumi"); - pr_hdr("[%d][%d] = 0x%x\n", + pr_info("tgt_sys_disp_act_pk_lumi"); + pr_info( + "[%d][%d] = 0x%x\n", i, j, hdr_plus_sei.tgt_sys_disp_act_pk_lumi[i][j]); } @@ -849,33 +921,35 @@ void hdr10_plus_debug(void) for (i = 0; i < hdr_plus_sei.num_windows; i++) { for (j = 0; j < 3; j++) - pr_hdr("maxscl[%d][%d] = 0x%x\n", + pr_info("maxscl[%d][%d] = 0x%x\n", i, j, hdr_plus_sei.maxscl[i][j]); - pr_hdr("average_maxrgb[%d] = 0x%x\n", + pr_info("average_maxrgb[%d] = 0x%x\n", i, hdr_plus_sei.average_maxrgb[i]); - pr_hdr("num_distribution_maxrgb_percentiles[%d] = 0x%x\n", + pr_info("num_distribution_maxrgb_percentiles[%d] = 0x%x\n", i, hdr_plus_sei.num_distribution_maxrgb_percentiles[i]); for (j = 0; j < hdr_plus_sei.num_distribution_maxrgb_percentiles[i]; j++) { - pr_hdr("distribution_maxrgb_pcntages[%d][%d] = 0x%x\n", + pr_info( + "distribution_maxrgb_pcntages[%d][%d] = 0x%x\n", i, j, hdr_plus_sei.distribution_maxrgb_percentages[i][j]); - pr_hdr("distribution_maxrgb_pcntiles[%d][%d] = 0x%x\n", + pr_info( + "distribution_maxrgb_pcntiles[%d][%d] = 0x%x\n", i, j, hdr_plus_sei.distribution_maxrgb_percentiles[i][j]); } - pr_hdr("fraction_bright_pixels[%d] = 0x%x\n", + pr_info("fraction_bright_pixels[%d] = 0x%x\n", i, hdr_plus_sei.fraction_bright_pixels[i]); } - pr_hdr("mast_disp_act_pk_lumi_flag = 0x%x\n", + pr_info("mast_disp_act_pk_lumi_flag = 0x%x\n", hdr_plus_sei.mast_disp_act_pk_lumi_flag); if (hdr_plus_sei.mast_disp_act_pk_lumi_flag) { - pr_hdr("num_rows_mast_disp_act_pk_lumi = 0x%x\n", + pr_info("num_rows_mast_disp_act_pk_lumi = 0x%x\n", hdr_plus_sei.num_rows_mast_disp_act_pk_lumi); - pr_hdr("num_cols_mast_disp_act_pk_lumi = 0x%x\n", + pr_info("num_cols_mast_disp_act_pk_lumi = 0x%x\n", hdr_plus_sei.num_cols_mast_disp_act_pk_lumi); for (i = 0; i < hdr_plus_sei.num_rows_mast_disp_act_pk_lumi; @@ -883,56 +957,59 @@ void hdr10_plus_debug(void) for (j = 0; j < hdr_plus_sei.num_cols_mast_disp_act_pk_lumi; j++) - pr_hdr("mast_disp_act_pk_lumi[%d][%d] = 0x%x\n", + pr_info( + "mast_disp_act_pk_lumi[%d][%d] = 0x%x\n", i, j, hdr_plus_sei.mast_disp_act_pk_lumi[i][j]); } } for (i = 0; i < hdr_plus_sei.num_windows; i++) { - pr_hdr("tone_mapping_flag[%d] = 0x%x\n", + pr_info("tone_mapping_flag[%d] = 0x%x\n", i, hdr_plus_sei.tone_mapping_flag[i]); - pr_hdr("knee_point_x[%d] = 0x%x\n", + pr_info("knee_point_x[%d] = 0x%x\n", i, hdr_plus_sei.knee_point_x[i]); - pr_hdr("knee_point_y[%d] = 0x%x\n", + pr_info("knee_point_y[%d] = 0x%x\n", i, hdr_plus_sei.knee_point_y[i]); - pr_hdr("num_bezier_curve_anchors[%d] = 0x%x\n", + pr_info("num_bezier_curve_anchors[%d] = 0x%x\n", i, hdr_plus_sei.num_bezier_curve_anchors[i]); for (j = 0; j < hdr_plus_sei.num_bezier_curve_anchors[i]; j++) - pr_hdr("bezier_curve_anchors[%d][%d] = 0x%x\n", + pr_info("bezier_curve_anchors[%d][%d] = 0x%x\n", i, j, hdr_plus_sei.bezier_curve_anchors[i][j]); - pr_hdr("color_saturation_mapping_flag[%d] = 0x%x\n", + pr_info("color_saturation_mapping_flag[%d] = 0x%x\n", i, hdr_plus_sei.color_saturation_mapping_flag[i]); - pr_hdr("color_saturation_weight[%d] = 0x%x\n", + pr_info("color_saturation_weight[%d] = 0x%x\n", i, hdr_plus_sei.color_saturation_weight[i]); } - pr_hdr("\ntx vsif packet data print begin\n"); - pr_hdr("application_version = 0x%x\n", + pr_info("\ntx vsif packet data print begin\n"); + pr_info("application_version = 0x%x\n", dbg_hdr10plus_pkt.application_version); - pr_hdr("targeted_max_lum = 0x%x\n", + pr_info("targeted_max_lum = 0x%x\n", dbg_hdr10plus_pkt.targeted_max_lum); - pr_hdr("average_maxrgb = 0x%x\n", + pr_info("average_maxrgb = 0x%x\n", dbg_hdr10plus_pkt.average_maxrgb); for (i = 0; i < 9; i++) - pr_hdr("distribution_values[%d] = 0x%x\n", + pr_info( + "distribution_values[%d] = 0x%x\n", i, dbg_hdr10plus_pkt.distribution_values[i]); - pr_hdr("num_bezier_curve_anchors = 0x%x\n", + pr_info("num_bezier_curve_anchors = 0x%x\n", dbg_hdr10plus_pkt.num_bezier_curve_anchors); - pr_hdr("knee_point_x = 0x%x\n", + pr_info("knee_point_x = 0x%x\n", dbg_hdr10plus_pkt.knee_point_x); - pr_hdr("knee_point_y = 0x%x\n", + pr_info("knee_point_y = 0x%x\n", dbg_hdr10plus_pkt.knee_point_y); for (i = 0; i < 9; i++) - pr_hdr("bezier_curve_anchors[%d] = 0x%x\n", + pr_info( + "bezier_curve_anchors[%d] = 0x%x\n", i, dbg_hdr10plus_pkt.bezier_curve_anchors[i]); - pr_hdr("graphics_overlay_flag = 0x%x\n", + pr_info("graphics_overlay_flag = 0x%x\n", dbg_hdr10plus_pkt.graphics_overlay_flag); - pr_hdr("no_delay_flag = 0x%x\n", + pr_info("no_delay_flag = 0x%x\n", dbg_hdr10plus_pkt.no_delay_flag); - pr_hdr("\ntx vsif packet data print end\n"); + pr_info("\ntx vsif packet data print end\n"); - pr_hdr(HDR10_PLUS_VERSION); + pr_info(HDR10_PLUS_VERSION); } diff --git a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.c b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.c index d3273e971f74..8df4d57627f0 100644 --- a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.c +++ b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.c @@ -36,6 +36,10 @@ unsigned int hdr10_plus_printk; module_param(hdr10_plus_printk, uint, 0664); MODULE_PARM_DESC(hdr10_plus_printk, "hdr10_plus_printk"); +unsigned int force_ref_peak = 1; +module_param(force_ref_peak, uint, 0664); +MODULE_PARM_DESC(force_ref_peak, "force_ref_peak"); + #define pr_hdr(fmt, args...)\ do {\ if (hdr10_plus_printk)\ @@ -43,80 +47,94 @@ MODULE_PARM_DESC(hdr10_plus_printk, "hdr10_plus_printk"); } while (0) /*EBZCurveParameters to gen OOTF bezier curves*/ -void EBZCurveParametersInit(struct EBZCurveParameters *EBZCurveParameters) +void ebzcurveparametersinit(struct ebzcurveparameters *ebzcurveparameters) { int i; - EBZCurveParameters->Sx = 0; - EBZCurveParameters->Sy = 0; - EBZCurveParameters->order = N; + ebzcurveparameters->sx = 0; + ebzcurveparameters->sy = 0; + ebzcurveparameters->order = N; for (i = 0; i < N; i++) - EBZCurveParameters->Anchor[i] = PORCESSING_DATA_MAX; + ebzcurveparameters->anchor[i] = PORCESSING_DATA_MAX; } /*percentile actually obtained from metadata */ -void PercentileInit(struct Percentiles *percentile, +void percentileinit( + struct percentiles *percentile, struct hdr10_plus_sei_s *hdr10_plus_sei) { int i; percentile->num_percentile = hdr10_plus_sei->num_distributions[0]; for (i = 0; i < percentile->num_percentile; i++) { - percentile->percentilePercent[i] = + percentile->percentilepercent[i] = hdr10_plus_sei->distribution_index[0][i]; - percentile->percentileValue[i] = + percentile->percentilevalue[i] = hdr10_plus_sei->distribution_values[0][i] / 10; } } /*metadata should obtained from 3C or 2094 metadata*/ -void MetaDataInit(struct Scene2094Metadata *Metadata, +void metadatainit( + struct scene2094metadata *metadata, struct hdr10_plus_sei_s *hdr10_plus_sei) { int i; - Metadata->maxSceneSourceLuminance = + metadata->maxscenesourceluminance = max(max(hdr10_plus_sei->maxscl[0][0], hdr10_plus_sei->maxscl[0][1]), - hdr10_plus_sei->maxscl[0][2]); - Metadata->minLuminance = MIN_LUMINANCE; - Metadata->referenceLuminance = - hdr10_plus_sei->targeted_system_display_maximum_luminance; - PercentileInit(&(Metadata->percentiles), hdr10_plus_sei); + hdr10_plus_sei->maxscl[0][2]) / 10; - Metadata->EBZCurveParameters.Sx = hdr10_plus_sei->knee_point_x[0]; - Metadata->EBZCurveParameters.Sy = hdr10_plus_sei->knee_point_y[0]; - Metadata->EBZCurveParameters.order = + /*hdmitx vsif block have no maxscl,we can choose distribution value[8]*/ + if (!metadata->maxscenesourceluminance) + metadata->maxscenesourceluminance = + hdr10_plus_sei->distribution_values[0][8] / 10; + + metadata->minluminance = MIN_LUMINANCE; + metadata->referenceluminance = + hdr10_plus_sei->targeted_system_display_maximum_luminance; + percentileinit(&metadata->percentiles, hdr10_plus_sei); + + metadata->ebzcurveparameters.sx = hdr10_plus_sei->knee_point_x[0]; + metadata->ebzcurveparameters.sy = hdr10_plus_sei->knee_point_y[0]; + metadata->ebzcurveparameters.order = hdr10_plus_sei->num_bezier_curve_anchors[0]; for (i = 0; i < N - 1; i++) - Metadata->EBZCurveParameters.Anchor[i] = + metadata->ebzcurveparameters.anchor[i] = hdr10_plus_sei->bezier_curve_anchors[0][i]; } /* get EBZcurve params from metadata.*/ -void getMetaData(struct Scene2094Metadata *metadata, - struct EBZCurveParameters *referenceBezierParams) +void getmetadata( + struct scene2094metadata *metadata, + struct ebzcurveparameters *referencebezierparams) { int i; - referenceBezierParams->order = metadata->EBZCurveParameters.order + 1; - referenceBezierParams->Sy = metadata->EBZCurveParameters.Sy; - referenceBezierParams->Sx = metadata->EBZCurveParameters.Sx; - for (i = 0; i < referenceBezierParams->order; i++) - referenceBezierParams->Anchor[i] = - metadata->EBZCurveParameters.Anchor[i]; + if (metadata->ebzcurveparameters.order) { + referencebezierparams->order = + metadata->ebzcurveparameters.order + 1; + referencebezierparams->sy = metadata->ebzcurveparameters.sy; + referencebezierparams->sx = metadata->ebzcurveparameters.sx; + for (i = 0; i < referencebezierparams->order; i++) + referencebezierparams->anchor[i] = + metadata->ebzcurveparameters.anchor[i]; + } else { + referencebezierparams->order = 10; + } } /*TV side default setting: bezier curve params to gen basic OOTF curve*/ -void BasisOOTF_Params_init(struct BasisOOTF_Params *BasisOOTF_Params) +void basisootf_params_init(struct basisootf_params *basisootf_params) { - int P2ToP9_MAX1_init[ORDER - 2] = { + int p2top9_max1_init[ORDER - 2] = { 0.5582 * PORCESSING_DATA_MAX, 0.6745 * PORCESSING_DATA_MAX, 0.7703 * PORCESSING_DATA_MAX, 0.8231 * PORCESSING_DATA_MAX, 0.8729 * PORCESSING_DATA_MAX, 0.9130 * PORCESSING_DATA_MAX, 0.9599 * PORCESSING_DATA_MAX, 0.9844 * PORCESSING_DATA_MAX }; - int P2ToP9_MAX2_init[ORDER - 2] = { + int p2top9_max2_init[ORDER - 2] = { 0.4839 * PORCESSING_DATA_MAX, 0.6325 * PORCESSING_DATA_MAX, 0.7253 * PORCESSING_DATA_MAX, 0.7722 * PORCESSING_DATA_MAX, 0.8201 * PORCESSING_DATA_MAX, 0.8837 * PORCESSING_DATA_MAX, @@ -125,61 +143,62 @@ void BasisOOTF_Params_init(struct BasisOOTF_Params *BasisOOTF_Params) int i; /*u12*/ - BasisOOTF_Params->SY1_V1 = 0 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY1_V2 = 1229 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY1_T1 = 901 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY1_T2 = 4095 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY2_V1 = 0 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY2_V2 = 819 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY2_T1 = 1024 << (PROCESSING_MAX - 12); - BasisOOTF_Params->SY2_T2 = 3890 << (PROCESSING_MAX - 12); + basisootf_params->SY1_V1 = 0 << (PROCESSING_MAX - 12); + basisootf_params->SY1_V2 = 1229 << (PROCESSING_MAX - 12); + basisootf_params->SY1_T1 = 901 << (PROCESSING_MAX - 12); + basisootf_params->SY1_T2 = 4095 << (PROCESSING_MAX - 12); + basisootf_params->SY2_V1 = 0 << (PROCESSING_MAX - 12); + basisootf_params->SY2_V2 = 819 << (PROCESSING_MAX - 12); + basisootf_params->SY2_T1 = 1024 << (PROCESSING_MAX - 12); + basisootf_params->SY2_T2 = 3890 << (PROCESSING_MAX - 12); /* KP mixing gain (final KP from bounds KP # 1 and KP # 2*/ /*as a function of scene percentile) */ - BasisOOTF_Params->KP_G_V1 = 4095 << (PROCESSING_MAX - 12); - BasisOOTF_Params->KP_G_V2 = 205 << (PROCESSING_MAX - 12); - BasisOOTF_Params->KP_G_T1 = 205 << (PROCESSING_MAX - 12); - BasisOOTF_Params->KP_G_T2 = 2048 << (PROCESSING_MAX - 12); + basisootf_params->KP_G_V1 = 4095 << (PROCESSING_MAX - 12); + basisootf_params->KP_G_V2 = 205 << (PROCESSING_MAX - 12); + basisootf_params->KP_G_T1 = 205 << (PROCESSING_MAX - 12); + basisootf_params->KP_G_T2 = 2048 << (PROCESSING_MAX - 12); /*Thresholds of minimum bound of P1 coefficient*/ - BasisOOTF_Params->P1_LIMIT_V1 = 3767 << (PROCESSING_MAX - 12); - BasisOOTF_Params->P1_LIMIT_V2 = 4013 << (PROCESSING_MAX - 12); - BasisOOTF_Params->P1_LIMIT_T1 = 41 << (PROCESSING_MAX - 12); - BasisOOTF_Params->P1_LIMIT_T2 = 410 << (PROCESSING_MAX - 12); + basisootf_params->P1_LIMIT_V1 = 3767 << (PROCESSING_MAX - 12); + basisootf_params->P1_LIMIT_V2 = 4013 << (PROCESSING_MAX - 12); + basisootf_params->P1_LIMIT_T1 = 41 << (PROCESSING_MAX - 12); + basisootf_params->P1_LIMIT_T2 = 410 << (PROCESSING_MAX - 12); /*Thresholds to compute relative shape of curve (P2~P9 coefficient)*/ /*by pre-defined bounds - as a function of scene percentile*/ - BasisOOTF_Params->P2To9_T1 = 205 << (PROCESSING_MAX - 12); - BasisOOTF_Params->P2To9_T2 = 2252 << (PROCESSING_MAX - 12); + basisootf_params->P2TO9_T1 = 205 << (PROCESSING_MAX - 12); + basisootf_params->P2TO9_T2 = 2252 << (PROCESSING_MAX - 12); for (i = 0; i < (ORDER - 2); i++) { - BasisOOTF_Params->P2ToP9_MAX1[i] = P2ToP9_MAX1_init[i]; - BasisOOTF_Params->P2ToP9_MAX2[i] = P2ToP9_MAX2_init[i]; + basisootf_params->P2TOP9_MAX1[i] = p2top9_max1_init[i]; + basisootf_params->P2TOP9_MAX2[i] = p2top9_max2_init[i]; } /*Ps mixing gain (obtain all Ps coefficients) -*/ /*as a function of TM dynamic compression ratio*/ - BasisOOTF_Params->PS_G_T1 = 512 << (PROCESSING_MAX - 12); - BasisOOTF_Params->PS_G_T2 = 3890 << (PROCESSING_MAX - 12); + basisootf_params->PS_G_T1 = 512 << (PROCESSING_MAX - 12); + basisootf_params->PS_G_T2 = 3890 << (PROCESSING_MAX - 12); /*Post-processing : Reduce P1/P2 (to enhance mid tone)*/ /*for high TM dynamic range compression cases*/ - BasisOOTF_Params->LOW_SY_T1 = 20 << (PROCESSING_MAX - 12); - BasisOOTF_Params->LOW_SY_T2 = 164 << (PROCESSING_MAX - 12); - BasisOOTF_Params->LOW_K_T1 = 491 << (PROCESSING_MAX - 12); - BasisOOTF_Params->LOW_K_T2 = 1638 << (PROCESSING_MAX - 12); - BasisOOTF_Params->RED_P1_V1 = 2662 << (PROCESSING_MAX - 12); - BasisOOTF_Params->RED_P1_T1 = 410 << (PROCESSING_MAX - 12); - BasisOOTF_Params->RED_P1_T2 = 3071 << (PROCESSING_MAX - 12); - BasisOOTF_Params->RED_P2_V1 = 3276 << (PROCESSING_MAX - 12); - BasisOOTF_Params->RED_P2_T1 = 410 << (PROCESSING_MAX - 12); - BasisOOTF_Params->RED_P2_T2 = 3071 << (PROCESSING_MAX - 12); + basisootf_params->LOW_SY_T1 = 20 << (PROCESSING_MAX - 12); + basisootf_params->LOW_SY_T2 = 164 << (PROCESSING_MAX - 12); + basisootf_params->LOW_K_T1 = 491 << (PROCESSING_MAX - 12); + basisootf_params->LOW_K_T2 = 1638 << (PROCESSING_MAX - 12); + basisootf_params->RED_P1_V1 = 2662 << (PROCESSING_MAX - 12); + basisootf_params->RED_P1_T1 = 410 << (PROCESSING_MAX - 12); + basisootf_params->RED_P1_T2 = 3071 << (PROCESSING_MAX - 12); + basisootf_params->RED_P2_V1 = 3276 << (PROCESSING_MAX - 12); + basisootf_params->RED_P2_T1 = 410 << (PROCESSING_MAX - 12); + basisootf_params->RED_P2_T2 = 3071 << (PROCESSING_MAX - 12); } /*obtain percentile info on psl50 and psl99,*/ /*to calculate content average level and distribution later*/ -void getPercentile_50_99(struct Percentiles *scenePercentiles, - int *psll50, int *psll99) +void getpercentile_50_99( + struct percentiles *scenepercentiles, + int *psll50, int *psll99) { int i; int npsll = PERCENTILE_ORDER; @@ -192,8 +211,8 @@ void getPercentile_50_99(struct Percentiles *scenePercentiles, int psll99_2 = -1, per99_2 = -1; /* Search for exact percent index or bounds*/ - int curPercent = 0, prevPercent = 0; - int curPsll = 0, prevPsll = 0; + int curpercent = 0, prevpercent = 0; + int curpsll = 0, prevpsll = 0; /*Set output to -1 (invalid)*/ *psll50 = -1; @@ -202,28 +221,31 @@ void getPercentile_50_99(struct Percentiles *scenePercentiles, for (i = 0; i < npsll; i++) { if (i == 1 || i == 2) continue; - curPercent = scenePercentiles->percentilePercent[i]; - curPsll = scenePercentiles->percentileValue[i]; - if (curPercent == 50) - *psll50 = curPsll; - else if (*psll50 == -1 && curPercent > 50 && prevPercent < 50) { - per50_1 = prevPercent; - per50_2 = curPercent; - psll50_1 = prevPsll; - psll50_2 = curPsll; + curpercent = scenepercentiles->percentilepercent[i]; + curpsll = scenepercentiles->percentilevalue[i]; + if (curpercent == 50) { + *psll50 = curpsll; + } else if ( + *psll50 == -1 && + curpercent > 50 && + prevpercent < 50) { + per50_1 = prevpercent; + per50_2 = curpercent; + psll50_1 = prevpsll; + psll50_2 = curpsll; } - if (curPercent == 99) { - *psll99 = curPsll; - } else if (*psll99 == -1 && curPercent > 99 && - prevPercent < 99) { - per99_1 = prevPercent; - per99_2 = curPercent; - psll99_1 = prevPsll; - psll99_2 = curPsll; + if (curpercent == 99) { + *psll99 = curpsll; + } else if (*psll99 == -1 && curpercent > 99 && + prevpercent < 99) { + per99_1 = prevpercent; + per99_2 = curpercent; + psll99_1 = prevpsll; + psll99_2 = curpsll; } - prevPercent = curPercent; - prevPsll = curPsll; + prevpercent = curpercent; + prevpsll = curpsll; } if (*psll50 == -1) { @@ -240,7 +262,7 @@ void getPercentile_50_99(struct Percentiles *scenePercentiles, } /* function to calculate linear interpolation*/ -int rampWeight(int v1, int v2, int t1, int t2, int t) +int rampweight(int v1, int v2, int t1, int t2, int t) { int retVal = v1; @@ -260,8 +282,9 @@ int rampWeight(int v1, int v2, int t1, int t2, int t) /*p1 calculation based on default setting and*/ /*content statistic information(percentile)*/ -int calcP1(int sx, int sy, int tgtL, int calcMaxL, - struct BasisOOTF_Params *basisOOTF_Params, +int calcp1( + int sx, int sy, int tgtL, int calcmaxl, + struct basisootf_params *basisootf_params, int *p1_red_gain) { @@ -271,23 +294,34 @@ int calcP1(int sx, int sy, int tgtL, int calcMaxL, ax = min(sx, PORCESSING_DATA_MAX); ay = min(sy, PORCESSING_DATA_MAX); - k = tgtL * PORCESSING_DATA_MAX / max(tgtL, calcMaxL); - p1_limit = rampWeight(basisOOTF_Params->P1_LIMIT_V2, - basisOOTF_Params->P1_LIMIT_V1, - basisOOTF_Params->P1_LIMIT_T1, - basisOOTF_Params->P1_LIMIT_T2, sy); + k = tgtL * PORCESSING_DATA_MAX / max(tgtL, calcmaxl); + p1_limit = rampweight( + basisootf_params->P1_LIMIT_V2, + basisootf_params->P1_LIMIT_V1, + basisootf_params->P1_LIMIT_T1, + basisootf_params->P1_LIMIT_T2, + sy); k2 = (PORCESSING_DATA_MAX + 1 - ax) * PORCESSING_DATA_MAX / (ORDER * (PORCESSING_DATA_MAX + 1 - ay)); p1_t = k2 * PORCESSING_DATA_MAX / k; p1 = max(min(p1_t, p1_limit), 0); - low_sy_g = rampWeight(PORCESSING_DATA_MAX + 1, 0, - basisOOTF_Params->LOW_SY_T1, basisOOTF_Params->LOW_SY_T2, sy); - high_k_g = rampWeight(PORCESSING_DATA_MAX + 1, 0, - basisOOTF_Params->LOW_K_T1, basisOOTF_Params->LOW_K_T2, k); + low_sy_g = rampweight( + PORCESSING_DATA_MAX + 1, 0, + basisootf_params->LOW_SY_T1, + basisootf_params->LOW_SY_T2, + sy); + high_k_g = rampweight( + PORCESSING_DATA_MAX + 1, 0, + basisootf_params->LOW_K_T1, + basisootf_params->LOW_K_T2, + k); high_tm_g = low_sy_g * high_k_g >> PROCESSING_MAX; - red_p1 = rampWeight(PORCESSING_DATA_MAX + 1, - basisOOTF_Params->RED_P1_V1, basisOOTF_Params->RED_P1_T1, - basisOOTF_Params->RED_P1_T2, high_tm_g); + red_p1 = rampweight( + PORCESSING_DATA_MAX + 1, + basisootf_params->RED_P1_V1, + basisootf_params->RED_P1_T1, + basisootf_params->RED_P1_T2, + high_tm_g); p1 = min(max((p1 * red_p1) >> PROCESSING_MAX, P1MIN), p1_limit); if (p1_red_gain != NULL) @@ -298,30 +332,46 @@ int calcP1(int sx, int sy, int tgtL, int calcMaxL, /*gen BasisOOTF parameters (sx,sy,p1~pn-1),based on content percentiles*/ /*and default bezier params*/ -int basisOOTF(struct Scene2094Metadata *metadata, - struct BasisOOTF_Params *basisOOTF_Params, int productPeak, - int sourceMaxL, struct EBZCurveParameters *sceneBezierParams) +int basisootf( + struct scene2094metadata *metadata, + struct basisootf_params *basisootf_params, int productpeak, + int sourcemaxl, struct ebzcurveparameters *scenebezierparams) { int order = ORDER; - int psll50, psll99, centerLuminance, k, sy1, sy2, sy, sx, rem; + int psll50, psll99, centerluminance, k, sy1, sy2, sy, sx, rem; int high_tm_g, p1, rem_p29, rem_ps, rem_red_p2, ps2to9[ORDER - 1]; int coeffi, plin[ORDER - 1], pcoeff[ORDER - 1]; - int targetLuminance = productPeak; - int sourceLuminance = max(targetLuminance, sourceMaxL); + int targetluminance = productpeak; + int sourceluminance = max(targetluminance, sourcemaxl); int i; - getPercentile_50_99(&(metadata->percentiles), &psll50, &psll99); + getpercentile_50_99(&metadata->percentiles, &psll50, &psll99); - centerLuminance = psll50 * PORCESSING_DATA_MAX / max(psll99, 1); - k = targetLuminance * PORCESSING_DATA_MAX / sourceLuminance; + centerluminance = psll50 * PORCESSING_DATA_MAX / max(psll99, 1); + k = targetluminance * PORCESSING_DATA_MAX / sourceluminance; - sy1 = rampWeight(basisOOTF_Params->SY1_V1, basisOOTF_Params->SY1_V2, - basisOOTF_Params->SY1_T1, basisOOTF_Params->SY1_T2, k); - sy2 = rampWeight(basisOOTF_Params->SY2_V1, basisOOTF_Params->SY2_V2, - basisOOTF_Params->SY2_T1, basisOOTF_Params->SY2_T2, k); - rem = rampWeight(basisOOTF_Params->KP_G_V1, basisOOTF_Params->KP_G_V2, - basisOOTF_Params->KP_G_T1, basisOOTF_Params->KP_G_T2, - centerLuminance); + if (hdr10_plus_printk & 2) + pr_hdr( + "basisOOTF precision: ctrL=%d, k=%d\n", + centerluminance, k); + sy1 = rampweight( + basisootf_params->SY1_V1, + basisootf_params->SY1_V2, + basisootf_params->SY1_T1, + basisootf_params->SY1_T2, + k); + sy2 = rampweight( + basisootf_params->SY2_V1, + basisootf_params->SY2_V2, + basisootf_params->SY2_T1, + basisootf_params->SY2_T2, + k); + rem = rampweight( + basisootf_params->KP_G_V1, + basisootf_params->KP_G_V2, + basisootf_params->KP_G_T1, + basisootf_params->KP_G_T2, + centerluminance); sy = (rem * sy1 + (PORCESSING_DATA_MAX + 1 - rem) * sy2) >> PROCESSING_MAX; sx = sy * k; @@ -329,157 +379,265 @@ int basisOOTF(struct Scene2094Metadata *metadata, /*P coefficient*/ high_tm_g = 0; - p1 = calcP1(sx, sy, targetLuminance, sourceMaxL, - basisOOTF_Params, &high_tm_g); + p1 = calcp1( + sx, sy, targetluminance, sourcemaxl, + basisootf_params, &high_tm_g); + if (hdr10_plus_printk & 2) + pr_hdr("basisOOTF precision: p1=(int) %d\n\n", p1); for (i = 0; i < (NPCOEFF - 1); i++) { - rem_p29 = rampWeight(basisOOTF_Params->P2ToP9_MAX2[i], - basisOOTF_Params->P2ToP9_MAX1[i], basisOOTF_Params->P2To9_T1, - basisOOTF_Params->P2To9_T2, centerLuminance); - ps2to9[i] = (rem_p29 * basisOOTF_Params->P2ToP9_MAX1[i] + + rem_p29 = rampweight( + basisootf_params->P2TOP9_MAX2[i], + basisootf_params->P2TOP9_MAX1[i], + basisootf_params->P2TO9_T1, + basisootf_params->P2TO9_T2, + centerluminance); + ps2to9[i] = (rem_p29 * basisootf_params->P2TOP9_MAX1[i] + (PORCESSING_DATA_MAX + 1 - rem_p29) * - basisOOTF_Params->P2ToP9_MAX2[i]) >> PROCESSING_MAX; + basisootf_params->P2TOP9_MAX2[i]) >> PROCESSING_MAX; + if (hdr10_plus_printk & 2) + pr_hdr( + "basisOOTF precision: g=%d ps2to9[%d] = %d\n", + rem_p29, i, ps2to9[i]); } - rem_ps = rampWeight(PORCESSING_DATA_MAX + 1, 0, - basisOOTF_Params->PS_G_T1, basisOOTF_Params->PS_G_T2, k); + rem_ps = rampweight( + PORCESSING_DATA_MAX + 1, 0, + basisootf_params->PS_G_T1, basisootf_params->PS_G_T2, k); pcoeff[0] = p1; for (i = 1; i < NPCOEFF; i++) { coeffi = i + 1; plin[i] = (coeffi * PORCESSING_DATA_MAX / order); - pcoeff[i] = max(min((rem_ps * ps2to9[i - 1] + - (PORCESSING_DATA_MAX + 1 - rem_ps) * plin[i]) >> PROCESSING_MAX, - coeffi * p1), plin[i]); + pcoeff[i] = max( + min((rem_ps * ps2to9[i - 1] + + (PORCESSING_DATA_MAX + 1 - rem_ps) * plin[i]) + >> PROCESSING_MAX, + coeffi * p1), + plin[i]); + if (hdr10_plus_printk & 2) + pr_hdr( + "basisOOTF precision: g=%d, pcoeff[%d] = %d\n", + rem_ps, i, pcoeff[i]); } /*p[1] recalc precision:0.01,bad*/ - rem_red_p2 = rampWeight(PORCESSING_DATA_MAX + 1, - basisOOTF_Params->RED_P2_V1, basisOOTF_Params->RED_P2_T1, - basisOOTF_Params->RED_P2_T2, high_tm_g); - pcoeff[1] = max(min((pcoeff[1] * rem_red_p2) >> PROCESSING_MAX, 2 * p1), - 2 * PORCESSING_DATA_MAX / ORDER); + rem_red_p2 = rampweight( + PORCESSING_DATA_MAX + 1, + basisootf_params->RED_P2_V1, + basisootf_params->RED_P2_T1, + basisootf_params->RED_P2_T2, + high_tm_g); + pcoeff[1] = max( + min((pcoeff[1] * rem_red_p2) >> PROCESSING_MAX, 2 * p1), + 2 * PORCESSING_DATA_MAX / ORDER); /*finally pcoeff[ORDER-1],sy,sx*/ - sceneBezierParams->Sx = sx; - sceneBezierParams->Sy = sy; + scenebezierparams->sx = sx; + scenebezierparams->sy = sy; /*only calc ORDER(10) < actual order(15)*/ for (i = 0; i < NPCOEFF; i++) - sceneBezierParams->Anchor[i] = pcoeff[i]; - + scenebezierparams->anchor[i] = pcoeff[i]; + if (hdr10_plus_printk & 2) { + pr_hdr("default P setting:\n"); + for (i = 0; i < NPCOEFF; i++) + pr_hdr("%2d: %d\n", i, pcoeff[i]); + } return 0; } /* receive bezier parameter(Kx,ky,P)and return guided parameter base on*/ /*product panel luminance out: product curve params(Kx,ky,P) */ -int GuidedOOTF(struct Scene2094Metadata *metadata, - struct BasisOOTF_Params *basisOOTF_Params, - struct EBZCurveParameters *referenceBezierParams, - int ProductLuminance, - struct EBZCurveParameters *productBezierParams) +int guidedootf( + struct scene2094metadata *metadata, + struct basisootf_params *basisootf_params, + struct ebzcurveparameters *referencebezierparams, + int productpeak, + struct ebzcurveparameters *productbezierparams) { int KP_BYPASS = 1229; - int refenceLuminance = metadata->referenceLuminance; - int productLuminance = ProductLuminance; - int minLuminance = metadata->minLuminance; - int maxLuminance = metadata->maxSceneSourceLuminance; - int order = referenceBezierParams->order; - int numP = order - 1; + int refenceluminance = metadata->referenceluminance; + int productluminance = productpeak; + int minluminance = metadata->minluminance; + int maxluminance = metadata->maxscenesourceluminance; + int order = referencebezierparams->order; + int nump = order - 1; int blendCoeff, norm; int anchorLinear[14]; int i; int ps1; - struct EBZCurveParameters minBezierParams; + struct ebzcurveparameters minbezierparams; - EBZCurveParametersInit(&minBezierParams); + ebzcurveparametersinit(&minbezierparams); - for (i = 0; i < numP; i++) + for (i = 0; i < nump; i++) anchorLinear[i] = (i + 1) * PORCESSING_DATA_MAX / order; + if (hdr10_plus_printk & 2) { + pr_hdr( + "order = %d, linear ps[i]:\n", + order); + for (i = 0; i < nump; i++) + pr_hdr( + " %2d: %4d\n", + i, anchorLinear[i]); + } + + /*patch for low luminance panel tm calculate, find rootcause next step*/ + if (force_ref_peak) { + refenceluminance = force_ref_peak; + if (refenceluminance < 250) + refenceluminance = 0; + } /*---------case 0: productPeak < minL ----------------- */ - if (productLuminance < minLuminance) { - productBezierParams->Sx = 0; - productBezierParams->Sy = 0; - for (i = 0; i < numP; i++) - productBezierParams->Anchor[i] = anchorLinear[i]; - productBezierParams->order = order; + if (productluminance < minluminance) { + if (hdr10_plus_printk & 2) { + pr_hdr("case: P < minL\n\n...processing...\n"); + pr_hdr( + "error GuidedOOTF: < %d nit not supported\n", + productluminance); + } + productbezierparams->sx = 0; + productbezierparams->sy = 0; + for (i = 0; i < nump; i++) + productbezierparams->anchor[i] = anchorLinear[i]; + productbezierparams->order = order; return -1; } /*---------case 1: productPeak = ref ----------------- */ - if (productLuminance == refenceLuminance) { - productBezierParams->Sx = referenceBezierParams->Sx; - productBezierParams->Sy = referenceBezierParams->Sy; - productBezierParams->order = referenceBezierParams->order; + if (productluminance == refenceluminance) { + if (hdr10_plus_printk & 2) + pr_hdr("case: P = ref\n\n...processing...\n"); + productbezierparams->sx = referencebezierparams->sx; + productbezierparams->sy = referencebezierparams->sy; + productbezierparams->order = referencebezierparams->order; - for (i = 0; i < numP; i++) { - productBezierParams->Anchor[i] = - referenceBezierParams->Anchor[i]; + for (i = 0; i < nump; i++) + productbezierparams->anchor[i] = + referencebezierparams->anchor[i]; + if (hdr10_plus_printk & 2) { + pr_hdr( + "order:%2d, (sx,sy):(%4d, %4d)\n", + productbezierparams->order, + productbezierparams->sx, + productbezierparams->sy); + for (i = 0; i < nump; i++) + pr_hdr( + " %2d: %4d\n", + i, productbezierparams->anchor[i]); } } /*---------case 2: productPeak > maxL ----------------- */ - else if (productLuminance > maxLuminance) { - productBezierParams->Sx = KP_BYPASS; - productBezierParams->Sy = KP_BYPASS; - productBezierParams->order = order; - for (i = 0; i < numP; i++) - productBezierParams->Anchor[i] = anchorLinear[i]; + else if (productluminance > maxluminance) { + if (hdr10_plus_printk & 2) + pr_hdr("case: P > maxL\n\n...processing...\n"); + productbezierparams->sx = KP_BYPASS; + productbezierparams->sy = KP_BYPASS; + productbezierparams->order = order; + for (i = 0; i < nump; i++) + productbezierparams->anchor[i] = anchorLinear[i]; } /*---------case 3: minL < productPeak < maxL ----------------- */ else { - productBezierParams->order = referenceBezierParams->order; + productbezierparams->order = referencebezierparams->order; /*---------case 3.1: minL < productPeak < ref ----------------- */ - if (productLuminance < refenceLuminance) { - norm = refenceLuminance - minLuminance; - blendCoeff = refenceLuminance - productLuminance; + if (productluminance < refenceluminance) { + if (hdr10_plus_printk & 2) + pr_hdr("case: P < ref\n\n...processing...\n"); + norm = refenceluminance - minluminance; + blendCoeff = refenceluminance - productluminance; - basisOOTF(metadata, basisOOTF_Params, minLuminance, - maxLuminance, &minBezierParams); + basisootf( + metadata, basisootf_params, minluminance, + maxluminance, &minbezierparams); - productBezierParams->Sy = - (blendCoeff * minBezierParams.Sy + - (norm - blendCoeff) * referenceBezierParams->Sy + + productbezierparams->sy = + (blendCoeff * minbezierparams.sy + + (norm - blendCoeff) * referencebezierparams->sy + (norm >> 1)) / norm; - productBezierParams->Sx = - productBezierParams->Sy * productLuminance / - maxLuminance; - for (i = 0; i < numP ; i++) { - productBezierParams->Anchor[i] = - (blendCoeff * referenceBezierParams->Anchor[i] + + productbezierparams->sx = + productbezierparams->sy * productluminance / + maxluminance; + for (i = 0; i < nump ; i++) { + productbezierparams->anchor[i] = + (blendCoeff * minbezierparams.anchor[i] + (norm - blendCoeff) * - minBezierParams.Anchor[i] + + referencebezierparams->anchor[i] + (norm >> 1)) / norm; } -/*---------case 3.2: ref < productPeak < maxL ----------------- */ + if (hdr10_plus_printk & 2) { + pr_hdr( + "p-1=>Anchor[i] = (blendCoeff *referenceBezierParams->Anchor[i] + (norm - blendCoeff)*minBezierParams.Anchor[i] + (norm>>1) )/norm\n"); + for (i = 0; i < nump; i++) { + pr_hdr( + "p-1=> %2d: %4d = %4d * %4d + (%4d - %4d) * %4d / %4d\n", + i, + productbezierparams->anchor[i], + blendCoeff, + referencebezierparams->anchor[i], + norm, + blendCoeff, + minbezierparams.anchor[i], + norm); + } + } + /*---------case 3.2: ref < productPeak < maxL ----------------- */ } else { - norm = maxLuminance - refenceLuminance; - blendCoeff = productLuminance - refenceLuminance; + if (hdr10_plus_printk & 2) + pr_hdr("case: P > ref\n\n...processing...\n"); + norm = maxluminance - refenceluminance; + blendCoeff = productluminance - refenceluminance; - productBezierParams->Sy = (blendCoeff * KP_BYPASS + - (norm - blendCoeff) * referenceBezierParams->Sy + + productbezierparams->sy = (blendCoeff * KP_BYPASS + + (norm - blendCoeff) * referencebezierparams->sy + (norm >> 1)) / norm; - productBezierParams->Sx = productBezierParams->Sy * - productLuminance / maxLuminance; + productbezierparams->sx = productbezierparams->sy * + productluminance / maxluminance; - for (i = 0; i < numP ; i++) { - productBezierParams->Anchor[i] = + for (i = 0; i < nump; i++) { + productbezierparams->anchor[i] = (blendCoeff * anchorLinear[i] + (norm - blendCoeff) * - referenceBezierParams->Anchor[i] + + referencebezierparams->anchor[i] + (norm >> 1)) / norm; } + if (hdr10_plus_printk & 2) { + for (i = 0; i < nump; i++) { + pr_hdr( + "p-1=> %2d: %4d = %4d * %4d + (%4d - %4d) * %4d/ %4d\n", + i, + productbezierparams->anchor[i], + blendCoeff, + anchorLinear[i], + norm, + blendCoeff, + referencebezierparams->anchor[i], + norm); + } + } } - ps1 = calcP1(productBezierParams->Sx, productBezierParams->Sy, - productLuminance, maxLuminance, basisOOTF_Params, NULL); + ps1 = calcp1( + productbezierparams->sx, productbezierparams->sy, + productluminance, maxluminance, basisootf_params, NULL); - productBezierParams->Anchor[0] = ps1; + productbezierparams->anchor[0] = ps1; - for (i = 1; i < numP; i++) { - productBezierParams->Anchor[i] = - min(productBezierParams->Anchor[i], - (i + 1) * productBezierParams->Anchor[0]); + for (i = 1; i < nump; i++) { + productbezierparams->anchor[i] = + min( + productbezierparams->anchor[i], + (i + 1) * productbezierparams->anchor[0]); + } + if (hdr10_plus_printk & 2) { + pr_hdr("p-2: %2d, %4d\n", 0, ps1); + // p process, form curve below CI line slope + for (i = 1; i < nump; i++) + pr_hdr( + "p-2=> %2d-> %d\n", + i, productbezierparams->anchor[i]); } } @@ -487,30 +645,31 @@ int GuidedOOTF(struct Scene2094Metadata *metadata, } /*bezier optimise method to gen bezier function*/ -int Decasteliau(uint64_t *BezierCurve, uint64_t *AnchorY, - uint64_t u, int order, uint64_t range_ebz_x) +int Decasteliau( + u64 *beziercurve, u64 *anchory, + u64 u, int order, u64 range_ebz_x) { - uint64_t PointY[16]; + u64 pointy[16]; int i, j; for (i = 0; i < order + 1; i++) - PointY[i] = AnchorY[i]; + pointy[i] = anchory[i]; for (i = 1; i <= order; i++) for (j = 0; j <= order - i; j++) { - PointY[j] = (PointY[j] * (range_ebz_x - u) + - PointY[j + 1] * u + range_ebz_x / 2); - PointY[j] = div64_u64(PointY[j], range_ebz_x); + pointy[j] = (pointy[j] * (range_ebz_x - u) + + pointy[j + 1] * u + range_ebz_x / 2); + pointy[j] = div64_u64(pointy[j], range_ebz_x); } - BezierCurve[1] = PointY[0]; + beziercurve[1] = pointy[0]; return 0; } #define org_anchory uint64_t oo_lut_x[OOLUT_NUM] = { - 0, 16, 32, 64, 128, 256, 512, 1024, 2048, 2560, 3072, 3584, 4096, + 1, 16, 32, 64, 128, 256, 512, 1024, 2048, 2560, 3072, 3584, 4096, 5120, 6144, 7168, 8192, 10240, 12288, 14336, 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536, 81920, 98304, 114688, 131072, 163840, 196608, 229376, 262144, 327680, 393216, 458752, @@ -535,43 +694,44 @@ uint64_t oo_lut_x[OOLUT_NUM] = { }; /*gen OOTF curve and gain from (sx,sy) and P1~pn-1*/ -int genEBZCurve(uint64_t *CurveX, uint64_t *CurveY, +int genEBZCurve( + u64 *curvex, u64 *curvey, unsigned int *gain, unsigned int *gain_ter, - uint64_t nKx, uint64_t nKy, - uint64_t *AnchorY, int order) + u64 nkx, uint64_t nky, + u64 *anchory, int order) { - uint64_t myAnchorY[16]; - uint64_t temp; - uint64_t linearX[POINTS]; - uint64_t Kx, Ky; + u64 myAnchorY[16]; + u64 temp; + u64 linearx[POINTS]; + u64 kx, ky; - uint64_t range_ebz_x; - uint64_t range_ebz_y; + u64 range_ebz_x; + u64 range_ebz_y; - uint64_t step_alpha; - uint64_t step_ter[POINTS]; - uint64_t BezierCurve[2]; + u64 step_alpha; + u64 step_ter[POINTS]; + u64 beziercurve[2]; int i; - int numP = N-1; + int nump = N - 1; /*u12->U16*/ - Kx = nKx<<(U32 - PROCESSING_MAX); - Ky = nKy<<(U32 - PROCESSING_MAX); + kx = nkx << (U32 - PROCESSING_MAX); + ky = nky << (U32 - PROCESSING_MAX); - range_ebz_x = _U32_MAX - Kx; - range_ebz_y = _U32_MAX - Ky; + range_ebz_x = _U32_MAX - kx; + range_ebz_y = _U32_MAX - ky; #ifdef org_anchory - for (i = 0; i < numP; i++)/* u12-> ebz_y, u32*/ + for (i = 0; i < nump; i++)/* u12-> ebz_y, u32*/ /*anchorY default range:PROCESSING_MAX */ - myAnchorY[i + 1] = AnchorY[i] << (U32-PROCESSING_MAX); + myAnchorY[i + 1] = anchory[i] << (U32 - PROCESSING_MAX); myAnchorY[0] = 0; myAnchorY[N] = _U32_MAX; /* u12 */ #else - for (i = 0; i < numP; i++)/* u12-> ebz_y, u32*/ + for (i = 0; i < nump; i++)/* u12-> ebz_y, u32*/ /*anchorY default range:PROCESSING_MAX */ - myAnchorY[i + 1] = (AnchorY[i] * range_ebz_y) >> PROCESSING_MAX; + myAnchorY[i + 1] = (anchory[i] * range_ebz_y) >> PROCESSING_MAX; myAnchorY[0] = 0; myAnchorY[N] = range_ebz_y; /*u12 -> U32*/ #endif /* org_anchory */ @@ -580,54 +740,47 @@ int genEBZCurve(uint64_t *CurveX, uint64_t *CurveY, #if 0 linearX[i] = (uint64_t)(i*_U32_MAX/POINTS); /* x index sample */ #else - linearX[i] = oo_lut_x[i];/* x index sample,u32 */ + linearx[i] = oo_lut_x[i];/* x index sample,u32 */ #endif - CurveY[i] = 0; + curvey[i] = 0; step_ter[i] = 1023; } for (i = 0; i < POINTS; i++) { - if (linearX[i] < Kx) { - CurveX[i] = linearX[i];/*u32*/ - CurveY[i] = linearX[i] * Ky; - CurveY[i] = div64_u64(CurveY[i], Kx + 1); - temp = CurveY[i] << GAIN_BIT;/*u12*/ - gain[i] = div64_u64(temp, CurveX[i] + 1); + if (linearx[i] < kx) { + curvex[i] = linearx[i];/*u32*/ + curvey[i] = linearx[i] * ky; + curvey[i] = div64_u64(curvey[i], kx ? kx : 1); + temp = curvey[i] << GAIN_BIT;/*u12*/ + gain[i] = div64_u64(temp, curvex[i]); step_ter[i] = 1024; - /*just as a mark for debugging*/ - /*printk("%d(int64):x->y,%lld->%lld,gain=%d\n",*/ - /*i, CurveX[i],CurveY[i],gain[i]);*/ } else{ - /* step_alpha = (linearX[i]-Kx)/range_ebz_x,*/ /*norm in Decasteliau() function*/ - step_alpha = (linearX[i] - Kx); + step_alpha = (linearx[i] - kx); step_ter[i] = step_alpha; /* calc each point from 1st to N-th layer*/ - Decasteliau(&BezierCurve[0], myAnchorY, step_alpha, - order, range_ebz_x); - /* u32 u32 u32*/ + Decasteliau( + &beziercurve[0], myAnchorY, step_alpha, + order, range_ebz_x); #ifdef org_anchory /*range_ebz_y = _U32_MAX*/ - CurveY[i] = Ky + ((range_ebz_y * BezierCurve[1] + - range_ebz_y / 2) >> U32); + curvey[i] = ky + + ((range_ebz_y * beziercurve[1] + range_ebz_y / 2) + >> U32); #else - CurveY[i] = Ky + ((range_ebz_y * BezierCurve[1] + + curvey[i] = ky + ((range_ebz_y * beziercurve[1] + range_ebz_y / 2)); - CurveY[i] = div64_u64(CurveY[i], range_ebz_y); + curvey[i] = div64_u64(curvey[i], range_ebz_y); #endif /* org_anchory*/ /*CurveX[i] = Kx +*/ /*((range_ebz_x * BezierCurve[0] + range_ebz_x / 2) / */ /*range_ebz_x);*/ - CurveX[i] = Kx + step_alpha; - temp = CurveY[i] << GAIN_BIT; - gain[i] = div64_u64(temp, CurveX[i] + 1); - + curvex[i] = kx + step_alpha; + temp = curvey[i] << GAIN_BIT; + gain[i] = div64_u64(temp, curvex[i]); } - temp = CurveY[i] << GAIN_BIT;/*u12*/ - gain[i] = div64_u64(temp, CurveX[i] + 1); - temp = CurveY[i] << GAIN_BIT; - gain_ter[i] = div64_u64(temp, linearX[i] + 1); } + gain[POINTS - 1] = 1 << GAIN_BIT; return 0; } @@ -635,146 +788,245 @@ void vframe_hdr_plus_sei_s_init(struct hdr10_plus_sei_s *hdr10_plus_sei) { int i; - - int percentilePercent_init[PERCENTILE_ORDER] = { + int P_init[N - 1] = {181, 406, 607, 796, 834, 863, 890, 917, 938}; + int percentilepercent_init[PERCENTILE_ORDER] = { 1, 5, 10, 25, 50, 75, 90, 95, 99}; - int percentileValue_init[PERCENTILE_ORDER] = { - 0, 1, 2, 79, 2537, 9900, 9901, 9902, 9904}; + /*int percentilevalue_init[PERCENTILE_ORDER] = {*/ + /* 0, 1, 2, 79, 2537, 9900, 9901, 9902, 9904};*/ hdr10_plus_sei->num_distributions[0] = PERCENTILE_ORDER - 1; for (i = 0; i < 3; i++) - hdr10_plus_sei->maxscl[0][i] = hdr_plus_sei.maxscl[0][i] / 10; + hdr10_plus_sei->maxscl[0][i] = hdr_plus_sei.maxscl[0][i]; hdr10_plus_sei->targeted_system_display_maximum_luminance = hdr_plus_sei.tgt_sys_disp_max_lumi; + /*for hdmitx output no number, default 9*/ + if (hdr10_plus_sei->num_distributions[0] == 0) + hdr10_plus_sei->num_distributions[0] = 9; + for (i = 0; i < (hdr10_plus_sei->num_distributions[0]); i++) { hdr10_plus_sei->distribution_index[0][i] = - percentilePercent_init[i]; - hdr10_plus_sei->distribution_values[0][i] = - percentileValue_init[i]; + hdr_plus_sei.distribution_maxrgb_percentages[0][i]; + /*hdmitx have no distribution index, default init*/ + if (hdr10_plus_sei->distribution_index[0][i] == 0) + hdr10_plus_sei->distribution_index[0][i] = + percentilepercent_init[i]; + hdr10_plus_sei->distribution_values[0][i] = + hdr_plus_sei.distribution_maxrgb_percentiles[0][i]; } hdr10_plus_sei->knee_point_x[0] = hdr_plus_sei.knee_point_x[0]; hdr10_plus_sei->knee_point_y[0] = hdr_plus_sei.knee_point_y[0]; - hdr10_plus_sei->num_bezier_curve_anchors[0] = - hdr_plus_sei.num_bezier_curve_anchors[0]; - - for (i = 0; i < (hdr10_plus_sei->num_bezier_curve_anchors[0]); i++) { - hdr10_plus_sei->bezier_curve_anchors[0][i] = - hdr_plus_sei.bezier_curve_anchors[0][i]<<(PROCESSING_MAX-10); + if (hdr_plus_sei.num_bezier_curve_anchors[0]) { + hdr10_plus_sei->num_bezier_curve_anchors[0] = + hdr_plus_sei.num_bezier_curve_anchors[0]; + for (i = 0; + i < (hdr10_plus_sei->num_bezier_curve_anchors[0]); + i++) + hdr10_plus_sei->bezier_curve_anchors[0][i] = + hdr_plus_sei.bezier_curve_anchors[0][i] << + (PROCESSING_MAX - 10); + } else { + hdr10_plus_sei->num_bezier_curve_anchors[0] = 9; + for (i = 0; i < 9; i++) + hdr10_plus_sei->bezier_curve_anchors[0][i] = + P_init[i] << (PROCESSING_MAX - 10); } /*debug--*/ - if (hdr10_plus_printk) { - + if (hdr10_plus_printk & 1) { for (i = 0; i < 3; i++) - pr_hdr("hdr10_plus_sei->maxscl[0][%d]=%d\n", + pr_hdr( + "hdr10_plus_sei->maxscl[0][%d]=%d\n", i, hdr10_plus_sei->maxscl[0][i]); - pr_hdr("targeted_system_display_maximum_luminance=%d\n", + pr_hdr( + "targeted_system_display_maximum_luminance=%d\n", hdr10_plus_sei->targeted_system_display_maximum_luminance); for (i = 0; i < (hdr10_plus_sei->num_distributions[0]); i++) { - pr_hdr("distribution_values[0][%d]=%d\n", + pr_hdr( + "distribution_values[0][%d]=%d\n", i, hdr10_plus_sei->distribution_values[0][i]); - pr_hdr("hdr10_plus_sei->distribution_index[0][%d]=%d\n", + pr_hdr( + "hdr10_plus_sei->distribution_index[0][%d]=%d\n", i, hdr10_plus_sei->distribution_index[0][i]); } - pr_hdr("hdr10_plus_sei->knee_point_x = %d\n" + pr_hdr( + "hdr10_plus_sei->knee_point_x = %d\n" "hdr10_plus_sei->knee_point_y = %d\n", hdr10_plus_sei->knee_point_x[0], hdr10_plus_sei->knee_point_y[0]); - pr_hdr("hdr10_plus_sei->num_bezier_curve_anchors[0] = %d\n", - hdr10_plus_sei->num_bezier_curve_anchors[0]); + pr_hdr( + "hdr10_plus_sei->num_bezier_curve_anchors[0] = %d\n", + hdr_plus_sei.num_bezier_curve_anchors[0]); for (i = 0; i < (hdr10_plus_sei->num_bezier_curve_anchors[0]); i++) { - pr_hdr("bezier_curve_anchors[0][%d] = ", i); - pr_hdr("%d\n", hdr_plus_sei.bezier_curve_anchors[0][i]); + pr_hdr( + "bezier_curve_anchors[0][%d] = %d\n", + i, hdr_plus_sei.bezier_curve_anchors[0][i]); } for (i = 0; i < 3; i++) { - pr_hdr("average_maxrgb[%d] = ", i); - pr_hdr("%d\n", hdr_plus_sei.average_maxrgb[i]); + pr_hdr( + "average_maxrgb[%d] = %d\n", + i, hdr_plus_sei.average_maxrgb[i]); } for (i = 0; i < (hdr_plus_sei.num_distribution_maxrgb_percentiles[0]); i++) { - pr_hdr("distribution_maxrgb_percentages[0][%d] = ", i); - pr_hdr("%d\n", - hdr_plus_sei.distribution_maxrgb_percentages[0][i]); + pr_hdr( + "distribution_maxrgb_percentages[0][%d] = %d\n", + i, hdr_plus_sei.distribution_maxrgb_percentages[0][i]); } for (i = 0; i < (hdr_plus_sei.num_distribution_maxrgb_percentiles[0]); i++) { - pr_hdr("distribution_maxrgb_percentiles[0][%d] = ", i); - pr_hdr("%d\n", - hdr_plus_sei.distribution_maxrgb_percentiles[0][i]); + pr_hdr( + "distribution_maxrgb_percentiles[0][%d] = %d\n", + i, hdr_plus_sei.distribution_maxrgb_percentiles[0][i]); } } +} +void vframe_hdr_sei_s_init( + struct hdr10_plus_sei_s *hdr10_plus_sei, + int source_lumin) +{ + int i; + int P_init[N - 1] = {181, 406, 607, 796, 834, 863, 890, 917, 938}; + int percentilepercent_init[PERCENTILE_ORDER] = { + 1, 5, 10, 25, 50, 75, 90, 95, 99 + }; + int percentilevalue_init[PERCENTILE_ORDER] = { + 0, 10000, 90, 2000, 4000, 8000, 10000, 10001, 10002 + }; + + hdr10_plus_sei->num_distributions[0] = PERCENTILE_ORDER - 1; + + for (i = 0; i < 3; i++) + hdr10_plus_sei->maxscl[0][i] = source_lumin * 10; + percentilevalue_init[1] = source_lumin * 10; + percentilevalue_init[3] = source_lumin * 2; + percentilevalue_init[4] = source_lumin * 4; + percentilevalue_init[5] = source_lumin * 8; + percentilevalue_init[6] = source_lumin * 10; + percentilevalue_init[7] = source_lumin * 10 + 1; + percentilevalue_init[8] = source_lumin * 10 + 2; + + hdr10_plus_sei->targeted_system_display_maximum_luminance = 0; + + hdr10_plus_sei->num_distributions[0] = 9; + for (i = 0; i < (hdr10_plus_sei->num_distributions[0]); i++) { + hdr10_plus_sei->distribution_index[0][i] = + percentilepercent_init[i]; + hdr10_plus_sei->distribution_values[0][i] = + percentilevalue_init[i]; + } + + hdr10_plus_sei->knee_point_x[0] = 0; + hdr10_plus_sei->knee_point_y[0] = 0; + + hdr10_plus_sei->num_bezier_curve_anchors[0] = 9; + for (i = 0; i < 9; i++) + hdr10_plus_sei->bezier_curve_anchors[0][i] = + P_init[i] << (PROCESSING_MAX - 10); + + for (i = 0; i < 3; i++) + hdr_plus_sei.average_maxrgb[i] = source_lumin; + + hdr_plus_sei.num_distribution_maxrgb_percentiles[0] = 0; } unsigned int gain[POINTS]; unsigned int gain_ter[POINTS]; -uint64_t curveX[POINTS], curveY[POINTS]; +u64 curvex[POINTS], curvey[POINTS]; + +/*input o->10000, should adaptive scale by shift and gamut*/ +static int match_ootf_output( + struct scene2094metadata metadata, + struct hdr10pgen_param_s *p_hdr10pgen_param, + int panel_lumin) +{ + unsigned int scale_float; + unsigned int maxl; + + maxl = metadata.maxscenesourceluminance; + if (!maxl) + maxl = 1000; + if (maxl < panel_lumin) + maxl = panel_lumin; + + /*o->10000 scale*/ + scale_float = 10000 * 1024 / maxl; + + p_hdr10pgen_param->shift = _log2(scale_float) - 10; + p_hdr10pgen_param->scale_gmt = scale_float >> p_hdr10pgen_param->shift; + memcpy(p_hdr10pgen_param->gain, gain, sizeof(unsigned int) * POINTS); + + if (hdr10_plus_printk & 4) + pr_hdr( + "maxl=%d, scale=%d, shift=%d, scale_gmt=%d, gain=%d-%d-%d\n", + maxl, scale_float, + p_hdr10pgen_param->shift, + p_hdr10pgen_param->scale_gmt, + gain[0], gain[86], gain[148]); + return 0; +} + // //mapping // struct hdr_proc_lut_param_s _hdr_lut_param; -int hdr10_plus_ootf_gen(void) +int hdr10_plus_ootf_gen( + int panel_lumin, + int force_source_lumin, + struct hdr10pgen_param_s *p_hdr10pgen_param) { /*int referenceCurve_flag = 1;*/ int order, i; - uint64_t Kx, Ky; - uint64_t AnchorY[15]; + u64 kx, ky; + u64 anchory[15]; /* bezier params obtained from metadata */ struct hdr10_plus_sei_s hdr10_plus_sei; - struct Scene2094Metadata metadata; - struct EBZCurveParameters referenceBezierParams; - struct EBZCurveParameters productBezierParams; - struct BasisOOTF_Params basisOOTF_Params; + struct scene2094metadata metadata; + struct ebzcurveparameters referencebezierparams; + struct ebzcurveparameters productbezierparams; + struct basisootf_params basisootf_params; - // mapping - enum hdr_module_sel { - VD1_HDR = 0x1, - VD2_HDR = 0x2, - OSD1_HDR = 0x4, - VDIN0_HDR = 0x8, - VDIN1_HDR = 0x10, - DI_HDR = 0x20, - HDR_MAX - }; + int productpeak = panel_lumin; - int productpeak = 700; - - memset(curveX, 0, sizeof(uint64_t) * POINTS); - memset(curveY, 0, sizeof(uint64_t) * POINTS); - memset(gain, 0, sizeof(unsigned int) * POINTS); + memset(curvex, 0, sizeof(uint64_t) * POINTS); + memset(curvey, 0, sizeof(uint64_t) * POINTS); + memset(gain, 0, sizeof(unsigned int) * POINTS); memset(gain_ter, 0, sizeof(unsigned int) * POINTS); - BasisOOTF_Params_init(&basisOOTF_Params); + basisootf_params_init(&basisootf_params); /* the final tv OOTF curve params init*/ - EBZCurveParametersInit(&productBezierParams); + ebzcurveparametersinit(&productbezierparams); /* the bezier parameters from metadata init*/ - EBZCurveParametersInit(&referenceBezierParams); + ebzcurveparametersinit(&referencebezierparams); /* repace with real vframe data*/ - vframe_hdr_plus_sei_s_init(&hdr10_plus_sei); + if (!force_source_lumin) + vframe_hdr_plus_sei_s_init(&hdr10_plus_sei); + else + vframe_hdr_sei_s_init(&hdr10_plus_sei, force_source_lumin); /*step 1. get metadata from vframe*/ - MetaDataInit(&metadata, &hdr10_plus_sei); + metadatainit(&metadata, &hdr10_plus_sei); /*step 2. get bezier params from metadata*/ - getMetaData(&metadata, &referenceBezierParams); + getmetadata(&metadata, &referencebezierparams); /*step 3. gen final guided OOTF*/ /*if (referenceCurve_flag == 0)*/ @@ -782,42 +1034,55 @@ int hdr10_plus_ootf_gen(void) /*ST-2094 percentile metadata */ /*basisOOTF(&metadata, &basisOOTF_Params, productPeak,*/ /* here length(minBezierParams->Anchor) =order*/ - /*metadata.maxSceneSourceLuminance, &productBezierParams);*/ + /*metadata.maxscenesourceluminance, &productBezierParams);*/ /*else*/ - GuidedOOTF( - &metadata, &basisOOTF_Params, - &referenceBezierParams, productpeak, - &productBezierParams); + guidedootf( + &metadata, &basisootf_params, + &referencebezierparams, productpeak, + &productbezierparams); + + if (hdr10_plus_printk & 2) { + pr_hdr("productPeak=%d\n", panel_lumin); + pr_hdr("\n===================guided out ===================\n"); + pr_hdr( + "1. knee point : (%4d,%4d)\n", + productbezierparams.sx, productbezierparams.sy); + pr_hdr( + "2. Bezier order : %d\n", + referencebezierparams.order); + pr_hdr("3. Bezier P coeffs :\n"); + for (i = 0; i < (productbezierparams.order - 1); i++) + pr_hdr( + " %2d: %4d\n", + i, productbezierparams.anchor[i]); + pr_hdr("\n=================================================\n"); + } /*step 4. get guided bezier params*/ - Kx = (uint64_t)productBezierParams.Sx; - Ky = (uint64_t)productBezierParams.Sy; - order = productBezierParams.order; - for (i = 0; i < productBezierParams.order - 1; i++) - AnchorY[i] = (uint64_t)productBezierParams.Anchor[i]; + kx = (uint64_t)productbezierparams.sx; + ky = (uint64_t)productbezierparams.sy; + order = productbezierparams.order; + for (i = 0; i < productbezierparams.order - 1; i++) + anchory[i] = (uint64_t)productbezierparams.anchor[i]; /*step 5. gen bezier curve*/ - genEBZCurve(&curveX[0], &curveY[0], &gain[0], &gain_ter[0], - Kx, Ky, &AnchorY[0], order); + genEBZCurve( + &curvex[0], &curvey[0], &gain[0], &gain_ter[0], + kx, ky, &anchory[0], order); + /* debug */ - if (hdr10_plus_printk) { + if (hdr10_plus_printk & 8) { for (i = 0; i < POINTS; i++) { - pr_hdr("fixed version:: %3d:(%lld, %lld)->%4d\n", - i, curveX[i], curveY[i], gain[i]); + pr_hdr( + "fixed : %3d:(%lld, %lld)->%4d\n", + i, curvex[i], curvey[i], gain[i]); } - hdr10_plus_printk = 0; } - /*hdr10+ temporary does not support other anchors 20190603*/ - if (hdr_plus_sei.num_bezier_curve_anchors[0] == 9) { - for (i = 0; i < POINTS; i++) - hdr_lut_param.ogain_lut[i] = gain[i]; - VSYNC_WR_MPEG_REG(VD1_HDR2_ADPS_ALPHA0, 0x28002800); - /* VSYNC_WR_MPEG_REG(VD1_HDR2_ADPS_ALPHA1,0x0a7a2800);*/ - VSYNC_WR_MPEG_REG_BITS(VD1_HDR2_ADPS_ALPHA1, 0x2800, 0, 16); - set_ootf_lut(VD1_HDR, &hdr_lut_param); - } + match_ootf_output(metadata, p_hdr10pgen_param, panel_lumin); + hdr10_plus_printk = 0; + return 0; } diff --git a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.h b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.h index ea587a132a34..af689fe40e4c 100644 --- a/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.h +++ b/drivers/amlogic/media/enhancement/amvecm/hdr/am_hdr10_plus_ootf.h @@ -26,7 +26,7 @@ #define PROCESSING_MAX 12 #define PORCESSING_DATA_MAX ((1 << PROCESSING_MAX) - 1) #define PROCESSING_MAX_HALF ((1 << (PROCESSING_MAX - 1)) - 1) -#define GAIN_BIT 7 +#define GAIN_BIT 6 #define U16 16 #define U16_MAXI ((1 << U16) - 1) #define MIN_LUMINANCE 200 @@ -34,24 +34,24 @@ #define U32 32 #define _U32_MAX 0xffffffff -struct EBZCurveParameters { +struct ebzcurveparameters { int order; - int Sx, Sy; - int Anchor[N + 1]; + int sx, sy; + int anchor[N + 1]; }; -struct Percentiles { +struct percentiles { int num_percentile; - int percentilePercent[PERCENTILE_ORDER]; - int percentileValue[PERCENTILE_ORDER]; + int percentilepercent[PERCENTILE_ORDER]; + int percentilevalue[PERCENTILE_ORDER]; }; -struct Scene2094Metadata { - int maxSceneSourceLuminance; - int referenceLuminance; - int minLuminance; - struct Percentiles percentiles; - struct EBZCurveParameters EBZCurveParameters; +struct scene2094metadata { + int maxscenesourceluminance; + int referenceluminance; + int minluminance; + struct percentiles percentiles; + struct ebzcurveparameters ebzcurveparameters; }; struct hdr10_plus_sei_s { @@ -73,7 +73,7 @@ struct hdr10_plus_sei_s { #define ORDER 10 #define NPCOEFF (ORDER - 1) #define P1MIN (PORCESSING_DATA_MAX / ORDER) -struct BasisOOTF_Params { +struct basisootf_params { /*Knee-Point (KP) parameters*/ /*KP ramp base thresholds (two bounds KP 1 and KP 2 are computed)*/ int SY1_V1; @@ -102,13 +102,13 @@ struct BasisOOTF_Params { /* Thresholds to compute relative shape of curve (P2~P9 coefficient)*/ /* by pre-defined bounds - as a function of scene percentile*/ - int P2To9_T1; - int P2To9_T2; + int P2TO9_T1; + int P2TO9_T2; /* Defined relative shape bounds (P2~P9 coefficient) for*/ /*a given maximum TM dynamic compression (eg : 20x )*/ - int P2ToP9_MAX1[ORDER - 2]; - int P2ToP9_MAX2[ORDER - 2]; + int P2TOP9_MAX1[ORDER - 2]; + int P2TOP9_MAX2[ORDER - 2]; /* Ps mixing gain (obtain all Ps coefficients) -*/ /*as a function of TM dynamic compression ratio*/ @@ -129,7 +129,16 @@ struct BasisOOTF_Params { int RED_P2_T2; }; -extern int hdr10_plus_ootf_gen(void); +struct hdr10pgen_param_s { + unsigned int shift; + /* scale * 1000 for 3bit float point*/ + unsigned int scale_gmt; + unsigned int gain[POINTS]; +}; +int hdr10_plus_ootf_gen( + int panel_lumin, + int force_source_lumin, + struct hdr10pgen_param_s *hdr10pgen_param); #endif /* AM_HDR10_PLUS_OOTF_H */ diff --git a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c index 9981c976acb4..35a89aa054bb 100644 --- a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c +++ b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.c @@ -911,11 +911,19 @@ int ncl_2020_709[9] = { /*int ncl_2020_709[9] = {*/ /*2543, -459, -36, -88, 2133, 3, -41, -161, 2250};*/ -/* standard2020->dcip3-d65 8bit*/ -int ncl_2020_p3[9] = { - 368, -96, -16, -16, 275, -3, 1, -8, 263}; +/* standard2020->dcip3 8bit*/ +int ncl_2020_p3dci[9] = { + 368, -96, -16, -16, 275, -3, 1, -8, 263 +}; + +/* standard2020->d65p3 8bit*/ +int ncl_2020_p3d65[9] = { + 344, -72, -15, -16, 275, -2, 0, -5, 260 +}; + int gamut_bypass_8bit[9] = { - 256, 0, 0, 0, 256, 0, 0, 0, 256}; + 256, 0, 0, 0, 256, 0, 0, 0, 256 +}; /* standard2020->709-d65 8bit*/ int ncl_2020_709_8bit[9] = { @@ -1212,7 +1220,8 @@ void hdr_highclip_by_luma( void set_hdr_matrix( enum hdr_module_sel module_sel, enum hdr_matrix_sel mtx_sel, - struct hdr_proc_mtx_param_s *hdr_mtx_param) + struct hdr_proc_mtx_param_s *hdr_mtx_param, + struct hdr10pgen_param_s *p_hdr10pgen_param) { unsigned int MATRIXI_COEF00_01 = 0; unsigned int MATRIXI_COEF02_10 = 0; @@ -1280,6 +1289,8 @@ void set_hdr_matrix( int adpscl_beta[3]; int adpscl_beta_s[3]; + int scale_shift = 0; + int i = 0; int in_mtx[MTX_NUM_PARAM] = { 1024, 0, 0, @@ -1682,7 +1693,8 @@ void set_hdr_matrix( for (i = 0; i < 9; i++) gmut_coef[i/3][i%3] = hdr_mtx_param->mtx_gamut[i]; - if (hdr_mtx_param->p_sel == HDR_SDR) + if ((hdr_mtx_param->p_sel == HDR_SDR) || + (hdr_mtx_param->p_sel == HDR10P_SDR)) /* use integer mode for gamut coeff */ gmut_shift = 0; else @@ -1713,7 +1725,8 @@ void set_hdr_matrix( hdr_mtx_param->p_sel == HLG_IPT) adpscl_alpha[i] = 1000 * (1 << adp_scal_y_shift) / 10000; - else if (hdr_mtx_param->p_sel == HDR_SDR) + else if ((hdr_mtx_param->p_sel == HDR_SDR) || + (hdr_mtx_param->p_sel == HDR10P_SDR)) adpscl_alpha[i] = (1 << adp_scal_y_shift); else @@ -1739,6 +1752,20 @@ void set_hdr_matrix( adpscl_shift[0] = adp_scal_x_shift - 1; adpscl_shift[1] = OO_NOR - _log2((1 << OO_NOR) / oo_y_lut_hdr_sdr[148]) - 1; + } else if (hdr_mtx_param->p_sel == HDR10P_SDR) { + if (p_hdr10pgen_param) + scale_shift = _log2((1 << OO_NOR) / + p_hdr10pgen_param->gain[148]); + else + scale_shift = + _log2((1 << OO_NOR) / oo_y_lut_hdr_sdr[148]); + /*because input 1/2, shift0/shift1 need change*/ + adpscl_shift[0] = adp_scal_x_shift - 1; + adpscl_shift[1] = OO_NOR - scale_shift - 1; + if (p_hdr10pgen_param) { + adpscl_shift[0] -= p_hdr10pgen_param->shift; + adpscl_shift[1] -= p_hdr10pgen_param->shift; + } } else if (hdr_mtx_param->p_sel == HDR_HLG) { adpscl_shift[0] = adp_scal_x_shift; adpscl_shift[1] = OO_NOR - @@ -2109,6 +2136,117 @@ void set_c_gain( VSYNC_WR_MPEG_REG(cgain_lut_data_port, lut[64]); } +#define NUM_HDR_HIST 16 +static u32 hdr_hist[NUM_HDR_HIST][128]; +static u32 hdr_max_rgb; +static u8 percentile_percent[7] = { + 1, 25, 50, 75, 90, 95, 99 +}; + +static u32 percentile[7]; + +void set_hist( + enum hdr_module_sel module_sel, int enable, + enum hdr_hist_sel hist_sel, + unsigned int hist_width, unsigned int hist_height) +{ + unsigned int hist_ctrl_port = 0; + + if (module_sel == VD1_HDR) + hist_ctrl_port = VD1_HDR2_HIST_CTRL; + else + return; + + if (enable) { + WRITE_VPP_REG(hist_ctrl_port + 1, hist_width - 1); + WRITE_VPP_REG(hist_ctrl_port + 2, hist_height - 1); + WRITE_VPP_REG( + hist_ctrl_port, + (1 << 4) | (hist_sel << 0)); + } else if (READ_VPP_REG_BITS(hist_ctrl_port, 4, 1)) { + WRITE_VPP_REG_BITS(hist_ctrl_port, 0, 4, 1); + hdr_max_rgb = 0; + } +} + +void get_hist(enum hdr_module_sel module_sel, enum hdr_hist_sel hist_sel) +{ + unsigned int hist_ctrl_port = 0; + unsigned int hist_height, hist_width, i; + u32 num_pixel, total_pixel, percentile_index; + + return; + + if (module_sel == VD1_HDR) + hist_ctrl_port = VD1_HDR2_HIST_CTRL; + else + return; + + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_G12A) { + hist_width = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 0, 13); + hist_height = READ_VPP_REG_BITS(VPP_PREBLEND_H_SIZE, 16, 13); + } else { + hist_height = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 0, 13); + hist_width = READ_VPP_REG_BITS(VPP_IN_H_V_SIZE, 16, 13); + } + if (!hist_width || !hist_height) + return; + + if ((hist_height != READ_VPP_REG(hist_ctrl_port + 2) + 1) || + (hist_width != READ_VPP_REG(hist_ctrl_port + 1) + 1) || + (READ_VPP_REG_BITS(hist_ctrl_port, 4, 1) == 0) || + (READ_VPP_REG_BITS(hist_ctrl_port, 0, 3) != hist_sel)) { + set_hist(module_sel, 1, hist_sel, hist_width, hist_height); + return; + } + + for (i = 0; i < NUM_HDR_HIST; i++) + memcpy(hdr_hist[i], hdr_hist[i + 1], 128 * sizeof(uint32_t)); + total_pixel = 0; + for (i = 0; i < 128; i++) { + WRITE_VPP_REG_BITS(hist_ctrl_port, i, 16, 8); + num_pixel = READ_VPP_REG(hist_ctrl_port + 3); + total_pixel += num_pixel; + hdr_hist[NUM_HDR_HIST - 1][i] = num_pixel; + } + num_pixel = 0; + percentile_index = 0; + if (total_pixel) { + for (i = 0; i < 128; i++) { + num_pixel += hdr_hist[NUM_HDR_HIST - 1][i]; + if (num_pixel * 100 / total_pixel >= + percentile_percent[percentile_index]) { + percentile[percentile_index] = + (i + 1) * 10000 / 128; + percentile_index++; + } + if (hdr_hist[NUM_HDR_HIST - 1][i]) + hdr_max_rgb = + (i + 1) * 10000 / 128; + } + } + + if (total_pixel && percentile_index) { + for (i = 0; i < 16; i++) { + pr_info("hist[%d..]=%d %d %d %d %d %d %d %d\n", + i * 8, + hdr_hist[NUM_HDR_HIST - 1][i * 8], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 1], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 2], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 3], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 4], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 5], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 6], + hdr_hist[NUM_HDR_HIST - 1][i * 8 + 7]); + pr_info("max=%d percentile=%d %d %d %d %d %d %d\n", + hdr_max_rgb, + percentile[0], percentile[1], percentile[2], + percentile[3], percentile[4], percentile[5], + percentile[6]); + } + } +} + struct hdr_proc_lut_param_s hdr_lut_param; enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel, @@ -2251,7 +2389,8 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel, hdr_lut_param.lut_on = LUT_OFF; hdr_lut_param.bitdepth = bit_depth; hdr_lut_param.cgain_en = LUT_OFF; - } else if (hdr_process_select == HDR_SDR) { + } else if (hdr_process_select == HDR_SDR || + hdr_process_select == HDR10P_SDR) { for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; hdr_lut_param.ogain_lut[i] = oo_y_lut_hdr_sdr[i]; @@ -2515,7 +2654,8 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel, hdr_mtx_param.mtx_on = MTX_OFF; hdr_mtx_param.p_sel = hdr_process_select; } else if (hdr_process_select == HDR_SDR || - hdr_process_select == HLG_SDR) { + hdr_process_select == HLG_SDR || + hdr_process_select == HDR10P_SDR) { hdr_mtx_param.mtx_only = HDR_ONLY; hdr_mtx_param.mtx_gamut_mode = 1; for (i = 0; i < MTX_NUM_PARAM; i++) { @@ -2634,17 +2774,270 @@ enum hdr_process_sel hdr_func(enum hdr_module_sel module_sel, hdr_mtx_param.p_sel = HDR_IPT; } - set_hdr_matrix(module_sel, HDR_IN_MTX, &hdr_mtx_param); + set_hdr_matrix(module_sel, HDR_IN_MTX, &hdr_mtx_param, NULL); set_eotf_lut(module_sel, &hdr_lut_param); - set_hdr_matrix(module_sel, HDR_GAMUT_MTX, &hdr_mtx_param); + set_hdr_matrix(module_sel, HDR_GAMUT_MTX, &hdr_mtx_param, NULL); set_ootf_lut(module_sel, &hdr_lut_param); set_oetf_lut(module_sel, &hdr_lut_param); - set_hdr_matrix(module_sel, HDR_OUT_MTX, &hdr_mtx_param); + set_hdr_matrix(module_sel, HDR_OUT_MTX, &hdr_mtx_param, NULL); + + set_c_gain(module_sel, &hdr_lut_param); + + return hdr_process_select; +} + +int hdr10p_ebzcurve_update( + enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct hdr10pgen_param_s *p_hdr10pgen_param) +{ + int bit_depth; + unsigned int i = 0; + struct hdr_proc_mtx_param_s hdr_mtx_param; + + memset(&hdr_mtx_param, 0, sizeof(struct hdr_proc_mtx_param_s)); + memset(&hdr_lut_param, 0, sizeof(struct hdr_proc_lut_param_s)); + + if (module_sel == VD1_HDR || + module_sel == VD2_HDR || + module_sel == OSD1_HDR) + bit_depth = 12; + else if ( + module_sel == VDIN0_HDR || + module_sel == VDIN1_HDR || + module_sel == DI_HDR) + bit_depth = 10; + else + return 0; + + if (is_meson_tl1_cpu()) + bit_depth = 10; + + /*lut parameters*/ + if (hdr_process_select == HDR10P_SDR) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + if (!p_hdr10pgen_param) + hdr_lut_param.ogain_lut[i] = + oo_y_lut_hdr_sdr[i]; + else + hdr_lut_param.ogain_lut[i] = + p_hdr10pgen_param->gain[i]; + } + hdr_lut_param.lut_on = LUT_ON; + } else { + return 0; + } +#ifdef HDR2_PRINT + pr_info("hdr: oo_gain %d = %lld-%lld-%lld, c_gain %d = %lld-%lld-%lld\n", + hdr_lut_param.lut_on, + hdr_lut_param.ogain_lut[0], hdr_lut_param.ogain_lut[74], + hdr_lut_param.ogain_lut[148], + hdr_lut_param.cgain_en, + hdr_lut_param.cgain_lut[0], hdr_lut_param.cgain_lut[32], + hdr_lut_param.cgain_lut[64]); +#endif + + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < 9; i++) { + if (!p_hdr10pgen_param) + hdr_mtx_param.mtx_gamut[i] = + ncl_2020_709_8bit[i]; + else + hdr_mtx_param.mtx_gamut[i] = + ncl_2020_p3d65[i] * + p_hdr10pgen_param->scale_gmt / 1024; + } + + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = hdr_process_select; + + set_hdr_matrix( + module_sel, HDR_GAMUT_MTX, + &hdr_mtx_param, p_hdr10pgen_param); + + set_ootf_lut(module_sel, &hdr_lut_param); + + return 0; +} + +enum hdr_process_sel hdr10p_func( + enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct vinfo_s *vinfo) +{ + int bit_depth; + unsigned int i = 0; + struct hdr_proc_mtx_param_s hdr_mtx_param; + bool mtx_only_mode = false; + + memset(&hdr_mtx_param, 0, sizeof(struct hdr_proc_mtx_param_s)); + memset(&hdr_lut_param, 0, sizeof(struct hdr_proc_lut_param_s)); + + if ((module_sel == OSD1_HDR) && + (is_meson_g12() || + is_meson_sm1_cpu() || + is_meson_tl1_cpu())) { + /* turn off OSD mtx and use HDR for g12, sm1, tl1 */ + VSYNC_WR_MPEG_REG( + VPP_WRAP_OSD1_MATRIX_EN_CTRL, 0); + if (!is_dolby_vision_on()) { + if (hdr_process_select == HDR_BYPASS) + hdr_process_select = RGB_YUV; + /* use in_mtx for g12b rev b, sm1, tl1 */ + if (hdr_process_select == RGB_YUV && + (is_meson_sm1_cpu() || + is_meson_tl1_cpu())) + mtx_only_mode = true; + } + } + + if (module_sel == VD1_HDR || + module_sel == VD2_HDR || + module_sel == OSD1_HDR) + bit_depth = 12; + else if (module_sel == VDIN0_HDR || + module_sel == VDIN1_HDR || + module_sel == DI_HDR) + bit_depth = 10; + else + return hdr_process_select; + + if (is_meson_tl1_cpu()) + bit_depth = 10; + + /*lut parameters*/ + if (hdr_process_select == RGB_YUV) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_bypass[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_bypass[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = + eo_y_lut_bypass[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = + cgain_lut_bypass[i] - 1; + } + hdr_lut_param.bitdepth = bit_depth; + if (mtx_only_mode) { + hdr_lut_param.lut_on = LUT_OFF; + hdr_lut_param.cgain_en = LUT_OFF; + } else { + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.cgain_en = LUT_ON; + } + } else if (hdr_process_select == HDR10P_SDR) { + for (i = 0; i < HDR2_OETF_LUT_SIZE; i++) { + hdr_lut_param.oetf_lut[i] = oe_y_lut_sdr[i]; + hdr_lut_param.ogain_lut[i] = oo_y_lut_hdr_sdr[i]; + if (i < HDR2_EOTF_LUT_SIZE) + hdr_lut_param.eotf_lut[i] = eo_y_lut_hdr[i]; + if (i < HDR2_CGAIN_LUT_SIZE) + hdr_lut_param.cgain_lut[i] = cgain_lut1[i] - 1; + } + hdr_lut_param.lut_on = LUT_ON; + hdr_lut_param.bitdepth = bit_depth; + hdr_lut_param.cgain_en = LUT_OFF; + } else { + return hdr_process_select; + } +#ifdef HDR2_PRINT + pr_info("hdr: oo_gain %d = %lld-%lld-%lld, c_gain %d = %lld-%lld-%lld\n", + hdr_lut_param.lut_on, + hdr_lut_param.ogain_lut[0], hdr_lut_param.ogain_lut[74], + hdr_lut_param.ogain_lut[148], + hdr_lut_param.cgain_en, + hdr_lut_param.cgain_lut[0], hdr_lut_param.cgain_lut[32], + hdr_lut_param.cgain_lut[64]); +#endif + + /*mtx parameters*/ + /* default pre/post in:yuv_rgb out:rgb_yuv */ + for (i = 0; i < 3; i++) { + hdr_mtx_param.mtxi_pre_offset[i] = + yuv2rgbpre[i]; + hdr_mtx_param.mtxi_pos_offset[i] = + yuv2rgbpos[i]; + hdr_mtx_param.mtxo_pre_offset[i] = + rgb2yuvpre[i]; + hdr_mtx_param.mtxo_pos_offset[i] = + rgb2yuvpos[i]; + } + + if (hdr_process_select == RGB_YUV) { + hdr_mtx_param.mtx_gamut_mode = 1; + if (mtx_only_mode) { + hdr_mtx_param.mtx_only = MTX_ONLY; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_out[i] = bypass_coeff[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + gamut_bypass[i]; + if (i < 3) { + hdr_mtx_param.mtxi_pre_offset[i] = + rgb2yuvpre[i]; + hdr_mtx_param.mtxi_pos_offset[i] = + rgb2yuvpos[i]; + hdr_mtx_param.mtxo_pre_offset[i] = + bypass_pre[i]; + hdr_mtx_param.mtxo_pos_offset[i] = + bypass_pos[i]; + } + } + hdr_mtx_param.mtx_on = MTX_OFF; + } else { + hdr_mtx_param.mtx_only = HDR_ONLY; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_cgain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_ogain[i] = bypass_coeff[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; + if (i < 9) + hdr_mtx_param.mtx_gamut[i] = + gamut_bypass[i]; + if (i < 3) { + hdr_mtx_param.mtxi_pre_offset[i] = + bypass_pre[i]; + hdr_mtx_param.mtxi_pos_offset[i] = + bypass_pos[i]; + } + } + hdr_mtx_param.mtx_on = MTX_ON; + } + hdr_mtx_param.p_sel = RGB_YUV; + } else if (hdr_process_select == HDR10P_SDR || + hdr_process_select == HLG_SDR) { + hdr_mtx_param.mtx_only = HDR_ONLY; + hdr_mtx_param.mtx_gamut_mode = 1; + for (i = 0; i < MTX_NUM_PARAM; i++) { + hdr_mtx_param.mtx_in[i] = ycbcr2rgb_ncl2020[i]; + hdr_mtx_param.mtx_cgain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_ogain[i] = rgb2ycbcr_709[i]; + hdr_mtx_param.mtx_out[i] = rgb2ycbcr_709[i]; + if (i < 9) { + hdr_mtx_param.mtx_gamut[i] = + ncl_2020_p3d65[i]; + } + } + hdr_mtx_param.mtx_on = MTX_ON; + hdr_mtx_param.p_sel = hdr_process_select; + } + + set_hdr_matrix(module_sel, HDR_IN_MTX, &hdr_mtx_param, NULL); + + set_eotf_lut(module_sel, &hdr_lut_param); + + set_oetf_lut(module_sel, &hdr_lut_param); + + set_hdr_matrix(module_sel, HDR_OUT_MTX, &hdr_mtx_param, NULL); set_c_gain(module_sel, &hdr_lut_param); diff --git a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h index 6059795e6893..a066547725d9 100644 --- a/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h +++ b/drivers/amlogic/media/enhancement/amvecm/set_hdr2_v0.h @@ -17,6 +17,7 @@ #include #include +#include "hdr/am_hdr10_plus_ootf.h" #ifndef MAX #define MAX(x1, x2) (double)(x1 > x2 ? x1 : x2) @@ -90,9 +91,19 @@ enum hdr_process_sel { RGB_YUV = 12, RGB_HDR = 13, RGB_HLG = 14, + HDR10P_SDR = 15, HDR_p_MAX }; +enum hdr_hist_sel { + HIST_E_RGBMAX = 0, + HIST_E_LUMA = 1, + HIST_E_SAT = 2, + HIST_O_BEFORE = 4, + HIST_O_AFTER = 6, + HIST_MAX +}; + #define MTX_ON 1 #define MTX_OFF 0 @@ -183,6 +194,15 @@ extern void mtx_setting(enum vpp_matrix_e mtx_sel, enum mtx_csc_e mtx_csc, int mtx_on); +unsigned int _log2(unsigned int value); +int hdr10p_ebzcurve_update( + enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct hdr10pgen_param_s *hdr10pgen_param); +enum hdr_process_sel hdr10p_func( + enum hdr_module_sel module_sel, + enum hdr_process_sel hdr_process_select, + struct vinfo_s *vinfo); extern void set_ootf_lut( enum hdr_module_sel module_sel, struct hdr_proc_lut_param_s *hdr_lut_param); @@ -196,4 +216,6 @@ extern unsigned int hdr10_force_clip; extern unsigned int hdr10_clip_luma; extern unsigned int hdr10_clip_margin; extern unsigned int hdr10_clip_mode; - +void get_hist( + enum hdr_module_sel module_sel, + enum hdr_hist_sel hist_sel);