dv: display abnormal when seeking [1/1]
authoryao liu <yao.liu@amlogic.com>
Tue, 17 Sep 2019 10:39:24 +0000 (06:39 -0400)
committerTao Zeng <tao.zeng@amlogic.com>
Mon, 23 Sep 2019 01:30:27 +0000 (18:30 -0700)
PD#SWPL-13834

Problem:
Dropping dv frame triggers parser_matedata which updates
the new_dovi_setting. Before rendering the first frame,
keep frame is displayed. However, keep frame requires
toggle, which updates the dovi_setting from new_dovi_setting,
causing color error in keep frame

Solution:
Dropping frame don't update new_dovi_setting

Verify:
passed on sm1

Change-Id: I1c73ba6f7d192066e3d5f9439ccbedc6d610d6eb
Signed-off-by: yao liu <yao.liu@amlogic.com>
drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c
drivers/amlogic/media/video_sink/video.c
include/linux/amlogic/media/amdolbyvision/dolby_vision.h

index cc72020..3539e98 100644 (file)
@@ -1056,6 +1056,9 @@ static struct master_display_info_s hdr10_data;
 #define COMP_BUF_SIZE 8196
 static char *md_buf[2];
 static char *comp_buf[2];
+static char *drop_md_buf[2];
+static char *drop_comp_buf[2];
+
 static int currentId = 1;
 static int backup_comp_size;
 static int backup_md_size;
@@ -3805,6 +3808,12 @@ void dolby_vision_init_receiver(void *pdev)
                comp_buf[i] = vmalloc(COMP_BUF_SIZE);
                if (comp_buf[i] != NULL)
                        memset(comp_buf[i], 0, COMP_BUF_SIZE);
+               drop_md_buf[i] = vmalloc(MD_BUF_SIZE);
+               if (drop_md_buf[i] != NULL)
+                       memset(drop_md_buf[i], 0, MD_BUF_SIZE);
+               drop_comp_buf[i] = vmalloc(COMP_BUF_SIZE);
+               if (drop_comp_buf[i] != NULL)
+                       memset(drop_comp_buf[i], 0, COMP_BUF_SIZE);
        }
 }
 
@@ -4787,7 +4796,7 @@ static int parse_sei_and_meta(
        int *total_comp_size,
        int *total_md_size,
        enum signal_format_e *src_format,
-       int *ret_flags)
+       int *ret_flags, bool drop_flag)
 {
        int i;
        char *p;
@@ -4897,22 +4906,48 @@ static int parse_sei_and_meta(
                        }
 
                        md_size = comp_size = 0;
-                       if (is_meson_tvmode())
-                               rpu_ret = p_funcs_tv->metadata_parser_process(
+                       if (drop_flag) {
+                               if (is_meson_tvmode())
+                                       rpu_ret =
+                                       p_funcs_tv->metadata_parser_process(
+                                       meta_buf, size + 2,
+                                       drop_comp_buf[nextId] +
+                                       *total_comp_size,
+                                       &comp_size,
+                                       drop_md_buf[nextId] + *total_md_size,
+                                       &md_size,
+                                       true);
+                               else
+                                       rpu_ret =
+                                       p_funcs_stb->metadata_parser_process(
+                                       meta_buf, size + 2,
+                                       drop_comp_buf[nextId] +
+                                       *total_comp_size,
+                                       &comp_size,
+                                       drop_md_buf[nextId] + *total_md_size,
+                                       &md_size,
+                                       true);
+                       } else {
+                               if (is_meson_tvmode())
+                                       rpu_ret =
+                                       p_funcs_tv->metadata_parser_process(
                                        meta_buf, size + 2,
                                        comp_buf[nextId] + *total_comp_size,
                                        &comp_size,
                                        md_buf[nextId] + *total_md_size,
                                        &md_size,
                                        true);
-                       else
-                               rpu_ret = p_funcs_stb->metadata_parser_process(
+                               else
+                                       rpu_ret =
+                                       p_funcs_stb->metadata_parser_process(
                                        meta_buf, size + 2,
                                        comp_buf[nextId] + *total_comp_size,
                                        &comp_size,
                                        md_buf[nextId] + *total_md_size,
                                        &md_size,
                                        true);
+
+                       }
                        if (rpu_ret < 0) {
                                pr_dolby_error(
                                        "meta(%d), pts(%lld) -> metadata parser process fail\n",
@@ -5629,7 +5664,8 @@ static u32 last_total_md_size;
 static u32 last_total_comp_size;
 /* toggle mode: 0: not toggle; 1: toggle frame; 2: use keep frame */
 int dolby_vision_parse_metadata(
-       struct vframe_s *vf, u8 toggle_mode, bool bypass_release)
+       struct vframe_s *vf, u8 toggle_mode,
+       bool bypass_release, bool drop_flag)
 {
        const struct vinfo_s *vinfo = get_current_vinfo();
        struct vframe_s *el_vf;
@@ -5784,7 +5820,7 @@ int dolby_vision_parse_metadata(
                                &total_comp_size,
                                &total_md_size,
                                &src_format,
-                               &ret_flags);
+                               &ret_flags, drop_flag);
                        if (ret_flags && req.dv_enhance_exist
                                && (frame_count == 0)) {
                                vf_notify_provider_by_name("dvbldec",
@@ -5892,7 +5928,7 @@ int dolby_vision_parse_metadata(
                                                        &el_comp_size,
                                                        &el_md_size,
                                                        &src_format,
-                                                       &ret_flags);
+                                                       &ret_flags, drop_flag);
                                        }
                                        if (!meta_flag_el) {
                                                total_comp_size =
@@ -5946,8 +5982,10 @@ int dolby_vision_parse_metadata(
                        el_flag = 1;
 
                if (toggle_mode != 2) {
-                       last_total_md_size = total_md_size;
-                       last_total_comp_size = total_comp_size;
+                       if (!drop_flag) {
+                               last_total_md_size = total_md_size;
+                               last_total_comp_size = total_comp_size;
+                       }
                } else if (meta_flag_bl && meta_flag_el) {
                        total_md_size = last_total_md_size;
                        total_comp_size = last_total_comp_size;
@@ -6002,6 +6040,11 @@ int dolby_vision_parse_metadata(
                metadata_parser = NULL;
        }
 
+       if (drop_flag) {
+               pr_dolby_dbg("drop frame_count %d\n", frame_count);
+               return 1;
+       }
+
        check_format = src_format;
        if (dolby_vision_request_mode != 0xff) {
                dolby_vision_mode = dolby_vision_request_mode;
@@ -6690,9 +6733,8 @@ int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag)
                return -1;
        if (vf && dolby_vision_vf_check(vf)) {
                ret = dolby_vision_parse_metadata(
-                       vf, 1, false);
-               if (!drop_flag)
-                       frame_count++;
+                       vf, 1, false, drop_flag);
+               frame_count++;
        }
 
        return ret;
@@ -6829,11 +6871,11 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
 
        if (is_sink_cap_changed(vinfo)) {
                if (vf)
-                       dolby_vision_parse_metadata(vf, 1, false);
+                       dolby_vision_parse_metadata(vf, 1, false, false);
                dolby_vision_set_toggle_flag(1);
        }
        if (is_video_turn_on() == 1) {
-               if (vf && !dolby_vision_parse_metadata(vf, 0, false))
+               if (vf && !dolby_vision_parse_metadata(vf, 0, false, false))
                        dolby_vision_set_toggle_flag(1);
        }
 
@@ -6855,7 +6897,7 @@ int dolby_vision_process(struct vframe_s *vf, u32 display_size,
                }
                if (dolby_vision_flags & FLAG_TOGGLE_FRAME)
                        dolby_vision_parse_metadata(
-                               NULL, 1, false);
+                               NULL, 1, false, false);
        }
 
        if (dolby_vision_mode == DOLBY_VISION_OUTPUT_MODE_BYPASS) {
@@ -7280,6 +7322,14 @@ int unregister_dv_functions(void)
                        vfree(comp_buf[i]);
                        comp_buf[i] = NULL;
                }
+               if (drop_md_buf[i] != NULL) {
+                       vfree(drop_md_buf[i]);
+                       drop_md_buf[i] = NULL;
+               }
+               if (drop_comp_buf[i] != NULL) {
+                       vfree(drop_comp_buf[i]);
+                       drop_comp_buf[i] = NULL;
+               }
        }
        if (p_funcs_stb || p_funcs_tv) {
                pr_info("*** unregister_dv_functions ***\n");
index 7186590..4fe787d 100644 (file)
@@ -530,6 +530,9 @@ static unsigned int videopip_drop_vf_cnt;
 MODULE_PARM_DESC(videopip_drop_vf_cnt, "\n videopip_drop_vf_cnt\n");
 module_param(videopip_drop_vf_cnt, uint, 0664);
 
+static unsigned int disable_dv_drop;
+MODULE_PARM_DESC(disable_dv_drop, "\n disable_dv_drop\n");
+module_param(disable_dv_drop, uint, 0664);
 
 enum toggle_out_fl_frame_e {
        OUT_FA_A_FRAME,
@@ -6166,7 +6169,8 @@ static int dolby_vision_drop_frame(void)
        vf = video_vf_get();
 
        if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME)
-               pr_info("drop vf %p, index %d\n", vf, vf->omx_index);
+               pr_info("drop vf %p, index %d, pts %d\n",
+                       vf, vf->omx_index, vf->pts);
 
        dolby_vision_update_metadata(vf, true);
        video_vf_put(vf);
@@ -6830,7 +6834,8 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
                                        omx_drop_done = true;
                                        pr_info("dolby vision drop done\n");
                                        break;
-                               }
+                               } else
+                                       break;
                        } else {
                                break;
                        }
@@ -7498,7 +7503,7 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
                            && is_dolby_vision_enable()) {
                                toggle_vf = pause_vf;
                                dolby_vision_parse_metadata(
-                                       cur_dispbuf, 2, false);
+                                       cur_dispbuf, 2, false, false);
                                dolby_vision_set_toggle_flag(1);
                                //use previous setting
                                //pr_info("DOLBY: pause frame %p\n", toggle_vf);
@@ -7655,7 +7660,7 @@ SET_FILTER:
                        && get_video_enabled()) {
                        toggle_vf = cur_dispbuf;
                        dolby_vision_parse_metadata(
-                               toggle_vf, 2, false);
+                               toggle_vf, 2, false, false);
                        dolby_vision_set_toggle_flag(1);
                        //pr_info("DOLBY: keep frame %p", toggle_vf);
                }
@@ -7669,7 +7674,7 @@ SET_FILTER:
                        && !for_dolby_vision_certification()) {
                        toggle_vf = cur_dispbuf;
                        dolby_vision_parse_metadata(
-                               cur_dispbuf, 0, false);
+                               cur_dispbuf, 0, false, false);
                        dolby_vision_set_toggle_flag(1);
                }
 #endif
@@ -9653,6 +9658,13 @@ static void set_omx_pts(u32 *p)
                                                frame_num);
                                dovi_drop_flag = true;
                                dovi_drop_frame_num = frame_num;
+
+                               if (disable_dv_drop) {
+                                       omx_run = true;
+                                       dovi_drop_flag = false;
+                                       dovi_drop_frame_num = 0;
+                                       omx_drop_done = true;
+                               }
                                break;
                        }
 #endif
index 8ad9128..ea8fbe2 100644 (file)
@@ -91,7 +91,8 @@ extern void tv_dolby_vision_dma_table_modify(
        u32 tbl_id, uint64_t value);
 extern void tv_dolby_vision_efuse_info(void);
 extern int dolby_vision_parse_metadata(
-       struct vframe_s *vf, u8 toggle_mode, bool bypass_release);
+       struct vframe_s *vf, u8 toggle_mode,
+       bool bypass_release, bool drop_flag);
 extern void dolby_vision_update_vsvdb_config(
        char *vsvdb_buf, u32 tbl_size);
 extern void tv_dolby_vision_el_info(void);