From e9b39122e7d19fe6f0529bda41f1a11dc3baca7a Mon Sep 17 00:00:00 2001 From: Xiaoming Sui Date: Fri, 26 Apr 2019 18:42:46 +0800 Subject: [PATCH] avsync: fix the avsync issue when pcrmaster [1/1] 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 --- drivers/amlogic/media/frame_sync/tsync.c | 22 +++++++++++++++++++ drivers/amlogic/media/frame_sync/tsync_pcr.c | 30 ++++++++++++++++++++++++-- drivers/amlogic/media/video_sink/video.c | 23 ++++++++++++++++++-- include/linux/amlogic/media/frame_sync/tsync.h | 1 + 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/drivers/amlogic/media/frame_sync/tsync.c b/drivers/amlogic/media/frame_sync/tsync.c index c6a9b41..5744664 100644 --- a/drivers/amlogic/media/frame_sync/tsync.c +++ b/drivers/amlogic/media/frame_sync/tsync.c @@ -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) diff --git a/drivers/amlogic/media/frame_sync/tsync_pcr.c b/drivers/amlogic/media/frame_sync/tsync_pcr.c index 7c51001..652368d 100644 --- a/drivers/amlogic/media/frame_sync/tsync_pcr.c +++ b/drivers/amlogic/media/frame_sync/tsync_pcr.c @@ -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:{ diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 65bd7cb..d85a9a5 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -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) diff --git a/include/linux/amlogic/media/frame_sync/tsync.h b/include/linux/amlogic/media/frame_sync/tsync.h index edf83a7..ddb6977 100644 --- a/include/linux/amlogic/media/frame_sync/tsync.h +++ b/include/linux/amlogic/media/frame_sync/tsync.h @@ -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) { -- 2.7.4