dv: improve the dv process flow [1/1]
authorBrian Zhu <brian.zhu@amlogic.com>
Fri, 6 Dec 2019 14:57:09 +0000 (22:57 +0800)
committerBrian Zhu <brian.zhu@amlogic.com>
Mon, 9 Dec 2019 06:35:18 +0000 (23:35 -0700)
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 <brian.zhu@amlogic.com>
(cherry picked from commit 7595b454438eddfd6332780a4109678730f831ab)

drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/video_sink/video_hw.c
drivers/amlogic/media/video_sink/video_priv.h
include/linux/amlogic/media/amdolbyvision/dolby_vision.h

index 562d7b890cdb6be68c0722dc715477dab0958dc0..19e6396b3e111e45314a3f84e5646a65df21b065 100644 (file)
@@ -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");
        }
index 8b4e8effb71ee80995808a71a46884a760ce477c..205356333b78a9a397c740f8d8a4d81f0c8294b2 100644 (file)
@@ -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))) {
index 17df909e807f678a288ab03d8d567fafc9da9bca..b3d09a684ad0f103efd3d4eb52a156f586517734 100644 (file)
@@ -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)))
index 36aa184470b563981e9281ff05e0560c3fcb38e5..5f68d90e904303fca4473e898173ffc047ec290d 100644 (file)
@@ -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;
 
index 4202d2e9934a10f797b3261dc556fc7b643348ed..b061d10afd9e725cc9197314e69fd853b362df1c 100644 (file)
@@ -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);