avsync: fix the avsync issue when pcrmaster [1/1]
authorXiaoming Sui <xiaoming.sui@amlogic.com>
Fri, 26 Apr 2019 10:42:46 +0000 (18:42 +0800)
committerNick Xie <nick@khadas.com>
Mon, 5 Aug 2019 06:27:06 +0000 (14:27 +0800)
PD#SWPL-7775

Problem:
dtv video freeze when the stream is replayed

Solution:
when replay at pcrmaster, check the vpts and systime,
if the vpts > systime and the diff > margin,
then adjust the sysclk to make playback smooth.

Verify:
X301

Change-Id: Id1474db030e06fff6ce425a54562cfa4e02ceaa9
Signed-off-by: Xiaoming Sui <xiaoming.sui@amlogic.com>
drivers/amlogic/media/frame_sync/tsync.c
drivers/amlogic/media/frame_sync/tsync_pcr.c
drivers/amlogic/media/video_sink/video.c
include/linux/amlogic/media/frame_sync/tsync.h

index c6a9b41..5744664 100644 (file)
@@ -1431,6 +1431,28 @@ int tsync_set_startsync_mode(int mode)
 }
 EXPORT_SYMBOL(tsync_set_startsync_mode);
 
+bool tsync_check_vpts_discontinuity(unsigned int vpts)
+{
+       unsigned int systemtime;
+
+       if (tsync_get_mode() != TSYNC_MODE_PCRMASTER)
+               return false;
+       if (tsync_pcr_demux_pcr_used() == 0)
+               systemtime = timestamp_pcrscr_get();
+       else
+               systemtime = timestamp_pcrscr_get()
+                       + timestamp_get_pcrlatency();
+       if (vpts > systemtime &&
+               (vpts - systemtime) > tsync_vpts_discontinuity_margin())
+               return true;
+       else if (systemtime > vpts &&
+               (systemtime - vpts) > tsync_vpts_discontinuity_margin())
+               return true;
+       else
+               return false;
+}
+EXPORT_SYMBOL(tsync_check_vpts_discontinuity);
+
 static ssize_t store_pcr_recover(struct class *class,
                struct class_attribute *attr,
                const char *buf, size_t size)
index 7c51001..652368d 100644 (file)
@@ -722,15 +722,41 @@ void tsync_pcr_avevent_locked(enum avevent_e event, u32 param)
                break;
 
        case VIDEO_TSTAMP_DISCONTINUITY:{
+               unsigned int systime;
+
                /* unsigned oldpts=timestamp_vpts_get(); */
                if (!get_vsync_pts_inc_mode()) {
                        tsync_pcr_tsdemuxpcr_discontinue |=
                                VIDEO_DISCONTINUE;
-                               timestamp_pcrscr_enable(0);
                                tsync_process_discontinue();
                }
+               if (tsdemux_pcrscr_valid_cb &&
+                       tsdemux_pcrscr_valid_cb() == 1 &&
+                       tsync_check_vpts_discontinuity(param)) {
+                       if (tsync_pcr_demux_pcr_used() == 1) {
+                               systime = timestamp_pcrscr_get() +
+                                       timestamp_get_pcrlatency();
+                               if (systime < param) {
+                                       tsync_use_demux_pcr = 0;
+                                       tsync_pcr_freerun_mode = 1;
+                                       timestamp_pcrscr_set(param);
+                                       timestamp_pcrscr_enable(1);
+                               } else {
+                                       timestamp_pcrscr_set(param);
+                               }
+                       } else {
+                               systime = timestamp_pcrscr_get();
+                               if (systime > param && tsync_pcr_freerun_mode) {
+                                       tsync_use_demux_pcr = 1;
+                                       tsync_pcr_freerun_mode = 0;
+                                       timestamp_pcrscr_set(param);
+                                       timestamp_pcrscr_enable(0);
+                               } else {
+                                       timestamp_pcrscr_set(param);
+                               }
+                       }
+               }
                timestamp_vpts_set(param);
-
                break;
        }
        case AUDIO_TSTAMP_DISCONTINUITY:{
index 65bd7cb..d85a9a5 100644 (file)
@@ -5286,7 +5286,8 @@ static inline bool vpts_expire(struct vframe_s *cur_vf,
                /*
                 * if paused ignore discontinue
                 */
-               if (!timestamp_pcrscr_enable_state()) {
+               if (!timestamp_pcrscr_enable_state() &&
+                       tsync_get_mode() != TSYNC_MODE_PCRMASTER) {
                        /*pr_info("video pts discontinue,
                         * but pcrscr is disabled,
                         * return false\n");
@@ -5323,8 +5324,26 @@ static inline bool vpts_expire(struct vframe_s *cur_vf,
 
                        return false;
                } else if (omx_secret_mode == true
-                               && cur_omx_index >= next_vf->omx_index)
+                               && cur_omx_index >= next_vf->omx_index) {
                        return true;
+               } else if (tsync_check_vpts_discontinuity(pts) &&
+                       tsync_get_mode() == TSYNC_MODE_PCRMASTER) {
+                       /* in pcrmaster mode and pcr clk was used by tync,
+                        * when the stream was replayed, the pcr clk was
+                        * changed to the head of the stream. in this case,
+                        * we send the "VIDEO_TSTAMP_DISCONTINUITY" signal
+                        *  to notify tsync and adjust the sysclock to
+                        * make playback smooth.
+                        */
+                       if (next_vf->pts != 0)
+                               tsync_avevent_locked(VIDEO_TSTAMP_DISCONTINUITY,
+                                       next_vf->pts);
+                       else if (next_vf->pts == 0) {
+                               tsync_avevent_locked(VIDEO_TSTAMP_DISCONTINUITY,
+                                       pts);
+                               return true;
+                       }
+               }
        } else if (omx_run
                        && omx_secret_mode
                        && (omx_pts + omx_pts_interval_upper < next_vf->pts)
index edf83a7..ddb6977 100644 (file)
@@ -159,6 +159,7 @@ extern void set_pts_realign(void);
 
 extern void timestamp_set_pcrlatency(u32 latency);
 extern u32 timestamp_get_pcrlatency(void);
+extern bool tsync_check_vpts_discontinuity(unsigned int vpts);
 
 static inline u32 tsync_vpts_discontinuity_margin(void)
 {