mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 03:40:35 +09:00
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:
@@ -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)
|
||||
|
||||
@@ -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:{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user