From 2f431de1139a559b50403d0466bcb036bfbfe1cb Mon Sep 17 00:00:00 2001 From: Pengcheng Chen Date: Mon, 22 Jan 2024 17:05:50 +0800 Subject: [PATCH] vpp: need delay one frame to toggle when amdv on [1/1] PD#SWPL-153851 Problem: vpp need delay one frame to toggle when amdv on Solution: add save frame logic Verify: t3x Change-Id: Id6b58a7f81e48ef7ca49c682cad69b7e76518e1e Signed-off-by: Pengcheng Chen --- drivers/media/video_sink/video.c | 42 +++++++++++++++++++++++ drivers/media/video_sink/video_priv.h | 6 ++++ drivers/media/video_sink/video_receiver.c | 38 ++++++++++++++++++-- drivers/media/video_sink/video_receiver.h | 3 ++ 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/drivers/media/video_sink/video.c b/drivers/media/video_sink/video.c index 4538faf9b..876639734 100644 --- a/drivers/media/video_sink/video.c +++ b/drivers/media/video_sink/video.c @@ -176,6 +176,7 @@ static struct device *amvideo_poll_dev; static const char video_dev_id[] = "amvideo-dev"; static struct amvideo_device_data_s amvideo_meson_dev; static struct dentry *video_debugfs_root; +static struct video_save_s video_save; static int video_vsync = -ENXIO; static int video_vsync_viu2 = -ENXIO; @@ -1050,6 +1051,9 @@ static void video_vf_unreg_provider(void) videopeek = 0; nopostvideostart = false; hold_property_changed = 0; + video_save.save_vf_en = false; + video_save.save_vf = NULL; + video_save.toggle_vf = NULL; atomic_inc(&video_unreg_flag); while (atomic_read(&video_inirq_flag) > 0) @@ -3709,6 +3713,43 @@ static struct vframe_s *vsync_toggle_frame(struct vframe_s *vf, int line) return cur_dispbuf[0]; } +static struct vframe_s *save_toggle_frame(struct vframe_s *vf) +{ +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + if (get_top1_onoff()) { + if (video_save.save_vf_en && video_save.save_vf) { + /* need toggle */ + video_save.toggle_vf = video_save.save_vf; + video_save.save_vf = vf; + vf = video_save.toggle_vf; + } else { + /* save frame, not toggle */ + video_save.save_vf = vf; + video_save.toggle_vf = NULL; + vf = NULL; + video_save.save_vf_en = true; + } + if (debug_flag & DEBUG_FLAG_PRINT_FRAME_DETAIL) + pr_info("%s: save_vf_en=%d, vf=%p, save_vf=%p, toggle_vf=%p\n", + __func__, + video_save.save_vf_en, vf, + video_save.save_vf ? + video_save.save_vf : NULL, + video_save.toggle_vf ? + video_save.toggle_vf : NULL); + } else { + video_save.toggle_vf = vf; + if (video_save.save_vf) { + if (!amvideo_vf_put(video_save.save_vf)) + video_save.save_vf = NULL; + } + video_save.save_vf_en = false; + } + vf = video_save.toggle_vf; +#endif + return vf; +} + struct vframe_s *amvideo_toggle_frame(s32 *vd_path_id) { struct vframe_s *path0_new_frame = NULL; @@ -4112,6 +4153,7 @@ struct vframe_s *amvideo_toggle_frame(s32 *vd_path_id) __LINE__); break; } + vf = save_toggle_frame(vf); path0_new_frame = vsync_toggle_frame(vf, __LINE__); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if (vd_path_id[0] == VFM_PATH_AMVIDEO || diff --git a/drivers/media/video_sink/video_priv.h b/drivers/media/video_sink/video_priv.h index d8bd8c4fe..6fa5728fa 100644 --- a/drivers/media/video_sink/video_priv.h +++ b/drivers/media/video_sink/video_priv.h @@ -610,6 +610,12 @@ struct video_layer_s { u32 frc_v_size_pre; }; +struct video_save_s { + struct vframe_s *save_vf; + struct vframe_s *toggle_vf; + bool save_vf_en; +}; + enum { ONLY_CORE0, ONLY_CORE1, diff --git a/drivers/media/video_sink/video_receiver.c b/drivers/media/video_sink/video_receiver.c index c9c8a31df..6db7417b3 100644 --- a/drivers/media/video_sink/video_receiver.c +++ b/drivers/media/video_sink/video_receiver.c @@ -213,6 +213,9 @@ static void common_vf_unreg_provider(struct video_recv_s *ins) ins->switch_vf = false; ins->last_switch_state = false; ins->frame_count = 0; + ins->save_vf_en = false; + ins->save_vf = NULL; + ins->toggle_vf = NULL; if (!strcmp(ins->recv_name, "video_render.0")) clear_vsync_2to1_info(); @@ -714,14 +717,45 @@ static struct vframe_s *recv_common_dequeue_frame(struct video_recv_s *ins, } #endif vf = common_vf_get(ins); +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + if (get_top1_onoff()) { + if (ins->save_vf_en && ins->save_vf) { + /* need toggle */ + ins->toggle_vf = ins->save_vf; + ins->save_vf = vf; + vf = ins->toggle_vf; + } else { + /* save frame, not toggle */ + ins->save_vf = vf; + ins->toggle_vf = NULL; + vf = NULL; + ins->save_vf_en = true; + } + if (debug_flag & DEBUG_FLAG_PRINT_FRAME_DETAIL) { + pr_info("%s: save_vf_num=%d, vf=%p, save_vf=%p, toggle_vf=%p\n", + __func__, + ins->save_vf_en, vf, + ins->save_vf ? ins->save_vf : NULL, + ins->toggle_vf ? ins->toggle_vf : NULL); + } + } else { + ins->toggle_vf = vf; + if (ins->save_vf) { + kfifo_put(&ins->put_q, ins->save_vf); + ins->save_vf = NULL; + } + ins->save_vf_en = false; + } + vf = ins->toggle_vf; +#endif if (vf) { #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM amvecm_process(path_id, ins, vf); #endif #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION /*top1 enable, need check one more frame*/ - if (is_amdv_enable() && get_top1_onoff()) {/*todo*/ - vf_top1 = common_vf_peek(ins); + if (get_top1_onoff()) {/*todo*/ + vf_top1 = ins->save_vf;//common_vf_peek(ins); /*wait next new Fn+1 for top1, proc top2 Fn + top1 Fn+1*/ /*if no new frame, proc top2 Fn + repeat Top1 Fn*/ if (!vf_top1 && diff --git a/drivers/media/video_sink/video_receiver.h b/drivers/media/video_sink/video_receiver.h index ae3f7cdbd..1e3afbf31 100644 --- a/drivers/media/video_sink/video_receiver.h +++ b/drivers/media/video_sink/video_receiver.h @@ -46,6 +46,8 @@ struct video_recv_s { struct vframe_s *rdma_buf; struct vframe_s *buf_to_put[DISPBUF_TO_PUT_MAX]; struct vframe_s *original_vf; + struct vframe_s *save_vf; + struct vframe_s *toggle_vf; DECLARE_KFIFO(put_q, struct vframe_s *, RECEIVER_BUFFER_POOL_SIZE); bool switch_vf; @@ -64,6 +66,7 @@ struct video_recv_s { u32 drop_vf_cnt; u8 path_id; s8 buf_to_put_num; + bool save_vf_en; struct recv_func_s *func; };