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 <xiaoming.sui@amlogic.com>
This commit is contained in:
Xiaoming Sui
2019-04-26 18:42:46 +08:00
committed by Tao Zeng
parent 671b3b914d
commit 099f0e2c4b
4 changed files with 72 additions and 4 deletions

View 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)

View File

@@ -723,15 +723,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:{

View File

@@ -5381,7 +5381,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");
@@ -5418,8 +5419,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)

View 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)
{