tsync: fix video not smooth in vmaster mode [1/1]
authorChao Liu <chao.liu@amlogic.com>
Thu, 21 Nov 2019 02:44:27 +0000 (10:44 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 23 Dec 2019 09:32:19 +0000 (02:32 -0700)
PD#SWPL-15541

Problem:
video not smooth during playing dvb demo source.
When tsync in vmaster mode, the pcrscr increase video in every vsync,
no matter whether video buffer is enough or not.

Solution:
When underflow occurs, if tsync in vmaster mode, decrease pcrscr pts.
This will increase the buffer time and make playback smooth

Verify:
AC214

Change-Id: Ief0fc8aa1c79a48cfc6f2d6bb6964a8b193b7bf9
Signed-off-by: Chao Liu <chao.liu@amlogic.com>
drivers/amlogic/media/frame_sync/timestamp.c
drivers/amlogic/media/frame_sync/tsync.c
drivers/amlogic/media/video_sink/video.c

index f21bab7087bcd5b96c8a7a659b84a76b46ec4d71..f27d110a85f8bdd06f209aff5d683103f82f5de6 100644 (file)
@@ -334,7 +334,7 @@ void timestamp_pcrscr_inc(s32 inc)
 {
        if (system_time_up) {
 #ifdef MODIFY_TIMESTAMP_INC_WITH_PLL
-               inc = inc * timestamp_inc_factor / PLL_FACTOR;
+               inc = inc * (s32)timestamp_inc_factor / PLL_FACTOR;
 #endif
                system_time += inc + system_time_inc_adj;
                ATRACE_COUNTER("PCRSCR",  system_time);
index 124badf85fd21f5df9fc0fa9fa14620d468c4cd2..618c68043fa0a6dde34afe0c43c4f5c6247449a5 100644 (file)
@@ -601,7 +601,7 @@ static int tsync_mode_switch(int mode, unsigned long diff_pts, int jump_pts)
        ("%c-discontinue,pcr=%d,vpts=%d,apts=%d,diff_pts=%lu,jump_Pts=%d\n",
         mode, timestamp_pcrscr_get(), timestamp_vpts_get(),
         timestamp_apts_get(), diff_pts, jump_pts);
-       if (!tsync_enable) {
+       if (!tsync_enable || !timestamp_apts_started()) {
                if (tsync_mode != TSYNC_MODE_VMASTER)
                        tsync_mode = TSYNC_MODE_VMASTER;
                tsync_av_mode = TSYNC_STATE_S;
@@ -697,7 +697,7 @@ static int tsync_mode_switch(int mode, unsigned long diff_pts, int jump_pts)
 
 static void tsync_state_switch_timer_fun(unsigned long arg)
 {
-       if (!vpause_flag && !apause_flag) {
+       if (!vpause_flag && !apause_flag && timestamp_apts_started()) {
                if (tsync_av_mode == TSYNC_STATE_D
                        || tsync_av_mode == TSYNC_STATE_A) {
                        if (tsync_av_dynamic_timeout_ms < jiffies_ms) {
@@ -829,7 +829,8 @@ void tsync_avevent_locked(enum avevent_e event, u32 param)
        case VIDEO_TSTAMP_DISCONTINUITY: {
                unsigned int oldpts = timestamp_vpts_get();
                int oldmod = tsync_mode;
-               if (tsync_mode == TSYNC_MODE_VMASTER)
+               if (tsync_mode == TSYNC_MODE_VMASTER &&
+                               timestamp_apts_started())
                        t = timestamp_apts_get();
                else
                        t = timestamp_pcrscr_get();
index 3c7d22dc671649ae9afcd06fd4c72f9f56e53e67..a63c4804e54f016ccbb4d197edf34b78c92eca2f 100644 (file)
@@ -3845,6 +3845,12 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
        /*debug info for skip & repeate vframe case*/
        if (!vf) {
                underflow++;
+               /* video master mode, reduce pcrscr */
+               if (tsync_get_mode() == TSYNC_MODE_VMASTER) {
+                       s32 pts_inc = 0 - vsync_pts_inc;
+
+                       timestamp_pcrscr_inc(pts_inc);
+               }
                ATRACE_COUNTER("underflow",  1);
                if (video_dbg_vf&(1<<0))
                        dump_vframe_status("vdin0");