diff --git a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c index fbf469572fb4..7a4654c286be 100644 --- a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c +++ b/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c @@ -7114,11 +7114,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; @@ -7148,11 +7148,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; @@ -7206,10 +7201,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"); @@ -7255,13 +7251,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; @@ -7280,21 +7269,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; @@ -7303,7 +7286,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); @@ -7337,8 +7320,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"); @@ -8237,6 +8218,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 ec006ea4a583..436eca3df73f 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -2443,26 +2443,38 @@ static 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) { @@ -2499,34 +2511,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; - } - /* trigger dv process once when stop playing */ - /* because toggle_vf is not sync with video off */ - if (cur_dv_vf && !toggle_vf) - dolby_vision_set_toggle_flag(1); +#ifdef OLD_DV_FLOW + /* trigger dv process once when stop playing */ + /* 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; @@ -2781,9 +2787,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; @@ -2982,9 +2986,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; @@ -3007,7 +3009,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 */ @@ -4327,11 +4329,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 ((cur_vd1_path_id != vd1_path_id || cur_vd2_path_id != vd2_path_id) && @@ -4357,6 +4356,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 c4405320a3d6..47786ced2fa0 100644 --- a/drivers/amlogic/media/video_sink/video_hw.c +++ b/drivers/amlogic/media/video_sink/video_hw.c @@ -4154,7 +4154,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; @@ -4171,7 +4170,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 c33abd7b8cdb..460a940b1bc8 100644 --- a/drivers/amlogic/media/video_sink/video_priv.h +++ b/drivers/amlogic/media/video_sink/video_priv.h @@ -218,6 +218,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);