dv: enable drop frame for dv [1/1]
authoryao liu <yao.liu@amlogic.com>
Mon, 26 Aug 2019 13:58:21 +0000 (09:58 -0400)
committeryao liu <yao.liu@amlogic.com>
Thu, 29 Aug 2019 02:13:09 +0000 (22:13 -0400)
PD#SWPL-13115

Problem:
Apk drop lots of frames before render
the first frame, in this case, omx_run
is false and no frames will render.
Decoder doesn't have free output buffer.

Solution:
Drop dv frames in video sync before render
the first frame if app want to drop.

Verify:
Verified on U212

Change-Id: I463619f658d7f78ad8d513e17ca78482e17b3a4e
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
drivers/amlogic/media/video_sink/video_priv.h
include/linux/amlogic/media/amdolbyvision/dolby_vision.h

index 34de9e2c2354f28d7613a8b5266d4087489ce73d..5f83a990e5f1b819ac6dc869ee5bd56bd35ce2b6 100644 (file)
@@ -6664,7 +6664,7 @@ int dolby_vision_wait_metadata(struct vframe_s *vf)
        return ret;
 }
 
-int dolby_vision_update_metadata(struct vframe_s *vf)
+int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag)
 {
        int ret = -1;
 
@@ -6673,7 +6673,8 @@ int dolby_vision_update_metadata(struct vframe_s *vf)
        if (vf && dolby_vision_vf_check(vf)) {
                ret = dolby_vision_parse_metadata(
                        vf, 1, false);
-               frame_count++;
+               if (!drop_flag)
+                       frame_count++;
        }
 
        return ret;
index 26d5b30389acfd006e1fb9279d01d04a6e22577d..a31bd029cf7644d37fb860940ab316817f87b5c5 100644 (file)
@@ -188,6 +188,9 @@ static u32 cur_disp_omx_index;
 #define DEBUG_FLAG_FFPLAY      (1<<0)
 #define DEBUG_FLAG_CALC_PTS_INC        (1<<1)
 
+static bool dovi_drop_flag;
+static int dovi_drop_frame_num;
+
 #define RECEIVER_NAME "amvideo"
 
 static s32 amvideo_poll_major;
@@ -6060,7 +6063,7 @@ struct vframe_s *dolby_vision_toggle_frame(struct vframe_s *vf)
        int height_bl, height_el;
        int ret;
 
-       ret = dolby_vision_update_metadata(vf);
+       ret = dolby_vision_update_metadata(vf, false);
        if (!is_dolby_vision_el_disable() || for_dolby_vision_certification())
                cur_dispbuf2 = dolby_vision_vf_peek_el(vf);
        if (cur_dispbuf2) {
@@ -6149,6 +6152,30 @@ static int dolby_vision_need_wait(void)
                return 1;
        return 0;
 }
+
+/* 1: drop fail; 0: drop success*/
+static int dolby_vision_drop_frame(void)
+{
+       struct vframe_s *vf;
+
+       if (dolby_vision_need_wait()) {
+               if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME)
+                       pr_info("drop frame need wait!\n");
+               return 1;
+       }
+       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);
+
+       dolby_vision_update_metadata(vf, true);
+       video_vf_put(vf);
+
+       if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME)
+               pr_info("drop vf %p done\n", vf);
+
+       return 0;
+}
 #endif
 /* patch for 4k2k bandwidth issue, skiw mali and vpu mif */
 static void dmc_adjust_for_mali_vpu(unsigned int width,
@@ -6776,6 +6803,40 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
        /* pr_info("%s: %s\n", __func__, dev_id_s); */
 #endif
 
+#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
+       if (is_dolby_vision_enable() && dovi_drop_flag) {
+               struct vframe_s *vf = NULL;
+               unsigned int cnt = 10;
+               int max_drop_index;
+
+               if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME)
+                       pr_info("dovi_drop_frame_num %d, omx_run %d\n",
+                               dovi_drop_frame_num, omx_run);
+               while (cnt--) {
+                       vf = video_vf_peek();
+                       if (vf && is_dovi_frame(vf)) {
+                               max_drop_index = omx_run ?
+                               omx_need_drop_frame_num : dovi_drop_frame_num;
+
+                               if (max_drop_index >= vf->omx_index) {
+                                       if (dolby_vision_drop_frame() == 1)
+                                               break;
+                               } else if (omx_run &&
+                                          (vf->omx_index >
+                                          omx_need_drop_frame_num)) {
+                                       /* all drop done*/
+                                       dovi_drop_flag = false;
+                                       omx_drop_done = true;
+                                       pr_info("dolby vision drop done\n");
+                                       break;
+                               }
+                       } else {
+                               break;
+                       }
+               }
+       }
+#endif
+
        if (omx_need_drop_frame_num > 0 && !omx_drop_done && omx_secret_mode) {
                struct vframe_s *vf = NULL;
 
@@ -6785,10 +6846,6 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
                        if (is_dolby_vision_enable()
                                && vf && is_dovi_frame(vf)) {
-                               pr_info("vsync_isr_in, ignore the omx %d frames drop for dv frame\n",
-                                       omx_need_drop_frame_num);
-                               omx_need_drop_frame_num = 0;
-                               omx_drop_done = true;
                                break;
                        }
 #endif
@@ -7171,20 +7228,31 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
                if (omx_continuous_drop_flag
                        && !(debug_flag
                                & DEBUG_FLAG_OMX_DISABLE_DROP_FRAME)) {
-                       if (debug_flag & DEBUG_FLAG_OMX_DEBUG_DROP_FRAME) {
-                               pr_info("drop omx_index %d, pts %d\n",
-                                       vf->omx_index, vf->pts);
-                       }
-                       vf = vf_get(RECEIVER_NAME);
-                       if (vf) {
-                               vf_put(vf, RECEIVER_NAME);
-                               video_drop_vf_cnt++;
-                               if (debug_flag & DEBUG_FLAG_PRINT_DROP_FRAME)
-                                       pr_info("drop frame: drop count %d\n",
-                                       video_drop_vf_cnt);
+                       if (is_dolby_vision_enable() && vf &&
+                           is_dovi_frame(vf)) {
+                               if (debug_flag & DEBUG_FLAG_OMX_DV_DROP_FRAME)
+                                       pr_info("dovi ignore continuous drop\n");
+                               /* if (omx_run)
+                                *      dolby_vision_drop_frame();
+                                */
+                       } else {
+                               if (debug_flag &
+                                       DEBUG_FLAG_OMX_DEBUG_DROP_FRAME) {
+                                       pr_info("drop omx_index %d, pts %d\n",
+                                               vf->omx_index, vf->pts);
+                               }
+                               vf = vf_get(RECEIVER_NAME);
+                               if (vf) {
+                                       vf_put(vf, RECEIVER_NAME);
+                                       video_drop_vf_cnt++;
+                                       if (debug_flag &
+                                           DEBUG_FLAG_PRINT_DROP_FRAME)
+                                               pr_info("drop frame: drop count %d\n",
+                                                       video_drop_vf_cnt);
+                               }
+                               vf = video_vf_peek();
+                               continue;
                        }
-                       vf = video_vf_peek();
-                       continue;
                }
 
                if (vpts_expire(cur_dispbuf, vf, toggle_cnt) || show_nosync) {
@@ -9075,6 +9143,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                omx_continuous_drop_count = 0;
                omx_continuous_drop_flag = false;
                cur_disp_omx_index = 0;
+               dovi_drop_flag = false;
+               dovi_drop_frame_num = 0;
                mutex_unlock(&omx_mutex);
        } else if (type == VFRAME_EVENT_PROVIDER_RESET) {
                video_vf_light_unreg_provider(1);
@@ -9098,6 +9168,8 @@ static int video_receiver_event_fun(int type, void *data, void *private_data)
                omx_continuous_drop_count = 0;
                omx_continuous_drop_flag = false;
                cur_disp_omx_index = 0;
+               dovi_drop_flag = false;
+               dovi_drop_frame_num = 0;
                mutex_unlock(&omx_mutex);
                //init_hdr_info();
 
@@ -9562,19 +9634,18 @@ static void set_omx_pts(u32 *p)
 
        } else if (set_from_hwc == 0 && !omx_run) {
                struct vframe_s *vf = NULL;
-               u32 donot_drop = 0;
-               u32 dovi_dual_layer = 0;
 
                while (try_cnt--) {
                        vf = vf_peek(RECEIVER_NAME);
 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
                        if (is_dolby_vision_enable()
                                && vf && is_dovi_frame(vf)) {
-                               pr_info("set_omx_pts ignore the omx %d frames drop for dv frame\n",
-                                       frame_num);
-                               donot_drop = 1;
-                               if (is_dovi_dual_layer_frame(vf))
-                                       dovi_dual_layer = 1;
+                               if (debug_flag &
+                                       DEBUG_FLAG_OMX_DV_DROP_FRAME)
+                                       pr_info("dovi will drop %d in vsync\n",
+                                               frame_num);
+                               dovi_drop_flag = true;
+                               dovi_drop_frame_num = frame_num;
                                break;
                        }
 #endif
@@ -9590,17 +9661,6 @@ static void set_omx_pts(u32 *p)
                        } else
                                break;
                }
-               if (donot_drop && omx_pts_set_from_hwc_count > 0) {
-                       pr_info("reset omx_run to true.\n");
-                       omx_run = true;
-               }
-#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
-               if (dovi_dual_layer) {
-                       omx_run = true;
-                       omx_drop_done = true;
-                       pr_info("dolby dual layer donot drop.\n");
-               }
-#endif
        }
        mutex_unlock(&omx_mutex);
 }
index 8da637ca4cbb50e5830ef18850b796a1c191cc52..1486966eaceb0d8ed62a2a536ea89de73c9e92e1 100644 (file)
@@ -35,6 +35,7 @@
 #define DEBUG_FLAG_OMX_DEBUG_DROP_FRAME        0x1000000
 #define DEBUG_FLAG_OMX_DISABLE_DROP_FRAME        0x2000000
 #define DEBUG_FLAG_PRINT_DROP_FRAME        0x4000000
+#define DEBUG_FLAG_OMX_DV_DROP_FRAME        0x8000000
 
 /*for video.c's static int debug_flag;*/
 
index 227cd6dea2c4154d49b3bd5d59244a774808ff27..8ad91283aefd0b53b7dbf4295e53f52e23b2daa7 100644 (file)
@@ -57,7 +57,7 @@ extern int get_dolby_vision_mode(void);
 extern void dolby_vision_set_toggle_flag(int flag);
 extern int dolby_vision_wait_metadata(struct vframe_s *vf);
 extern int dolby_vision_pop_metadata(void);
-extern int dolby_vision_update_metadata(struct vframe_s *vf);
+int dolby_vision_update_metadata(struct vframe_s *vf, bool drop_flag);
 extern int dolby_vision_process(struct vframe_s *vf, u32 display_size,
        u8 pps_state);
 extern void dolby_vision_init_receiver(void *pdev);