From de231b4084e0a79cdc6e8f727800a603255d21db Mon Sep 17 00:00:00 2001 From: yao liu Date: Tue, 17 Sep 2019 06:39:24 -0400 Subject: [PATCH] dv: display abnormal when seeking [1/1] PD#SWPL-13834 Problem: Dropping dv frame triggers parser_matedata which updates the new_dovi_setting. Before rendering the first frame, keep frame is displayed. However, keep frame requires toggle, which updates the dovi_setting from new_dovi_setting, causing color error in keep frame Solution: Dropping frame don't update new_dovi_setting Verify: passed on sm1 Change-Id: I1c73ba6f7d192066e3d5f9439ccbedc6d610d6eb Signed-off-by: yao liu --- .../enhancement/amdolby_vision/amdolby_vision.c | 82 +++++++++++++++++----- drivers/amlogic/media/video_sink/video.c | 22 ++++-- .../amlogic/media/amdolbyvision/dolby_vision.h | 3 +- 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index cc72020..3539e98 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -1056,6 +1056,9 @@ static struct master_display_info_s hdr10_data; #define COMP_BUF_SIZE 8196 static char *md_buf[2]; static char *comp_buf[2]; +static char *drop_md_buf[2]; +static char *drop_comp_buf[2]; + static int currentId = 1; static int backup_comp_size; static int backup_md_size; @@ -3805,6 +3808,12 @@ void dolby_vision_init_receiver(void *pdev) comp_buf[i] = vmalloc(COMP_BUF_SIZE); if (comp_buf[i] != NULL) memset(comp_buf[i], 0, COMP_BUF_SIZE); + drop_md_buf[i] = vmalloc(MD_BUF_SIZE); + if (drop_md_buf[i] != NULL) + memset(drop_md_buf[i], 0, MD_BUF_SIZE); + drop_comp_buf[i] = vmalloc(COMP_BUF_SIZE); + if (drop_comp_buf[i] != NULL) + memset(drop_comp_buf[i], 0, COMP_BUF_SIZE); } } @@ -4787,7 +4796,7 @@ static int parse_sei_and_meta( int *total_comp_size, int *total_md_size, enum signal_format_e *src_format, - int *ret_flags) + int *ret_flags, bool drop_flag) { int i; char *p; @@ -4897,22 +4906,48 @@ static int parse_sei_and_meta( } md_size = comp_size = 0; - if (is_meson_tvmode()) - rpu_ret = p_funcs_tv->metadata_parser_process( + if (drop_flag) { + if (is_meson_tvmode()) + rpu_ret = + p_funcs_tv->metadata_parser_process( + meta_buf, size + 2, + drop_comp_buf[nextId] + + *total_comp_size, + &comp_size, + drop_md_buf[nextId] + *total_md_size, + &md_size, + true); + else + rpu_ret = + p_funcs_stb->metadata_parser_process( + meta_buf, size + 2, + drop_comp_buf[nextId] + + *total_comp_size, + &comp_size, + drop_md_buf[nextId] + *total_md_size, + &md_size, + true); + } else { + if (is_meson_tvmode()) + rpu_ret = + p_funcs_tv->metadata_parser_process( meta_buf, size + 2, comp_buf[nextId] + *total_comp_size, &comp_size, md_buf[nextId] + *total_md_size, &md_size, true); - else - rpu_ret = p_funcs_stb->metadata_parser_process( + else + rpu_ret = + p_funcs_stb->metadata_parser_process( meta_buf, size + 2, comp_buf[nextId] + *total_comp_size, &comp_size, md_buf[nextId] + *total_md_size, &md_size, true); + + } if (rpu_ret < 0) { pr_dolby_error( "meta(%d), pts(%lld) -> metadata parser process fail\n", @@ -5629,7 +5664,8 @@ static u32 last_total_md_size; static u32 last_total_comp_size; /* toggle mode: 0: not toggle; 1: toggle frame; 2: use keep frame */ int dolby_vision_parse_metadata( - struct vframe_s *vf, u8 toggle_mode, bool bypass_release) + struct vframe_s *vf, u8 toggle_mode, + bool bypass_release, bool drop_flag) { const struct vinfo_s *vinfo = get_current_vinfo(); struct vframe_s *el_vf; @@ -5784,7 +5820,7 @@ int dolby_vision_parse_metadata( &total_comp_size, &total_md_size, &src_format, - &ret_flags); + &ret_flags, drop_flag); if (ret_flags && req.dv_enhance_exist && (frame_count == 0)) { vf_notify_provider_by_name("dvbldec", @@ -5892,7 +5928,7 @@ int dolby_vision_parse_metadata( &el_comp_size, &el_md_size, &src_format, - &ret_flags); + &ret_flags, drop_flag); } if (!meta_flag_el) { total_comp_size = @@ -5946,8 +5982,10 @@ int dolby_vision_parse_metadata( el_flag = 1; if (toggle_mode != 2) { - last_total_md_size = total_md_size; - last_total_comp_size = total_comp_size; + if (!drop_flag) { + last_total_md_size = total_md_size; + last_total_comp_size = total_comp_size; + } } else if (meta_flag_bl && meta_flag_el) { total_md_size = last_total_md_size; total_comp_size = last_total_comp_size; @@ -6002,6 +6040,11 @@ int dolby_vision_parse_metadata( metadata_parser = NULL; } + if (drop_flag) { + pr_dolby_dbg("drop frame_count %d\n", frame_count); + return 1; + } + check_format = src_format; if (dolby_vision_request_mode != 0xff) { dolby_vision_mode = dolby_vision_request_mode; @@ -6690,9 +6733,8 @@ int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag) return -1; if (vf && dolby_vision_vf_check(vf)) { ret = dolby_vision_parse_metadata( - vf, 1, false); - if (!drop_flag) - frame_count++; + vf, 1, false, drop_flag); + frame_count++; } return ret; @@ -6829,11 +6871,11 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size, if (is_sink_cap_changed(vinfo)) { if (vf) - dolby_vision_parse_metadata(vf, 1, false); + dolby_vision_parse_metadata(vf, 1, false, false); dolby_vision_set_toggle_flag(1); } if (is_video_turn_on() == 1) { - if (vf && !dolby_vision_parse_metadata(vf, 0, false)) + if (vf && !dolby_vision_parse_metadata(vf, 0, false, false)) dolby_vision_set_toggle_flag(1); } @@ -6855,7 +6897,7 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size, } if (dolby_vision_flags & FLAG_TOGGLE_FRAME) dolby_vision_parse_metadata( - NULL, 1, false); + NULL, 1, false, false); } if (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) { @@ -7280,6 +7322,14 @@ int unregister_dv_functions(void) vfree(comp_buf[i]); comp_buf[i] = NULL; } + if (drop_md_buf[i] != NULL) { + vfree(drop_md_buf[i]); + drop_md_buf[i] = NULL; + } + if (drop_comp_buf[i] != NULL) { + vfree(drop_comp_buf[i]); + drop_comp_buf[i] = NULL; + } } if (p_funcs_stb || p_funcs_tv) { pr_info("*** unregister_dv_functions ***\n"); diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 7186590..4fe787d 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -530,6 +530,9 @@ static unsigned int videopip_drop_vf_cnt; MODULE_PARM_DESC(videopip_drop_vf_cnt, "\n videopip_drop_vf_cnt\n"); module_param(videopip_drop_vf_cnt, uint, 0664); +static unsigned int disable_dv_drop; +MODULE_PARM_DESC(disable_dv_drop, "\n disable_dv_drop\n"); +module_param(disable_dv_drop, uint, 0664); enum toggle_out_fl_frame_e { OUT_FA_A_FRAME, @@ -6166,7 +6169,8 @@ static int dolby_vision_drop_frame(void) vf = video_vf_get(); if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME) - pr_info("drop vf %p, index %d\n", vf, vf->omx_index); + pr_info("drop vf %p, index %d, pts %d\n", + vf, vf->omx_index, vf->pts); dolby_vision_update_metadata(vf, true); video_vf_put(vf); @@ -6830,7 +6834,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) omx_drop_done = true; pr_info("dolby vision drop done\n"); break; - } + } else + break; } else { break; } @@ -7498,7 +7503,7 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) && is_dolby_vision_enable()) { toggle_vf = pause_vf; dolby_vision_parse_metadata( - cur_dispbuf, 2, false); + cur_dispbuf, 2, false, false); dolby_vision_set_toggle_flag(1); //use previous setting //pr_info("DOLBY: pause frame %p\n", toggle_vf); @@ -7655,7 +7660,7 @@ SET_FILTER: && get_video_enabled()) { toggle_vf = cur_dispbuf; dolby_vision_parse_metadata( - toggle_vf, 2, false); + toggle_vf, 2, false, false); dolby_vision_set_toggle_flag(1); //pr_info("DOLBY: keep frame %p", toggle_vf); } @@ -7669,7 +7674,7 @@ SET_FILTER: && !for_dolby_vision_certification()) { toggle_vf = cur_dispbuf; dolby_vision_parse_metadata( - cur_dispbuf, 0, false); + cur_dispbuf, 0, false, false); dolby_vision_set_toggle_flag(1); } #endif @@ -9653,6 +9658,13 @@ static void set_omx_pts(u32 *p) frame_num); dovi_drop_flag = true; dovi_drop_frame_num = frame_num; + + if (disable_dv_drop) { + omx_run = true; + dovi_drop_flag = false; + dovi_drop_frame_num = 0; + omx_drop_done = true; + } break; } #endif diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h index 8ad9128..ea8fbe2 100644 --- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h +++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h @@ -91,7 +91,8 @@ extern void tv_dolby_vision_dma_table_modify( u32 tbl_id, uint64_t value); extern void tv_dolby_vision_efuse_info(void); extern int dolby_vision_parse_metadata( - struct vframe_s *vf, u8 toggle_mode, bool bypass_release); + struct vframe_s *vf, u8 toggle_mode, + bool bypass_release, bool drop_flag); extern void dolby_vision_update_vsvdb_config( char *vsvdb_buf, u32 tbl_size); extern void tv_dolby_vision_el_info(void); -- 2.7.4