]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
parsers: TELETEXT / TEXTSUB - use PCR as the main clock
authorJaroslav Kysela <perex@perex.cz>
Thu, 27 Apr 2017 16:09:31 +0000 (18:09 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 27 Apr 2017 16:09:43 +0000 (18:09 +0200)
Most PTS clocks is just wrong.

src/input/mpegts/tsdemux.c
src/parsers/parser_teletext.c
src/parsers/parsers.c
src/service.c
src/service.h

index e4f6e88687f18901f01119c0ca64d98eb0272c63..570144fce2b860b25ad6dcb321327da0b1b7f31f 100644 (file)
@@ -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);
 
   }
index 66d77fe1f3dfec13b07a28955aacb9f9e1628e2b..0df6a2c9e734742eec10c257f4372576748eeb28 100644 (file)
@@ -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:
index 736b604c956c0eec7b72edf65ba8561e6ca26c4a..2baccae44002a0b599614bc5899a7e94419ebc29 100644 (file)
@@ -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;
index e126c9be187286d64b9e5298e84f3340de936351..220b4ad398c865faa34249ddd8052120e17f2d7c 100644 (file)
@@ -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
index d215f63d5af3409e30303eede0e844c99792ebaa..68a492293560619ebfcc0bcf84e2fb524d759a31 100644 (file)
@@ -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