From: Jaroslav Kysela Date: Thu, 27 Apr 2017 16:09:31 +0000 (+0200) Subject: parsers: TELETEXT / TEXTSUB - use PCR as the main clock X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7911c035b96aa97e644c8ef43e984fe0c779a329;p=thirdparty%2Ftvheadend.git parsers: TELETEXT / TEXTSUB - use PCR as the main clock Most PTS clocks is just wrong. --- diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index e4f6e8868..570144fce 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -55,6 +55,7 @@ ts_recv_packet0 mpegts_service_t *m; int len2, off, pusi, cc, pid, error, errors = 0; const uint8_t *tsb2; + int64_t pcr; service_set_streaming_status_flags((service_t*)t, TSS_MUX_PACKETS); @@ -69,7 +70,7 @@ ts_recv_packet0 /* Check CC */ - if(tsb2[3] & 0x10) { + if (tsb2[3] & 0x10) { cc = tsb2[3] & 0xf; if(st->es_cc != -1 && cc != st->es_cc) { /* Let the hardware to stabilize and don't flood the log */ @@ -84,7 +85,7 @@ ts_recv_packet0 st->es_cc = (cc + 1) & 0xf; } - if(!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET)) + if (!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET)) continue; if (st->es_type == SCT_CA) @@ -93,9 +94,33 @@ ts_recv_packet0 if (tsb2[3] & 0xc0) /* scrambled */ continue; - off = tsb2[3] & 0x20 ? tsb2[4] + 5 : 4; + if (tsb2[3] & 0x20) { + off = tsb2[4] + 5; + if (st->es_pid == t->s_pcr_pid && !error && off > 10 && (tsb2[5] & 0x10) != 0) { + pcr = (uint64_t)tsb2[6] << 25; + pcr |= (uint64_t)tsb2[7] << 17; + pcr |= (uint64_t)tsb2[8] << 9; + pcr |= (uint64_t)tsb2[9] << 1; + pcr |= ((uint64_t)tsb2[10] >> 7) & 0x01; + /* handle the broken info using candidate variable */ + if (t->s_current_pcr == PTS_UNSET || pts_diff(t->s_current_pcr, pcr) <= 90000 || + (t->s_candidate_pcr != PTS_UNSET && pts_diff(t->s_candidate_pcr, pcr) <= 90000)) { + if (t->s_current_pcr == PTS_UNSET) + tvhtrace(LS_TS, "%s: Initial PCR: %"PRId64, service_nicename((service_t*)t), pcr); + t->s_current_pcr = pcr; + if (t->s_candidate_pcr != PTS_UNSET) { + tvhtrace(LS_TS, "%s: PCR change: %"PRId64, service_nicename((service_t*)t), pcr); + t->s_candidate_pcr = PTS_UNSET; + } + } else { + t->s_candidate_pcr = pcr; + } + } + } else { + off = 4; + } - if(off <= 188 && t->s_status == SERVICE_RUNNING) + if (off <= 188 && t->s_status == SERVICE_RUNNING) parse_mpeg_ts((service_t*)t, st, tsb2 + off, 188 - off, pusi, error); } diff --git a/src/parsers/parser_teletext.c b/src/parsers/parser_teletext.c index 66d77fe1f..0df6a2c9e 100644 --- a/src/parsers/parser_teletext.c +++ b/src/parsers/parser_teletext.c @@ -914,7 +914,7 @@ tt_decode_line(mpegts_service_t *t, elementary_stream_t *st, uint8_t *buf) if(update_tt_clock(t, buf + 34)) teletext_rundown_scan(t, ttp); - ttm->ttm_current_pts = t->s_current_pts; + ttm->ttm_current_pts = t->s_current_pcr + (int64_t)t->s_pts_shift * 900; break; case 1 ... 23: diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 736b604c9..2baccae44 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -1812,9 +1812,9 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data, psize -= hlen; buf = d + 6 + hlen; - if(psize >= 46) { + if(psize >= 46 && t->s_current_pcr != PTS_UNSET) { teletext_input((mpegts_service_t *)t, st, buf, psize); - pkt = pkt_alloc(st->es_type, buf, psize, st->es_curpts, st->es_curdts); + pkt = pkt_alloc(st->es_type, buf, psize, t->s_current_pcr, t->s_current_pcr); pkt->pkt_commercial = t->s_tt_commercial_advice; pkt->pkt_err = st->es_buf.sb_err; parser_deliver(t, st, pkt); @@ -1828,13 +1828,6 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data, static void parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt) { - if(SCT_ISAUDIO(st->es_type) && pkt->pkt_pts != PTS_UNSET && - (t->s_current_pts == PTS_UNSET || - pkt->pkt_pts > t->s_current_pts || - pkt->pkt_pts < t->s_current_pts - 180000)) { - t->s_current_pts = (pkt->pkt_pts + (int64_t)t->s_pts_shift * 900) % PTS_MASK; - } - assert(pkt->pkt_type == st->es_type); pkt->pkt_componentindex = st->es_index; diff --git a/src/service.c b/src/service.c index e126c9be1..220b4ad39 100644 --- a/src/service.c +++ b/src/service.c @@ -704,7 +704,8 @@ service_start(service_t *t, int instance, int weight, int flags, pthread_mutex_lock(&t->s_stream_mutex); t->s_status = SERVICE_RUNNING; - t->s_current_pts = PTS_UNSET; + t->s_current_pcr = PTS_UNSET; + t->s_candidate_pcr = PTS_UNSET; /** * Initialize stream diff --git a/src/service.h b/src/service.h index d215f63d5..68a492293 100644 --- a/src/service.h +++ b/src/service.h @@ -484,7 +484,8 @@ typedef struct service { tvhlog_limit_t s_tei_log; - int64_t s_current_pts; + int64_t s_current_pcr; + int64_t s_candidate_pcr; /* * Local channel numbers per bouquet