]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts scan: improve dead service detection (add SDT checks)
authorJaroslav Kysela <perex@perex.cz>
Thu, 1 Jan 2015 15:12:23 +0000 (16:12 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 1 Jan 2015 15:12:23 +0000 (16:12 +0100)
src/input/mpegts/dvb_psi.c
src/input/mpegts/mpegts_mux.c
src/service.c

index 0dff0c71290bb8cfab973557bf942a51afb7dc46..e3347fa6625a241d9b3fb13fdca2ea382c8f4b72 100644 (file)
@@ -1020,37 +1020,13 @@ dvb_pat_callback
   uint16_t nit_pid = 0;
   mpegts_mux_t          *mm  = mt->mt_mux;
   mpegts_table_state_t  *st  = NULL;
-  mpegts_service_t *s, *snext;
-  time_t last_seen;
+  mpegts_service_t *s;
 
   /* Begin */
   if (tableid != 0) return -1;
   tsid = (ptr[0] << 8) | ptr[1];
   r    = dvb_table_begin(mt, ptr, len, tableid, tsid, 5,
                          &st, &sect, &last, &ver);
-  if (r == 0 && mt->mt_opaque == NULL) {
-    /*
-     * Disable "not seen" services. It's quite easy algorithm which
-     * compares the time for the most recent services with others.
-     * If there is a big gap (24 hours) the service will be removed.
-     *
-     * Note that this code is run only when the PAT table scan is
-     * fully completed (all live services are known at this point).
-     */
-    last_seen = 0;
-    LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link)
-      if (last_seen < s->s_dvb_check_seen)
-        last_seen = s->s_dvb_check_seen;
-    for (s = LIST_FIRST(&mm->mm_services); s; s = snext) {
-      snext = LIST_NEXT(s, s_dvb_mux_link);
-      if (s->s_enabled && s->s_auto != SERVICE_AUTO_OFF &&
-          s->s_dvb_check_seen + 24 * 3600 < last_seen) {
-        tvhinfo("mpegts", "disabling service %s (missing in PAT)", s->s_nicename ?: "<unknown>");
-        service_set_enabled((service_t *)s, 0, SERVICE_AUTO_PAT_MISSING);
-      }
-    }
-    mt->mt_opaque = mm;
-  }
   if (r != 1) return r;
 
   /* Multiplex */
@@ -1610,6 +1586,9 @@ dvb_sdt_callback
     s       = mpegts_service_find(mm, service_id, 0, 1, &save);
     charset = dvb_charset_find(mn, mm, s);
 
+    if (s)
+      s->s_dvb_check_seen = dispatch_clock;
+
     /* Descriptor loop */
     DVB_DESC_EACH(lptr, llen, dtag, dlen, dptr) {
       tvhtrace("sdt", "    dtag %02X dlen %d", dtag, dlen);
@@ -2430,10 +2409,6 @@ psi_parse_pmt
 void
 psi_tables_default ( mpegts_mux_t *mm )
 {
-  mpegts_service_t *s;
-
-  LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link)
-    s->s_dvb_check_seen = s->s_dvb_last_seen;
   mpegts_table_add(mm, DVB_PAT_BASE, DVB_PAT_MASK, dvb_pat_callback,
                    NULL, "pat", MT_QUICKREQ | MT_CRC | MT_RECORD,
                    DVB_PAT_PID);
index 46e16816b6ebea1a3b421aa705371791a837bc0f..9cebfa1d5b31b68a2a8290938e80a506830ce426 100644 (file)
@@ -104,6 +104,7 @@ mpegts_mux_instance_start
   mpegts_mux_instance_t *mmi = *mmiptr;
   mpegts_mux_t          * mm = mmi->mmi_mux;
   mpegts_input_t        * mi = mmi->mmi_input;
+  mpegts_service_t      *  s;
   mpegts_mux_nice_name(mm, buf, sizeof(buf));
 
   /* Already active */
@@ -114,6 +115,10 @@ mpegts_mux_instance_start
     return 0;
   }
 
+  /* Dead service check */
+  LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link)
+    s->s_dvb_check_seen = s->s_dvb_last_seen;
+
   /* Start */
   mi->mi_display_name(mi, buf2, sizeof(buf2));
   tvhinfo("mpegts", "%s - tuning on %s", buf, buf2);
@@ -832,6 +837,34 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
  * Scanning
  * *************************************************************************/
 
+static void
+mpegts_mux_scan_service_check ( mpegts_mux_t *mm )
+{
+  mpegts_service_t *s, *snext;
+  time_t last_seen;
+
+  /*
+   * Disable "not seen" services. It's quite easy algorithm which
+   * compares the time for the most recent services with others.
+   * If there is a big gap (24 hours) the service will be removed.
+   *
+   * Note that this code is run only when the PAT table scan is
+   * fully completed (all live services are known at this point).
+   */
+  last_seen = 0;
+  LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link)
+    if (last_seen < s->s_dvb_check_seen)
+      last_seen = s->s_dvb_check_seen;
+  for (s = LIST_FIRST(&mm->mm_services); s; s = snext) {
+    snext = LIST_NEXT(s, s_dvb_mux_link);
+    if (s->s_enabled && s->s_auto != SERVICE_AUTO_OFF &&
+        s->s_dvb_check_seen + 24 * 3600 < last_seen) {
+      tvhinfo("mpegts", "disabling service %s (missing in PAT/SDT)", s->s_nicename ?: "<unknown>");
+      service_set_enabled((service_t *)s, 0, SERVICE_AUTO_PAT_MISSING);
+    }
+  }
+}
+
 void
 mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res )
 {
@@ -854,9 +887,10 @@ mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res )
   }
   pthread_mutex_unlock(&mm->mm_tables_lock);
 
-  if (res)
+  if (res) {
     mpegts_network_scan_mux_done(mm);
-  else
+    mpegts_mux_scan_service_check(mm);
+  } else
     mpegts_network_scan_mux_fail(mm);
 }
 
index b6bf458272e3baa560ebec45199ca90506eb1839..5972d9832d80f5b9210a5be23dc82bc10562cc6f 100644 (file)
@@ -183,7 +183,7 @@ service_class_auto_list ( void *o )
   static const struct strtab tab[] = {
     { "",                   0 },
     { "No Auto (Disabled)", 1 },
-    { "Missing In PAT",     2 }
+    { "Missing In PAT/SDT", 2 }
   };
   return strtab2htsmsg(tab);
 }