static u32 tsync_demux_pcr_discontinue_count;
static u32 tsync_demux_pcr_continue_count;
+static int tsync_vpts_adjust;
+static u32 tsync_disable_demux_pcr;
+static u32 tsync_audio_mode;
+static int tsync_audio_discontinue;
+static int tsync_audio_continue_count;
+static u32 last_discontinue_checkin_apts;
+static u32 last_pcr_checkin_apts;
+static u32 last_pcr_checkin_vpts;
+static u32 last_pcr_checkin_apts_count;
+static u32 last_pcr_checkin_vpts_count;
+
static DEFINE_SPINLOCK(tsync_pcr_lock);
}
EXPORT_SYMBOL(tsync_pcr_get_min_checkinpts);
+static void tsync_set_pcr_mode(int mode, u32 param)
+{
+ if (tsync_pcr_debug & 0x03) {
+ pr_info("tsync_use_demux_pcr: %d to %d\n",
+ tsync_use_demux_pcr, mode);
+ }
+ if (mode == 0) {
+ tsync_use_demux_pcr = 0;
+ timestamp_pcrscr_set(param);
+ timestamp_pcrscr_enable(1);
+ timestamp_vpts_set(param);
+ } else if (mode == 1) {
+ tsync_use_demux_pcr = 1;
+ timestamp_pcrscr_enable(0);
+ }
+}
+
void tsync_pcr_pcrscr_set(void)
{
u32 first_pcr = 0, first_vpts = 0, first_apts = 0;
pr_info("now and the cur_checkin_apts is %x\n ",
cur_checkin_apts);
}
-
+ if (tsync_pcr_debug & 0x01) {
+ pr_info("check first_pcr=%x,first_apts=%x,first_vpts %x\n",
+ first_pcr, first_apts, first_vpts);
+ pr_info("cur_pcr=%x,checkin_apts=%x,checkin_vpts=%x\n",
+ cur_pcr, cur_checkin_apts, cur_checkin_vpts);
+ pr_info("gap_pa=%d,gap_pv=%d,gap_av=%d\n",
+ (int)(cur_pcr - cur_checkin_apts) / 90,
+ (int)(cur_pcr - cur_checkin_vpts) / 90,
+ (int)(cur_checkin_apts - cur_checkin_vpts) / 90);
+ pr_info("alevel=%d vlevel=%d\n",
+ abuf_level, vbuf_level);
+ }
/* check the valid of the pcr */
if (cur_pcr && cur_checkin_vpts && cur_checkin_apts &&
cur_checkin_vpts != 0xffffffff &&
- cur_checkin_apts != 0xffffffff) {
+ cur_checkin_apts != 0xffffffff &&
+ !(tsync_pcr_inited_flag & complete_init_flag)) {
u32 gap_pa, gap_pv, gap_av;
gap_pa = abs(cur_pcr - cur_checkin_apts);
gap_av = abs(cur_checkin_apts - cur_checkin_vpts);
gap_pv = abs(cur_pcr - cur_checkin_vpts);
- if ((gap_pa > MAX_GAP) && (gap_pv > MAX_GAP))
- cur_pcr = 0;
+ if ((gap_pa > MAX_GAP) && (gap_pv > MAX_GAP)) {
+ if (gap_av > MAX_GAP)
+ ref_pcr = cur_checkin_vpts;
+ else
+ ref_pcr = min_checkinpts -
+ tsync_pcr_ref_latency;
+ tsync_set_pcr_mode(0, ref_pcr);
+ tsync_pcr_inited_mode =
+ INIT_PRIORITY_VIDEO;
+ tsync_pcr_inited_flag |= TSYNC_PCR_INITCHECK_VPTS;
+ pr_info("tsync_set:pcrsrc %x,vpts %x, mode %d\n",
+ timestamp_pcrscr_get(), timestamp_vpts_get(),
+ tsync_use_demux_pcr);
+ return;
+ }
}
/* decide use which para to init */
if (cur_pcr && !(tsync_pcr_inited_flag & complete_init_flag)
&& (min_checkinpts != 0)) {
tsync_pcr_inited_flag |= TSYNC_PCR_INITCHECK_PCR;
- if (tsync_pcr_debug&0x02)
- pr_info("cur_pcr=%x min_checkinpts=%x\n",
- cur_pcr, min_checkinpts);
- if ((abs(cur_pcr - min_checkinpts) >
+ if ((abs(cur_pcr - cur_checkin_vpts) >
PLAY_PCR_INVALID_THRESHOLD) &&
- min_checkinpts != 0xffffffff) {
- ref_pcr = min_checkinpts;
- tsync_use_demux_pcr = 0;
+ cur_checkin_vpts != 0xffffffff) {
+ ref_pcr = cur_checkin_vpts -
+ tsync_pcr_ref_latency;
+ tsync_set_pcr_mode(0, ref_pcr);
+ tsync_pcr_inited_mode = INIT_PRIORITY_VIDEO;
+ } else if (((cur_pcr > min_checkinpts) &&
+ (cur_pcr - min_checkinpts) > 500 * 90) ||
+ tsync_disable_demux_pcr == 1) {
+ if (abs(cur_checkin_apts - cur_checkin_vpts)
+ > MAX_GAP)
+ ref_pcr = cur_checkin_vpts -
+ tsync_pcr_ref_latency;
+ else
+ ref_pcr = min_checkinpts;
+ tsync_set_pcr_mode(0, ref_pcr);
tsync_pcr_inited_mode = INIT_PRIORITY_VIDEO;
- if (tsync_pcr_debug&0x01) {
- pr_info("check init.first_pcr=0x%x, first_apts=0x%x, ",
- first_pcr, first_apts);
- pr_info("first_vpts=0x%x, cur_pcr = 0x%x, checkin_vpts=0x%x, ",
- first_vpts, cur_pcr, cur_checkin_vpts);
- pr_info("checkin_apts=0x%x alevel=%d vlevel=%d\n",
- cur_checkin_apts, abuf_level, vbuf_level);
- pr_info("[%d]init by pcr. pcr=%x usepcr=%d\n",
- __LINE__, ref_pcr, tsync_pcr_usepcr);
- }
} else {
- ref_pcr = timestamp_pcrscr_get();
- ref_pcr = timestamp_pcrscr_get();
- if (cur_pcr > min_checkinpts) {
- ref_pcr = min_checkinpts -
- tsync_pcr_ref_latency;
- timestamp_pcrscr_set(ref_pcr);
- timestamp_pcrscr_enable(1);
- tsync_use_demux_pcr = 0;
- if (cur_checkin_vpts == 0xffffffff)
- tsync_pcr_inited_mode =
- INIT_PRIORITY_AUDIO;
- else
- tsync_pcr_inited_mode =
- INIT_PRIORITY_VIDEO;
- } else {
- tsync_use_demux_pcr = 1;
- tsync_pcr_inited_mode = INIT_PRIORITY_PCR;
- }
+ tsync_set_pcr_mode(1, ref_pcr);
+ tsync_pcr_inited_mode = INIT_PRIORITY_PCR;
}
- pr_info("tsync set:pcrsrc %x,vpts %x,mode %d\n",
+ pr_info("tsync_set:pcrsrc %x,vpts %x,mode-%d\n",
timestamp_pcrscr_get(), timestamp_firstvpts_get(),
tsync_use_demux_pcr);
if (tsdemux_pcrscr_get_cb)
init_check_first_demuxpcr = tsdemux_pcrscr_get_cb();
+ return;
}
if (first_apts && !(tsync_pcr_inited_flag & complete_init_flag)
timestamp_firstvpts_get());
}
}
- timestamp_pcrscr_set(ref_pcr);
- timestamp_pcrscr_enable(1);
+ ref_pcr = tsync_pcr_get_min_checkinpts();
+ tsync_set_pcr_mode(0, ref_pcr);
+ tsync_pcr_inited_mode = INIT_PRIORITY_VIDEO;
init_check_first_systemtime = ref_pcr;
if (tsdemux_pcrscr_get_cb)
init_check_first_demuxpcr = tsdemux_pcrscr_get_cb();
timestamp_firstvpts_get());
}
}
- timestamp_pcrscr_set(ref_pcr);
- timestamp_pcrscr_enable(1);
+ ref_pcr = tsync_pcr_get_min_checkinpts();
+ tsync_set_pcr_mode(0, ref_pcr);
+ tsync_pcr_inited_mode = INIT_PRIORITY_VIDEO;
}
}
return tsync_last_play_mode;
}
-static void tsync_set_pcr_mode(int mode, u32 param)
-{
- if (tsync_pcr_debug & 0x03) {
- pr_info("tsync_use_demux_pcr: %d to %d\n",
- tsync_use_demux_pcr, mode);
- }
- if (mode == 0) {
- tsync_use_demux_pcr = 0;
- timestamp_pcrscr_set(param);
- timestamp_pcrscr_enable(1);
- timestamp_vpts_set(param);
- } else if (mode == 1) {
- tsync_use_demux_pcr = 1;
- timestamp_pcrscr_enable(0);
- }
-}
-
static void tsync_process_discontinue(void)
{
u32 cur_vpts = timestamp_vpts_get();
u32 cur_tsdemuxpcr = 0;
u32 ref_pcr = 0, tsdemux_pcr_diff;
u32 cur_checkin_vpts = get_last_checkin_pts(PTS_TYPE_VIDEO);
+ u32 cur_checkin_apts = get_last_checkin_pts(PTS_TYPE_AUDIO);
if (tsdemux_pcrscr_get_cb && (tsync_demux_last_pcr == 0
|| tsync_demux_last_pcr == 0xffffffff))
if (tsync_pcr_inited_mode != INIT_PRIORITY_PCR) {
if ((tsync_pcr_tsdemuxpcr_discontinue & VIDEO_DISCONTINUE)
== VIDEO_DISCONTINUE) {
- cur_checkin_vpts -= tsync_pcr_ref_latency;
+ if (abs(cur_checkin_apts - cur_checkin_vpts)
+ > MAX_GAP)
+ ref_pcr = cur_checkin_vpts -
+ tsync_pcr_ref_latency;
+ else
+ ref_pcr = tsync_pcr_get_min_checkinpts();
tsync_set_pcr_mode(0, cur_checkin_vpts);
tsync_pcr_tsdemuxpcr_discontinue = 0;
}
}
}
-static u32 last_pcr_checkin_apts;
-static u32 last_pcr_checkin_vpts;
-static u32 last_pcr_checkin_apts_count;
-static u32 last_pcr_checkin_vpts_count;
-
void tsync_pcr_check_checinpts(void)
{
u32 checkin_vpts = 0;
u32 checkin_apts = 0;
- checkin_vpts = get_last_checkin_pts(PTS_TYPE_VIDEO);
- checkin_apts = get_last_checkin_pts(PTS_TYPE_AUDIO);
-
- if (tsync_pcr_vstart_flag == 0 && tsync_pcr_astart_flag == 0)
- return;
-
- if (checkin_vpts == 0xffffffff)
- return;
-
- if (tsdemux_pcraudio_valid_cb && tsdemux_pcraudio_valid_cb()
- && (checkin_apts == 0xffffffff))
- return;
-
- if (last_pcr_checkin_apts == 0 || last_pcr_checkin_vpts == 0) {
- last_pcr_checkin_apts = checkin_apts;
- last_pcr_checkin_vpts = checkin_vpts;
- return;
- }
-
- if (last_pcr_checkin_apts > checkin_apts)
- tsync_pcr_tsdemuxpcr_discontinue |= AUDIO_DISCONTINUE;
-
- if (abs(last_pcr_checkin_vpts - checkin_vpts) > 2 * 90000)
- tsync_pcr_tsdemuxpcr_discontinue |= VIDEO_DISCONTINUE;
-
- if (last_pcr_checkin_apts == checkin_apts) {
- last_pcr_checkin_apts_count++;
- if (last_pcr_checkin_apts_count > 100)
- tsync_pcr_tsdemuxpcr_discontinue |= AUDIO_DISCONTINUE;
- } else {
- last_pcr_checkin_apts = checkin_apts;
- last_pcr_checkin_apts_count = 0;
+ if (tsync_pcr_astart_flag == 1) {
+ checkin_apts = get_last_checkin_pts(PTS_TYPE_AUDIO);
+ if ((checkin_apts != 0xffffffff)
+ && (last_pcr_checkin_apts != 0)) {
+ if (abs(last_pcr_checkin_apts - checkin_apts)
+ > 2 * 90000) {
+ tsync_pcr_tsdemuxpcr_discontinue |=
+ AUDIO_DISCONTINUE;
+ tsync_audio_discontinue = 1;
+ last_discontinue_checkin_apts = 0;
+ tsync_audio_continue_count = 0;
+ if (tsync_pcr_debug & 0x03) {
+ pr_info("a_discontinue,last %x,cur %x\n",
+ last_pcr_checkin_apts,
+ checkin_apts);
+ }
+ }
+ if (last_pcr_checkin_apts == checkin_apts) {
+ last_pcr_checkin_apts_count++;
+ if (last_pcr_checkin_apts_count > 40) {
+ tsync_pcr_tsdemuxpcr_discontinue |=
+ AUDIO_DISCONTINUE;
+ tsync_audio_discontinue = 1;
+ last_discontinue_checkin_apts = 0;
+ tsync_audio_continue_count = 0;
+ if (tsync_pcr_debug & 0x03)
+ pr_info("a_discontinue,count\n");
+ }
+ } else {
+ if (tsync_audio_discontinue == 1 &&
+ checkin_apts != 0xffffffff &&
+ last_discontinue_checkin_apts == 0 &&
+ checkin_apts > last_pcr_checkin_apts &&
+ ((checkin_apts - last_pcr_checkin_apts)
+ < 500 * 90)) {
+ last_discontinue_checkin_apts =
+ last_pcr_checkin_apts;
+ tsync_audio_continue_count = 1;
+ }
+ last_pcr_checkin_apts = checkin_apts;
+ last_pcr_checkin_apts_count = 0;
+ }
+ if (tsync_audio_continue_count)
+ tsync_audio_continue_count++;
+ if (tsync_audio_continue_count > 50 &&
+ tsync_audio_discontinue &&
+ last_discontinue_checkin_apts) {
+ tsync_audio_discontinue = 0;
+ if (tsync_pcr_debug & 0x03)
+ pr_info("a_continued,resumed\n");
+ }
+ } else {
+ last_pcr_checkin_apts = checkin_apts;
+ }
}
- if (last_pcr_checkin_vpts == checkin_vpts) {
- last_pcr_checkin_vpts_count++;
- if (last_pcr_checkin_vpts_count > 100)
- tsync_pcr_tsdemuxpcr_discontinue |= VIDEO_DISCONTINUE;
- } else {
- last_pcr_checkin_vpts = checkin_vpts;
- last_pcr_checkin_vpts_count = 0;
+ if (tsync_pcr_vstart_flag == 1) {
+ checkin_vpts = get_last_checkin_pts(PTS_TYPE_VIDEO);
+ if ((checkin_vpts != 0xffffffff) &&
+ (last_pcr_checkin_vpts != 0)) {
+ if (abs(last_pcr_checkin_vpts - checkin_vpts)
+ > 2 * 90000) {
+ tsync_pcr_tsdemuxpcr_discontinue |=
+ VIDEO_DISCONTINUE;
+ if (tsync_pcr_debug & 0x03) {
+ pr_info("v_discontinue,last %x,cur %x\n",
+ last_pcr_checkin_vpts,
+ checkin_vpts);
+ }
+ }
+ if (last_pcr_checkin_vpts == checkin_vpts) {
+ last_pcr_checkin_vpts_count++;
+ if (last_pcr_checkin_vpts_count > 50) {
+ tsync_pcr_tsdemuxpcr_discontinue |=
+ VIDEO_DISCONTINUE;
+ if (tsync_pcr_debug & 0x03)
+ pr_info("v_discontinue,count\n");
+ }
+ } else {
+ last_pcr_checkin_vpts = checkin_vpts;
+ last_pcr_checkin_vpts_count = 0;
+ }
+ } else {
+ last_pcr_checkin_vpts = checkin_vpts;
+ }
}
-
}
EXPORT_SYMBOL(tsync_pcr_pcrscr_set);
tsync_pcr_reset_flag = 0;
tsync_pcr_asynccheck_cnt = 0;
tsync_pcr_vsynccheck_cnt = 0;
- pr_info("wait_pcr_count = 0\n");
-
tsync_pcr_last_tsdemuxpcr = 0;
tsync_pcr_discontinue_local_point = 0;
tsync_pcr_discontinue_point = 0;
tsync_pcr_first_jiffes = 0;
tsync_pcr_first_systime = 0;
speed_check_count = 0;
+ tsync_audio_discontinue = 0;
+ tsync_audio_continue_count = 0;
+ last_discontinue_checkin_apts = 0;
+ tsync_vpts_adjust = 0;
}
}
EXPORT_SYMBOL(tsync_pcr_set_apts);
+int tsync_get_vpts_adjust(void)
+{
+ return tsync_vpts_adjust * 90;
+}
+EXPORT_SYMBOL(tsync_get_vpts_adjust);
+
int tsync_pcr_start(void)
{
timestamp_pcrscr_enable(0);
first_time_record = (jiffies * TIME_UNIT90K) / HZ;
tsync_pcr_started = 1;
- if (tsdemux_pcrscr_valid_cb && tsdemux_pcrscr_valid_cb() == 0) {
+ if ((tsdemux_pcrscr_valid_cb &&
+ tsdemux_pcrscr_valid_cb() == 0) ||
+ tsync_disable_demux_pcr == 1) {
tsync_use_demux_pcr = 0;
tsync_pcr_inited_mode = INIT_PRIORITY_AUDIO;
} else {
tsync_pcr_inited_mode = INIT_PRIORITY_PCR;
}
tsync_pcr_read_cnt = 0;
- pr_info("[tsync_pcr_start]usepcr=%d tsync_pcr_inited_mode=%d\n",
- tsync_pcr_usepcr, tsync_pcr_inited_mode);
add_timer(&tsync_pcr_check_timer);
}
abuf_fatal_error = 0;
return size;
}
-static ssize_t tsync_pcr_freerun_mode_show(struct class *cla,
+static ssize_t tsync_pcr_mode_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", tsync_use_demux_pcr);
+}
+
+static ssize_t tsync_audio_mode_show(struct class *cla,
struct class_attribute *attr,
char *buf)
{
- return sprintf(buf, "%d\n", tsync_pcr_freerun_mode);
+ return sprintf(buf, "%d\n", tsync_audio_mode);
}
-static ssize_t tsync_pcr_freerun_mode_store(struct class *cla,
+static ssize_t tsync_audio_mode_store(struct class *cla,
struct class_attribute *attr,
const char *buf, size_t count)
{
size_t r;
- /*r = sscanf(buf, "%d", &tsync_pcr_freerun_mode);*/
- r = kstrtoint(buf, 0, &tsync_pcr_freerun_mode);
+ r = kstrtoint(buf, 0, &tsync_audio_mode);
+ if (r != 0)
+ return -EINVAL;
+ return count;
+}
- pr_info("%s(%d)\n", __func__, tsync_pcr_freerun_mode);
+static ssize_t tsync_disable_pcr_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", tsync_disable_demux_pcr);
+}
+static ssize_t tsync_disable_pcr_store(struct class *cla,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ size_t r;
+
+ r = kstrtoint(buf, 0, &tsync_disable_demux_pcr);
if (r != 0)
return -EINVAL;
+ return count;
+}
+
+static ssize_t tsync_vpts_adjust_store(struct class *cla,
+ struct class_attribute *attr,
+ const char *buf, size_t count)
+{
+ size_t r;
+ r = kstrtoint(buf, 0, &tsync_vpts_adjust);
+ if (r != 0)
+ return -EINVAL;
return count;
}
+static ssize_t tsync_vpts_adjust_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%d\n", tsync_vpts_adjust);
+}
+
+static ssize_t tsync_audio_level_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ u32 audio_level;
+
+ audio_level = tsync_audio_discontinue & 0xff;
+ return sprintf(buf, "%d\n", audio_level);
+}
+
+static ssize_t tsync_pcr_apts_diff_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ u32 t1, apts_diff;
+
+ t1 = timestamp_get_pts_latency(1);
+ apts_diff = t1 & 0xffff;
+ return sprintf(buf, "%d\n", apts_diff);
+}
+
+static ssize_t tsync_last_checkin_apts_show(struct class *cla,
+ struct class_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "0x%x\n", last_discontinue_checkin_apts);
+}
+
static ssize_t show_reset_flag(struct class *class,
struct class_attribute *attr, char *buf)
{
show_tsync_pcr_dispoint, store_tsync_pcr_dispoint),
__ATTR(audio_resample_type, 0644, NULL,
store_tsync_pcr_audio_resample_type),
- __ATTR(tsync_pcr_freerun_mode, 0644,
- tsync_pcr_freerun_mode_show, tsync_pcr_freerun_mode_store),
+ __ATTR(tsync_pcr_mode, 0644,
+ tsync_pcr_mode_show, NULL),
+ __ATTR(tsync_audio_mode, 0644,
+ tsync_audio_mode_show, tsync_audio_mode_store),
+ __ATTR(tsync_disable_demux_pcr, 0644,
+ tsync_disable_pcr_show, tsync_disable_pcr_store),
+
+ __ATTR(tsync_vpts_adjust, 0644,
+ tsync_vpts_adjust_show, tsync_vpts_adjust_store),
+
+ __ATTR(tsync_audio_level, 0644,
+ tsync_audio_level_show, NULL),
+ __ATTR(tsync_pcr_apts_diff, 0644,
+ tsync_pcr_apts_diff_show, NULL),
+ __ATTR(tsync_last_discontinue_checkin_apts, 0644,
+ tsync_last_checkin_apts_show, NULL),
__ATTR(tsync_pcr_reset_flag, 0664,
show_reset_flag, NULL),
__ATTR(tsync_pcr_apause_flag, 0664,
timestamp_pcrscr_set(0);
wait_pcr_count = 0;
tsync_pcr_debug = 0;
+ tsync_audio_mode = 0;
+ tsync_disable_demux_pcr = 0;
pr_info("[tsync_pcr_init]init success.\n");
return 0;
}