From d5c5f37ce82dfb8ab2475bf6393764d312c93e45 Mon Sep 17 00:00:00 2001 From: Brian Zhu Date: Fri, 6 Dec 2019 22:57:09 +0800 Subject: [PATCH] dv: improve the dv process flow [1/1] PD#SWPL-18116 Problem: Under keeping frame case, dv toggle frame with wrong mode, it may cause non-dv effect . Solution: Improve the toggle flow , pass the correct mode into dv driver. Then using the last meta data Verify: Verified on u212 Change-Id: I456bb16e16810c166aba23d07a3296595032861e Signed-off-by: Brian Zhu (cherry picked from commit 7595b454438eddfd6332780a4109678730f831ab) --- .../amdolby_vision/amdolby_vision.c | 44 ++++------- drivers/amlogic/media/video_sink/video.c | 73 ++++++++++--------- drivers/amlogic/media/video_sink/video_hw.c | 3 +- drivers/amlogic/media/video_sink/video_priv.h | 1 + .../media/amdolbyvision/dolby_vision.h | 4 +- 5 files changed, 55 insertions(+), 70 deletions(-) diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index 562d7b890cdb..19e6396b3e11 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -7113,11 +7113,11 @@ static void bypass_pps_path(u8 pps_state) } } +/* toggle mode: 0: not toggle; 1: toggle frame; 2: use keep frame */ +/* pps_state 0: no change, 1: pps enable, 2: pps disable */ int dolby_vision_process( - struct vframe_s *rpt_vf, - struct vframe_s *vf, - u32 display_size, - u8 pps_state) /* 0: no change, 1: pps enable, 2: pps disable */ + struct vframe_s *vf, u32 display_size, + u8 toggle_mode, u8 pps_state) { int src_chroma_format = 0; u32 h_size = (display_size >> 16) & 0xffff; @@ -7147,11 +7147,6 @@ int dolby_vision_process( vf->compWidth : vf->width; v_size = (vf->type & VIDTYPE_COMPRESS) ? vf->compHeight : vf->height; - } else if (rpt_vf) { - h_size = (rpt_vf->type & VIDTYPE_COMPRESS) ? - rpt_vf->compWidth : rpt_vf->width; - v_size = (rpt_vf->type & VIDTYPE_COMPRESS) ? - rpt_vf->compHeight : rpt_vf->height; } else { h_size = 0; v_size = 0; @@ -7205,10 +7200,11 @@ int dolby_vision_process( new_dovi_setting.video_height = 0xffff; } } - if (!vf && !sdr_delay) { + if ((!vf || (toggle_mode != 1)) && !sdr_delay) { /* log to monitor if has dv toggles not needed */ /* !sdr_delay: except in transition from DV to SDR */ - pr_dolby_dbg("NULL frame, hdr module %s, video %s\n", + pr_dolby_dbg("NULL/RPT frame %p, hdr module %s, video %s\n", + vf, get_hdr_module_status(VD1_PATH) == HDR_MODULE_ON ? "on" : "off", get_video_enabled() ? "on" : "off"); @@ -7254,13 +7250,6 @@ int dolby_vision_process( else if (video_status == 1) video_turn_off = false; - if (video_turn_off && - get_hdr_module_status(VD1_PATH) - != HDR_MODULE_ON) { - vf = NULL; - /* rpt_vf = NULL; */ - } - if (dolby_vision_mode != dolby_vision_target_mode) format_changed = 1; @@ -7279,21 +7268,15 @@ int dolby_vision_process( if (sink_changed || policy_changed || format_changed || (video_status == 1) || (graphic_status & 2) || (dolby_vision_flags & FLAG_FORCE_HDMI_PKT)) { - u8 toggle_mode; - - pr_dolby_dbg("sink %s, cap 0x%x, video %s, osd %s, vf %p, rpt_vf %p\n", + pr_dolby_dbg("sink %s, cap 0x%x, video %s, osd %s, vf %p, toggle mode %d\n", current_sink_available ? "on" : "off", current_hdr_cap, video_turn_off ? "off" : "on", is_graphics_output_off() ? "off" : "on", - vf, rpt_vf); - if (vf && (vf != rpt_vf)) - toggle_mode = 1; - else - toggle_mode = 0; - if ((vf || rpt_vf) && + vf, toggle_mode); + if (vf && !dolby_vision_parse_metadata( - vf ? vf : rpt_vf, toggle_mode, false, false)) { + vf, toggle_mode, false, false)) { h_size = (display_size >> 16) & 0xffff; v_size = display_size & 0xffff; new_dovi_setting.video_width = h_size; @@ -7302,7 +7285,7 @@ int dolby_vision_process( } } - if ((!vf && !rpt_vf && video_turn_off) || + if ((!vf && video_turn_off) || (video_status == -1)) { if (dolby_vision_policy_process(&mode, FORMAT_SDR)) { pr_dolby_dbg("Fake SDR, mode->%d\n", mode); @@ -7336,8 +7319,6 @@ int dolby_vision_process( if (dolby_vision_status != BYPASS_PROCESS) { if (vinfo && !is_meson_tvmode() && !force_stb_mode) { - if (!vf && rpt_vf) - rpt_vf = vf; if (vf && is_hdr10plus_frame(vf)) { /* disable dolby immediately */ pr_info("Dolby bypass: HDR10+: Switched to SDR first\n"); @@ -8232,6 +8213,7 @@ unsigned int dolby_vision_check_enable(void) pr_info("dovi enable in uboot and mode is DV ST\n"); } } + dolby_vision_target_mode = dolby_vision_mode; } else pr_info("dovi disable in uboot\n"); } diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 8b4e8effb71e..205356333b78 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -2449,26 +2449,38 @@ struct vframe_s *dvel_toggle_frame( static void dolby_vision_proc( struct video_layer_s *layer, - struct vpp_frame_par_s *cur_frame_par, - struct vframe_s *toggle_vf) + struct vpp_frame_par_s *cur_frame_par) { +#ifdef OLD_DV_FLOW static struct vframe_s *cur_dv_vf; +#endif static u32 cur_frame_size; + struct vframe_s *disp_vf; + u8 toggle_mode; if (is_dolby_vision_enable()) { u32 frame_size = 0, h_size, v_size; u8 pps_state = 0; /* pps no change */ +/* TODO: check if need */ +#ifdef OLD_DV_FLOW /* force toggle when keeping frame after playing */ if (is_local_vf(layer->dispbuf) && - !toggle_vf && + !layer->new_frame && is_dolby_vision_video_on() && get_video_enabled()) { - toggle_vf = layer->dispbuf; if (!dolby_vision_parse_metadata( layer->dispbuf, 2, false, false)) dolby_vision_set_toggle_flag(1); } +#endif + disp_vf = layer->dispbuf; + if (layer->new_frame) + toggle_mode = 1; /* new frame */ + else if (!disp_vf || is_local_vf(disp_vf)) + toggle_mode = 2; /* keep frame */ + else + toggle_mode = 0; /* pasue frame */ if (cur_frame_par) { if (layer->new_vpp_setting) { @@ -2505,34 +2517,28 @@ static void dolby_vision_proc( v_size /= (cur_frame_par->vscale_skip_count + 1); frame_size = (h_size << 16) | v_size; - } else if (toggle_vf) { - h_size = (toggle_vf->type & VIDTYPE_COMPRESS) ? - toggle_vf->compWidth : toggle_vf->width; - v_size = (toggle_vf->type & VIDTYPE_COMPRESS) ? - toggle_vf->compHeight : toggle_vf->height; + } else if (disp_vf) { + h_size = (disp_vf->type & VIDTYPE_COMPRESS) ? + disp_vf->compWidth : disp_vf->width; + v_size = (disp_vf->type & VIDTYPE_COMPRESS) ? + disp_vf->compHeight : disp_vf->height; frame_size = (h_size << 16) | v_size; } - if (is_local_vf(layer->dispbuf)) { - if (get_video_enabled()) - toggle_vf = layer->dispbuf; - else - toggle_vf = NULL; - } + +#ifdef OLD_DV_FLOW /* trigger dv process once when stop playing */ - /* because toggle_vf is not sync with video off */ - if (cur_dv_vf && !toggle_vf) + /* because disp_vf is not sync with video off */ + if (cur_dv_vf && !disp_vf) dolby_vision_set_toggle_flag(1); - + cur_dv_vf = disp_vf; +#endif if (cur_frame_size != frame_size) { cur_frame_size = frame_size; - if (!toggle_vf && get_video_enabled()) - toggle_vf = layer->dispbuf; dolby_vision_set_toggle_flag(1); } - cur_dv_vf = toggle_vf; dolby_vision_process( - layer->dispbuf, toggle_vf, - frame_size, pps_state); + disp_vf, frame_size, + toggle_mode, pps_state); dolby_vision_update_setting(); } return; @@ -2952,9 +2958,7 @@ static void pip_swap_frame(struct vframe_s *vf) layer->new_vpp_setting = false; } -static s32 pip_render_frame( - struct video_layer_s *layer, - struct vframe_s *toggle_vf) +static s32 pip_render_frame(struct video_layer_s *layer) { struct vpp_frame_par_s *frame_par; u32 zoom_start_y, zoom_end_y; @@ -3169,9 +3173,7 @@ static void primary_swap_frame( ATRACE_COUNTER(__func__, 0); } -static s32 primary_render_frame( - struct video_layer_s *layer, - struct vframe_s *toggle_vf) +static s32 primary_render_frame(struct video_layer_s *layer) { struct vpp_frame_par_s *frame_par; bool force_setting = false; @@ -3194,7 +3196,7 @@ static s32 primary_render_frame( /* dolby vision process for each vsync */ #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - dolby_vision_proc(layer, frame_par, toggle_vf); + dolby_vision_proc(layer, frame_par); #endif /* process cur frame for each vsync */ @@ -4739,11 +4741,8 @@ SET_FILTER: } /* filter setting management */ - frame_par_di_set = primary_render_frame( - &vd_layer[0], vd_layer[0].dispbuf); - - pip_render_frame( - &vd_layer[1], vd_layer[1].dispbuf); + frame_par_di_set = primary_render_frame(&vd_layer[0]); + pip_render_frame(&vd_layer[1]); if (vd_layer[0].dispbuf && (vd_layer[0].dispbuf->flag & VFRAME_FLAG_FAKE_FRAME)) @@ -4781,6 +4780,10 @@ SET_FILTER: else vd_layer[0].enable_3d_mode = mode_3d_disable; + /* all frames has been renderred, so reset new frame flag */ + vd_layer[0].new_frame = false; + vd_layer[1].new_frame = false; + if (cur_dispbuf && cur_dispbuf->process_fun && ((vd1_path_id == VFM_PATH_AMVIDEO) || (vd1_path_id == VFM_PATH_DEF))) { diff --git a/drivers/amlogic/media/video_sink/video_hw.c b/drivers/amlogic/media/video_sink/video_hw.c index 17df909e807f..b3d09a684ad0 100644 --- a/drivers/amlogic/media/video_sink/video_hw.c +++ b/drivers/amlogic/media/video_sink/video_hw.c @@ -4241,7 +4241,6 @@ s32 layer_swap_frame( bool first_picture = false; bool enable_layer = false; bool frame_changed; - bool new_frame = false; struct video_layer_s *layer = NULL; struct disp_info_s *layer_info = NULL; int ret = vppfilter_success; @@ -4258,7 +4257,7 @@ s32 layer_swap_frame( if (layer->dispbuf != vf) { layer->new_vframe_count++; - new_frame = true; + layer->new_frame = true; if (!layer->dispbuf || (layer->new_vframe_count == 1) || (is_local_vf(layer->dispbuf))) diff --git a/drivers/amlogic/media/video_sink/video_priv.h b/drivers/amlogic/media/video_sink/video_priv.h index 36aa184470b5..5f68d90e9043 100644 --- a/drivers/amlogic/media/video_sink/video_priv.h +++ b/drivers/amlogic/media/video_sink/video_priv.h @@ -221,6 +221,7 @@ struct video_layer_s { bool property_changed; u8 force_config_cnt; bool new_vpp_setting; + bool new_frame; u32 vout_type; bool bypass_pps; diff --git a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h index 4202d2e9934a..b061d10afd9e 100644 --- a/include/linux/amlogic/media/amdolbyvision/dolby_vision.h +++ b/include/linux/amlogic/media/amdolbyvision/dolby_vision.h @@ -66,8 +66,8 @@ int dolby_vision_wait_metadata(struct vframe_s *vf); int dolby_vision_pop_metadata(void); int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag); int dolby_vision_process( - struct vframe_s *rpt_vf, struct vframe_s *vf, - u32 display_size, u8 pps_state); + struct vframe_s *vf, u32 display_size, + u8 toggle_mode, u8 pps_state); void dolby_vision_init_receiver(void *pdev); void dolby_vision_vf_put(struct vframe_s *vf); struct vframe_s *dolby_vision_vf_peek_el(struct vframe_s *vf); -- 2.20.1