video: add fast and slow playback support [1/1]
authorDaogao Xu <daogao.xu@amlogic.com>
Fri, 30 Nov 2018 06:30:56 +0000 (14:30 +0800)
committerLuan Yuan <luan.yuan@amlogic.com>
Mon, 17 Dec 2018 02:58:32 +0000 (10:58 +0800)
PD#SWPL-1690

Problem:
YouTube requires support playback rate 0.25, 0.50, 1.00, 1.25, 1.50,
2.00

Solution:
vsync_slow_factor can be used to slow playback, extend it's value to
support fast playback

Verify:
mesongxl_p212_32_kernel49

Change-Id: I94589a210b8531cc198414b3017c3caf82827565
Signed-off-by: Daogao Xu <daogao.xu@amlogic.com>
drivers/amlogic/media/video_sink/video.c

index 08b1fca..931bb7d 100644 (file)
@@ -999,6 +999,11 @@ static u32 vsync_pts_112;
 static u32 vsync_pts_101;
 static u32 vsync_pts_100;
 static u32 vsync_freerun;
+/* extend this value to support both slow and fast playback
+ * 0,1: normal playback
+ * [2,1000]: speed/vsync_slow_factor
+ * >1000: speed*(vsync_slow_factor/1000000)
+ */
 static u32 vsync_slow_factor = 1;
 
 /* pts alignment */
@@ -2472,8 +2477,18 @@ static void vsync_toggle_frame(struct vframe_s *vf)
        ori_start_y_lines = 0;
        ori_end_y_lines = ((vf->type & VIDTYPE_COMPRESS) ?
                vf->compHeight : vf->height) - 1;
-       if (debug_flag & DEBUG_FLAG_PRINT_TOGGLE_FRAME)
-               pr_info("%s()\n", __func__);
+       if (debug_flag & DEBUG_FLAG_PRINT_TOGGLE_FRAME) {
+               u32 pcr = timestamp_pcrscr_get();
+               u32 vpts = timestamp_vpts_get();
+               u32 apts = timestamp_apts_get();
+
+               pr_info("%s pts:%d.%06d pcr:%d.%06d vpts:%d.%06d apts:%d.%06d\n",
+                               __func__, (vf->pts) / 90000,
+                               ((vf->pts) % 90000) * 1000 / 90, (pcr) / 90000,
+                               ((pcr) % 90000) * 1000 / 90, (vpts) / 90000,
+                               ((vpts) % 90000) * 1000 / 90, (apts) / 90000,
+                               ((apts) % 90000) * 1000 / 90);
+       }
 
        if (trickmode_i || trickmode_fffb)
                trickmode_duration_count = trickmode_duration;
@@ -4095,6 +4110,10 @@ static inline bool duration_expire(struct vframe_s *cur_vf,
        static s32 rpt_tab_idx;
        static const u32 rpt_tab[4] = { 0x100, 0x100, 0x300, 0x300 };
 
+       /* do not switch to new frames in none-normal speed */
+       if (vsync_slow_factor > 1000)
+               return false;
+
        if ((cur_vf == NULL) || (cur_dispbuf == &vf_local))
                return true;
 
@@ -5187,11 +5206,18 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
 
                if (vsync_slow_factor == 1) {
                        timestamp_pcrscr_inc_scale(vsync_pts_inc_scale,
-                                                  vsync_pts_inc_scale_base);
-               } else
-                       timestamp_pcrscr_inc(
-                               vsync_pts_inc / vsync_slow_factor);
-               timestamp_apts_inc(vsync_pts_inc / vsync_slow_factor);
+                                       vsync_pts_inc_scale_base);
+                       timestamp_apts_inc(vsync_pts_inc / vsync_slow_factor);
+               } else if (vsync_slow_factor > 1000) {
+                       u32 inc = (vsync_slow_factor / 1000)
+                               * vsync_pts_inc / 1000;
+
+                       timestamp_pcrscr_inc(inc);
+                       timestamp_apts_inc(inc);
+               } else {
+                       timestamp_pcrscr_inc(vsync_pts_inc / vsync_slow_factor);
+                       timestamp_apts_inc(vsync_pts_inc / vsync_slow_factor);
+               }
        }
        if (omx_secret_mode == true) {
                u32 system_time = timestamp_pcrscr_get();