From 9f9025ebc1c978a31c2bd028b998ce56c367a876 Mon Sep 17 00:00:00 2001 From: Brian Zhu Date: Wed, 27 Nov 2019 01:55:13 +0800 Subject: [PATCH] amvideo: add dv support for video_receiver [1/2] PD#SWPL-17393 Problem: video receiver has no dv vframe operation. Solution: Add dv vframe operation. Verify: Verifed by u212 Change-Id: I0caf24d85a0d6d8382c13d72d9a439390ac21047 Signed-off-by: Brian Zhu --- drivers/amlogic/media/video_sink/video.c | 18 ++-- drivers/amlogic/media/video_sink/video_priv.h | 4 + .../amlogic/media/video_sink/video_receiver.c | 89 ++++++++++++++++--- 3 files changed, 89 insertions(+), 22 deletions(-) diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index eb1334bb87ad..ed17b68c4024 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -2392,6 +2392,7 @@ static int dvel_swap_frame(struct vframe_s *vf) dvel_changed = true; dvel_size = new_dvel_w; need_disable_vd2 = false; + safe_switch_videolayer(1, true, true); } /* check the el size */ if (dvel_size != new_dvel_w) @@ -2409,7 +2410,7 @@ static int dvel_swap_frame(struct vframe_s *vf) return ret; } -static struct vframe_s *dvel_toggle_frame( +struct vframe_s *dvel_toggle_frame( struct vframe_s *vf, bool new_frame) { struct vframe_s *toggle_vf = NULL; @@ -4268,10 +4269,6 @@ SET_FILTER: path2_new_frame = gvideo_recv[0]->func->dequeue_frame(gvideo_recv[0]); if (vd1_path_id == gvideo_recv[0]->path_id) { - /* FIXME: need DV dual layer case */ -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - dv_new_vf = dvel_toggle_frame(vf, true); -#endif amvecm_on_vs( (gvideo_recv[0]->cur_buf != &gvideo_recv[0]->local_buf) @@ -4307,10 +4304,6 @@ SET_FILTER: path3_new_frame = gvideo_recv[1]->func->dequeue_frame(gvideo_recv[1]); if (vd1_path_id == gvideo_recv[1]->path_id) { - /* FIXME: need DV dual layer case */ -#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION - dv_new_vf = dvel_toggle_frame(vf, true); -#endif amvecm_on_vs( (gvideo_recv[1]->cur_buf != &gvideo_recv[1]->local_buf) @@ -4742,8 +4735,13 @@ SET_FILTER: VD2_PATH); #endif - if (need_disable_vd2) + if (need_disable_vd2) { safe_switch_videolayer(1, false, true); +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + /* reset dvel statue when disable vd2 */ + dvel_status = false; +#endif + } /* filter setting management */ frame_par_di_set = primary_render_frame( diff --git a/drivers/amlogic/media/video_sink/video_priv.h b/drivers/amlogic/media/video_sink/video_priv.h index f10625b436e5..238fe2018aa0 100644 --- a/drivers/amlogic/media/video_sink/video_priv.h +++ b/drivers/amlogic/media/video_sink/video_priv.h @@ -405,6 +405,10 @@ int get_video_debug_flags(void); int _video_set_disable(u32 val); int _videopip_set_disable(u32 val); struct device *get_video_device(void); +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION +struct vframe_s *dvel_toggle_frame( + struct vframe_s *vf, bool new_frame); +#endif #ifdef CONFIG_AMLOGIC_MEDIA_VIDEOCAPTURE int ext_frame_capture_poll(int endflags); diff --git a/drivers/amlogic/media/video_sink/video_receiver.c b/drivers/amlogic/media/video_sink/video_receiver.c index db4439239449..1018772a9ab0 100644 --- a/drivers/amlogic/media/video_sink/video_receiver.c +++ b/drivers/amlogic/media/video_sink/video_receiver.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "video_priv.h" #include "video_receiver.h" @@ -115,8 +116,7 @@ static inline void common_vf_put( vfp = vf_get_provider(ins->recv_name); if (vfp && vf) { vf_put(vf, ins->recv_name); -/* FIXME: chek if need enable */ -#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */ +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if ((glayer_info[0].display_path_id == ins->path_id) && is_dolby_vision_enable()) dolby_vision_vf_put(vf); @@ -229,11 +229,31 @@ static int common_receiver_event_fun( return 0; } +static inline int recycle_dvel_vf_put(void) +{ +#define DVEL_RECV_NAME "dvel" + + int event = 0, ret = 0; + struct vframe_s *vf = NULL; + struct vframe_provider_s *vfp = vf_get_provider(DVEL_RECV_NAME); + + if (vfp) { + vf = vf_get(DVEL_RECV_NAME); + if (vf) { + vf_put(vf, DVEL_RECV_NAME); + event |= VFRAME_EVENT_RECEIVER_PUT; + vf_notify_provider(DVEL_RECV_NAME, event, NULL); + ret = 1; + } + } + return ret; +} + static const struct vframe_receiver_op_s common_recv_func = { .event_cb = common_receiver_event_fun }; -#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */ +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION static int dolby_vision_need_wait_common(struct video_recv_s *ins) { struct vframe_s *vf; @@ -311,6 +331,8 @@ static struct vframe_s *recv_common_dequeue_frame( struct video_recv_s *ins) { struct vframe_s *vf = NULL; + struct vframe_s *toggle_vf = NULL; + s32 drop_count = -1; if (!ins) { pr_err("recv_common_dequeue_frame error, empty ins\n"); @@ -318,33 +340,76 @@ static struct vframe_s *recv_common_dequeue_frame( } vf = common_vf_peek(ins); -/* FIXME: chek if need enable */ -#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */ - if ((glayer_info[0].display_path_id == ins->path_id) && vf && +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + if ((glayer_info[0].display_path_id == ins->path_id) && is_dolby_vision_enable()) { - dolby_vision_check_hdr10(vf); - dolby_vision_check_hdr10plus(vf); - dolby_vision_check_hlg(vf); + struct provider_aux_req_s req; + u32 i, bl_cnt = 0xffffffff; + + if (vf) { + dolby_vision_check_mvc(vf); + dolby_vision_check_hdr10(vf); + dolby_vision_check_hdr10plus(vf); + dolby_vision_check_hlg(vf); + } + if (vf_peek("dvel")) { + req.vf = NULL; + req.bot_flag = 0; + req.aux_buf = NULL; + req.aux_size = 0xffffffff; + req.dv_enhance_exist = 0; + vf_notify_provider_by_name( + "dvbldec", + VFRAME_EVENT_RECEIVER_GET_AUX_DATA, + (void *)&req); + bl_cnt = req.aux_size; + + req.vf = NULL; + req.bot_flag = 0; + req.aux_buf = NULL; + req.aux_size = 0xffffffff; + req.dv_enhance_exist = 0; + vf_notify_provider_by_name( + "dveldec", + VFRAME_EVENT_RECEIVER_GET_AUX_DATA, + (void *)&req); + if ((req.aux_size != 0xffffffff) && + (bl_cnt != 0xffffffff) && + (bl_cnt > req.aux_size)) { + i = bl_cnt - req.aux_size; + while (i > 0) { + if (!recycle_dvel_vf_put()) + break; + i--; + } + } + } } #endif while (vf) { if (!vf->frame_dirty) { -#ifdef ENABLE_DV /* CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION */ +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION if ((glayer_info[0].display_path_id == ins->path_id) && dolby_vision_need_wait_common(ins)) break; #endif vf = common_vf_get(ins); - if (vf) + if (vf) { common_toggle_frame(ins, vf); + toggle_vf = vf; +#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION + dvel_toggle_frame(vf, true); +#endif + } } else { vf = common_vf_get(ins); if (vf) common_vf_put(ins, vf); } + drop_count++; vf = common_vf_peek(ins); } - return vf; + return toggle_vf; } static s32 recv_common_return_frame( -- 2.20.1