]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
streaming - PCR changes - handle non-shared PCR PIDs correctly, fixes #4361
authorJaroslav Kysela <perex@perex.cz>
Tue, 9 May 2017 16:52:30 +0000 (18:52 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 9 May 2017 16:57:12 +0000 (18:57 +0200)
src/input/mpegts/dvb_psi.c
src/input/mpegts/tsdemux.c
src/parsers/parsers.c
src/service.c
src/service.h
src/streaming.c
src/tvheadend.h

index 8d61585422a8e970adf333679257f4aa71dcf349..d01fb944a639a8b39054f951df49f258b714279c 100644 (file)
@@ -2237,6 +2237,7 @@ psi_parse_pmt
   int position;
   int tt_position;
   int video_stream;
+  int pcr_shared = 0;
   const char *lang;
   uint8_t audio_type, audio_version;
   mpegts_mux_t *mux = mt->mt_mux;
@@ -2477,10 +2478,23 @@ psi_parse_pmt
         st->es_ancillary_id = ancillary_id;
         update |= PMT_UPDATE_ANCILLARY_ID;
       }
+
+      if (st->es_pid == t->s_pcr_pid)
+        pcr_shared = 1;
     }
     position++;
   }
 
+  /* Handle PCR 'elementary stream' */
+  if (!pcr_shared) {
+    st = service_stream_type_find((service_t *)t, SCT_PCR);
+    if (st)
+      st->es_pid = t->s_pcr_pid;
+    else
+      st = service_stream_create((service_t*)t, t->s_pcr_pid, SCT_PCR);
+    st->es_delete_me = 0;
+  }
+
   /* Scan again to see if any streams should be deleted */
   for(st = TAILQ_FIRST(&t->s_components); st != NULL; st = next) {
     next = TAILQ_NEXT(st, es_link);
index 5333dd1c140003690e5edcdeaafc86120380600a..b6bdf399bb4e7436b9a91b87500db8171aeeb44a 100644 (file)
@@ -85,12 +85,6 @@ ts_recv_packet0
       st->es_cc = (cc + 1) & 0xf;
     }
 
-    if (!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET))
-      continue;
-
-    if (st->es_type == SCT_CA)
-      continue;
-
     if (tsb2[3] & 0xc0) /* scrambled */
       continue;
 
@@ -122,6 +116,12 @@ ts_recv_packet0
       off = 4;
     }
 
+    if (!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET))
+      continue;
+
+    if (st->es_type == SCT_CA)
+      continue;
+
     if (off <= 188 && t->s_status == SERVICE_RUNNING)
       parse_mpeg_ts((service_t*)t, st, tsb2 + off, 188 - off, pusi, error);
 
index 08b02dd81d4681b724961f9a11cfb303847abf88..4b64973b008e2cd73da1137847183fa0af752042 100644 (file)
@@ -1835,8 +1835,10 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt)
   diff = st->es_type == SCT_DVBSUB ? 4*90000 : 3*90000;
 
   if (pts_diff(pkt->pkt_pcr, pkt->pkt_pts) > diff) {
+    printf("%s: PTS and PCR diff is very big (%"PRId64")\n",
+           service_component_nicename(st), pts_diff(pkt->pkt_pcr, pkt->pkt_pts));
     if (tvhlog_limit(&st->es_pcr_log, 2))
-      tvhwarn(LS_PARSER, "%s: PTS and PCR diff is very large (%"PRId64")",
+      tvhwarn(LS_PARSER, "%s: PTS and PCR diff is very big (%"PRId64")",
               service_component_nicename(st), pts_diff(pkt->pkt_pcr, pkt->pkt_pts));
     goto end;
   }
index 978736e632e500c691658ff6e5353b6014f2f3c3..a11876a16bceb1f4e66e11fa238d06ec42bb6d91 100644 (file)
@@ -429,26 +429,26 @@ service_build_filter_add(service_t *t, elementary_stream_t *st,
 static void
 service_print_filter(service_t *t)
 {
-#if 0
   elementary_stream_t *st;
   caid_t *ca;
 
+  if (!tvhtrace_enabled())
+    return;
   TAILQ_FOREACH(st, &t->s_filt_components, es_filt_link) {
     if (LIST_EMPTY(&st->es_caids)) {
-      tvhinfo(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %s",
+      tvhtrace(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %s",
               t->s_nicename, st->es_index, st->es_pid,
               streaming_component_type2txt(st->es_type),
               lang_code_get(st->es_lang));
     } else {
       LIST_FOREACH(ca, &st->es_caids, link)
         if (ca->use)
-          tvhinfo(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %04x %06x",
+          tvhtrace(LS_SERVICE, "esfilter: \"%s\" %03d %05d %s %04x %06x",
                   t->s_nicename, st->es_index, st->es_pid,
                   streaming_component_type2txt(st->es_type),
                   ca->caid, ca->providerid);
     }
   }
-#endif
 }
 
 /**
@@ -1211,6 +1211,22 @@ service_stream_find_(service_t *t, int pid)
   return NULL;
 }
 
+/**
+ * Find a first elementary stream in a service (by type)
+ */
+elementary_stream_t *
+service_stream_type_find(service_t *t, streaming_component_type_t type)
+{
+  elementary_stream_t *st;
+
+  lock_assert(&t->s_stream_mutex);
+
+  TAILQ_FOREACH(st, &t->s_components, es_link)
+    if(st->es_type == type)
+      return st;
+  return NULL;
+}
+
 /**
  *
  */
@@ -1978,6 +1994,10 @@ void service_save ( service_t *t, htsmsg_t *m )
 
   list = htsmsg_create_list();
   TAILQ_FOREACH(st, &t->s_components, es_link) {
+
+    if (st->es_type == SCT_PCR)
+      continue;
+
     sub = htsmsg_create_map();
 
     htsmsg_add_u32(sub, "pid", st->es_pid);
@@ -2176,7 +2196,7 @@ void service_load ( service_t *t, htsmsg_t *c )
         continue;
 
       type = streaming_component_txt2type(v);
-      if(type == -1)
+      if(type == -1 || type == SCT_PCR)
         continue;
 
       if(htsmsg_get_u32(c, "pid", &pid))
index d85e49762f4eee2c55642e166119933ee4a748bd..8bb6794ddd26af708fa27251a71573752f61ec00 100644 (file)
@@ -544,6 +544,9 @@ service_stream_find(service_t *t, int pid)
     return t->s_last_es;
 }
 
+elementary_stream_t *
+service_stream_type_find(service_t *t, streaming_component_type_t type);
+
 elementary_stream_t *service_stream_create(service_t *t, int pid,
                                     streaming_component_type_t type);
 
index 873a104a251339c15f50f958a862483980f5fecb..6e223d29a3f671e9bb90453f0311b439ada9cee2 100644 (file)
@@ -538,6 +538,8 @@ streaming_start_component_find_by_index(streaming_start_t *ss, int idx)
 static struct strtab streamtypetab[] = {
   { "NONE",       SCT_NONE },
   { "UNKNOWN",    SCT_UNKNOWN },
+  { "RAW",        SCT_RAW },
+  { "PCR",        SCT_PCR },
   { "MPEG2VIDEO", SCT_MPEG2VIDEO },
   { "MPEG2AUDIO", SCT_MPEG2AUDIO },
   { "H264",       SCT_H264 },
index ec8d8b92547ff0d1ab3378cb07b218c824ef42d1..69e5321701a0c4edba588905cd0de6c648e2bcf9 100644 (file)
@@ -273,6 +273,7 @@ typedef enum {
   SCT_NONE = -1,
   SCT_UNKNOWN = 0,
   SCT_RAW = 1,
+  SCT_PCR,
   SCT_MPEG2VIDEO,
   SCT_MPEG2AUDIO,
   SCT_H264,