]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epggrab: eit - massive fixes for the previous commit 1134/head
authorJaroslav Kysela <perex@perex.cz>
Thu, 13 Sep 2018 15:40:34 +0000 (17:40 +0200)
committerJaroslav Kysela <perex@perex.cz>
Thu, 13 Sep 2018 15:40:34 +0000 (17:40 +0200)
src/epggrab.h
src/epggrab/module.c
src/epggrab/module/eit.c
src/epggrab/otamux.c
src/epggrab/private.h
src/input/mpegts/dvb_psi.c

index 60d84994d53e256e4018c19e0895043edd1d2b24..1ce5b1dbcfa90b6465d963f7be2052b61a1188d3 100644 (file)
@@ -246,8 +246,10 @@ struct epggrab_ota_mux
   uint8_t                            om_complete;     ///< Has completed a scan
   uint8_t                            om_requeue;      ///< Requeue when stolen
   uint8_t                            om_save;         ///< something changed
+  uint8_t                            om_detected;     ///< detected some activity
   mtimer_t                           om_timer;        ///< Per mux active timer
   mtimer_t                           om_data_timer;   ///< Any EPG data seen?
+  mtimer_t                           om_handlers_timer; ///< Run handlers callback
   int64_t                            om_retry_time;   ///< Next time to retry
 
   char                              *om_force_modname;///< Force this module
@@ -262,7 +264,6 @@ struct epggrab_ota_mux
   RB_ENTRY(epggrab_ota_mux)          om_global_link;
 
   LIST_HEAD(, epggrab_ota_mux_eit_plist) om_eit_plist;
-  mtimer_t                           om_eit_timer;
 };
 
 /*
@@ -290,6 +291,7 @@ struct epggrab_module_ota
   /* Transponder tuning */
   int  (*start) ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
   int  (*stop)  ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
+  void (*handlers) (epggrab_ota_map_t *map, struct mpegts_mux *mm );
   int  (*tune)  ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om,
                   struct mpegts_mux *mm );
   void  *opaque;
index faf29dd3c39b6d2e45ca55d617b1c6b83c0dcb3d..8b571a8f75c33b80976cd22a280505c2cac7f031 100644 (file)
@@ -728,6 +728,7 @@ epggrab_module_ota_t *epggrab_module_ota_create
   skel->activate     = ops->activate;
   skel->start        = ops->start;
   skel->stop         = ops->stop;
+  skel->handlers     = ops->handlers;
   skel->done         = ops->done;
   skel->tune         = ops->tune;
   skel->process_data = ops->process_data;
index 39953c7b10d37c56258f3892a4d6dcc3de8c22eb..fdc0d8e35151c127192f9d026041e960562c3604 100644 (file)
@@ -103,8 +103,6 @@ typedef struct eit_module_t
 
 static TAILQ_HEAD(, eit_private) eit_private_list;
 
-static void eit_install_handlers(void *aux);
-
 /* ************************************************************************
  * Status handling
  * ***********************************************************************/
@@ -1104,29 +1102,72 @@ static int _eit_start
   ( epggrab_ota_map_t *map, mpegts_mux_t *dm )
 {
   epggrab_module_ota_t *m = map->om_module;
-  epggrab_ota_mux_t *om;
 
   /* Disabled */
   if (!m->enabled && !map->om_forced) return -1;
 
-  om = epggrab_ota_find_mux(dm);
-  if (!om) return -1;
-
-  mtimer_arm_rel(&om->om_eit_timer, eit_install_handlers, dm, sec2mono(20));
   return 0;
 }
 
-static int _eit_stop
-  ( epggrab_ota_map_t *map, mpegts_mux_t *dm )
+static void _eit_install_handlers
+  ( epggrab_ota_map_t *_map, mpegts_mux_t *dm )
 {
   epggrab_ota_mux_t *om;
+  epggrab_ota_map_t *map;
+  epggrab_module_ota_t *m;
+  epggrab_ota_mux_eit_plist_t *plist;
+  eit_private_t *priv, *priv2;
+  int pid, opts;
 
   om = epggrab_ota_find_mux(dm);
-  if (!om) return -1;
+  if (!om)
+    return;
 
-  mtimer_disarm(&om->om_eit_timer);
+  priv = NULL;
+  map = NULL;
+  LIST_FOREACH(plist, &om->om_eit_plist, link) {
+    priv2 = (eit_private_t *)plist->priv;
+    if (!priv || priv->module->priority < priv2->module->priority) {
+      m = priv2->module;
+      LIST_FOREACH(map, &om->om_modules, om_link) {
+        if (map->om_module == m)
+          break;
+      }
+      if (!map || (!m->enabled && !map->om_forced)) {
+        tvhtrace(m->subsys, "handlers - module '%s' not enabled", m->id);
+        continue;
+      }
+      priv = priv2;
+    }
+  }
 
-  return 0;
+  if (!priv)
+    return;
+
+  epggrab_ota_free_eit_plist(om);
+
+  if (priv->bat_pid) {
+    mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL,
+                     "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT);
+  }
+
+  m = priv->module;
+
+  tvhtrace(m->subsys, "handlers - detected module '%s'", m->id);
+  priv = (eit_private_t *)m->opaque;
+  pid = priv->pid;
+  opts = 0;
+
+  /* Standard (0x12) */
+  if (pid == 0) {
+    pid  = DVB_EIT_PID;
+    opts = MT_RECORD;
+  }
+
+  mpegts_table_add(dm, 0, 0, _eit_callback, map, map->om_module->id, LS_TBL_EIT,
+                   MT_CRC | opts, pid, MPS_WEIGHT_EIT);
+  // TODO: might want to limit recording to EITpf only
+  tvhdebug(m->subsys, "%s: installed table handlers", m->id);
 }
 
 static int _eit_activate(void *m, int e)
@@ -1200,61 +1241,6 @@ static int eit_nit_array_check(uint16_t val, uint16_t *array, int array_count)
   return 1;
 }
 
-static void eit_install_handlers(void *aux)
-{
-  mpegts_mux_t *dm = aux;
-  epggrab_ota_mux_t *om;
-  epggrab_ota_map_t *map;
-  epggrab_module_ota_t *m;
-  epggrab_ota_mux_eit_plist_t *plist;
-  eit_private_t *priv, *priv2;
-  int pid, opts;
-
-  om = epggrab_ota_find_mux(dm);
-  if (!om)
-    return;
-
-  priv = NULL;
-  LIST_FOREACH(plist, &om->om_eit_plist, link) {
-    priv2 = (eit_private_t *)plist->priv;
-    if (!priv || priv->module->priority < priv2->module->priority) {
-      m = priv->module;
-      LIST_FOREACH(map, &om->om_modules, om_link) {
-      if (map->om_module == m)
-        break;
-      }
-      if (!map || (!m->enabled && !map->om_forced)) {
-        tvhtrace(m->subsys, "handlers - module '%s' not enabled", m->id);
-        continue;
-      }
-      priv = priv2;
-    }
-  }
-
-  if (priv->bat_pid) {
-    mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL,
-                     "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT);
-  }
-
-  m = priv->module;
-
-  tvhtrace(m->subsys, "handlers - detected module '%s'", m->id);
-  priv = (eit_private_t *)m->opaque;
-  pid = priv->pid;
-  opts = 0;
-
-  /* Standard (0x12) */
-  if (pid == 0) {
-    pid  = DVB_EIT_PID;
-    opts = MT_RECORD;
-  }
-
-  mpegts_table_add(dm, 0, 0, _eit_callback, map, map->om_module->id, LS_TBL_EIT,
-                   MT_CRC | opts, pid, MPS_WEIGHT_EIT);
-  // TODO: might want to limit recording to EITpf only
-  tvhdebug(m->subsys, "%s: installed table handlers", m->id);
-}
-
 static void eit_queue_priv
   (mpegts_mux_t *dm, const char *src, eit_private_t *priv)
 {
@@ -1274,6 +1260,8 @@ static void eit_queue_priv
   plist->src = src;
   plist->priv = priv;
   LIST_INSERT_HEAD(&om->om_eit_plist, plist, link);
+
+  om->om_detected = 1;
 }
 
 void eit_nit_callback
@@ -1552,7 +1540,7 @@ static void eit_init_one ( const char *id, htsmsg_t *conf )
   ops = calloc(1, sizeof(*ops));
   priv = calloc(1, sizeof(*priv));
   ops->start = _eit_start;
-  ops->stop = _eit_stop;
+  ops->handlers = _eit_install_handlers;
   ops->done = _eit_done;
   ops->activate = _eit_activate;
   ops->process_data = _eit_process_data;
index 6e16c82abfcc17865d39e1d1ab9e9104b6c2c23c..200f3fa391b0a730168a59b073efd3211b0c2626 100644 (file)
@@ -63,6 +63,7 @@ static void epggrab_ota_kick ( int delay );
 
 static void epggrab_ota_timeout_cb ( void *p );
 static void epggrab_ota_data_timeout_cb ( void *p );
+static void epggrab_ota_handlers_timeout_cb ( void *p );
 static void epggrab_ota_kick_cb ( void *p );
 
 static void epggrab_mux_start ( mpegts_mux_t *mm, void *p );
@@ -113,13 +114,15 @@ epggrab_ota_timeout_get ( void )
   return timeout;
 }
 
-static void
+void
 epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota )
 {
   epggrab_ota_mux_eit_plist_t *plist;
 
-  while ((plist = LIST_FIRST(&ota->om_eit_plist)) != NULL)
+  while ((plist = LIST_FIRST(&ota->om_eit_plist)) != NULL) {
+    LIST_REMOVE(plist, link);
     free(plist);
+  }
 }
 
 static int
@@ -214,6 +217,7 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason )
 
   mtimer_disarm(&om->om_timer);
   mtimer_disarm(&om->om_data_timer);
+  mtimer_disarm(&om->om_handlers_timer);
 
   assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE);
   TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link);
@@ -274,11 +278,14 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm )
 
   TAILQ_INSERT_TAIL(&epggrab_ota_active, om, om_q_link);
   om->om_q_type = EPGGRAB_OTA_MUX_ACTIVE;
+  om->om_detected = 0;
   grace = mpegts_input_grace(mmi->mmi_input, mm);
   mtimer_arm_rel(&om->om_timer, epggrab_ota_timeout_cb, om,
                  sec2mono(epggrab_ota_timeout_get() + grace));
   mtimer_arm_rel(&om->om_data_timer, epggrab_ota_data_timeout_cb, om,
                  sec2mono(30 + grace)); /* 30 seconds to receive any EPG info */
+  mtimer_arm_rel(&om->om_data_timer, epggrab_ota_handlers_timeout_cb, om,
+                 sec2mono(5 + grace));
   if (modname) {
     LIST_FOREACH(m, &epggrab_modules, link)
       if (!strcmp(m->id, modname)) {
@@ -476,6 +483,56 @@ epggrab_ota_data_timeout_cb ( void *p )
   }
 }
 
+static void
+epggrab_ota_handlers_timeout2_cb ( void *p )
+{
+  epggrab_ota_mux_t *om = p;
+  epggrab_ota_map_t *map;
+  mpegts_mux_t *mm;
+
+  lock_assert(&global_lock);
+
+  if (!om)
+    return;
+
+  mm = mpegts_mux_find0(&om->om_mux_uuid);
+  if (!mm)
+    return;
+
+  /* Run handlers */
+  LIST_FOREACH(map, &om->om_modules, om_link) {
+    if (!map->om_complete && map->om_module->handlers)
+      map->om_module->handlers(map, mm);
+  }
+}
+
+static void
+epggrab_ota_handlers_timeout_cb ( void *p )
+{
+  epggrab_ota_mux_t *om = p;
+  epggrab_ota_map_t *map;
+
+  lock_assert(&global_lock);
+
+  if (!om)
+    return;
+
+  /* Test for any valid data reception */
+  LIST_FOREACH(map, &om->om_modules, om_link) {
+    if (!map->om_first)
+      break;
+  }
+
+  if (!om->om_detected && map == NULL) {
+    /* wait longer */
+    mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout_cb,
+                   om, sec2mono(5));
+  } else {
+    mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout2_cb,
+                   om, sec2mono(20));
+  }
+}
+
 static void
 epggrab_ota_kick_cb ( void *p )
 {
@@ -898,6 +955,7 @@ epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota  )
 
   mtimer_disarm(&ota->om_timer);
   mtimer_disarm(&ota->om_data_timer);
+  mtimer_disarm(&ota->om_handlers_timer);
   if (head != NULL)
     TAILQ_REMOVE(head, ota, om_q_link);
   RB_REMOVE(&epggrab_ota_all, ota, om_global_link);
index 47a7c949a8b9186087e717b791ff66717f8dd660..9dbc5a9c985d610481d1b2565545e4dd6cf60242 100644 (file)
@@ -101,6 +101,7 @@ epggrab_module_ext_t *epggrab_module_ext_create
 typedef struct epggrab_ota_module_ops {
     int (*start)     (epggrab_ota_map_t *map, struct mpegts_mux *mm);
     int (*stop)      (epggrab_ota_map_t *map, struct mpegts_mux *mm);
+    void (*handlers) (epggrab_ota_map_t *map, struct mpegts_mux *mm);
     int  (*activate) (void *m, int e);
     void (*done)     (void *m);
     int  (*tune)     (epggrab_ota_map_t *map, epggrab_ota_mux_t *om,
@@ -138,6 +139,7 @@ epggrab_ota_mux_t *epggrab_ota_create
 void epggrab_ota_create_and_register_by_id
   ( epggrab_module_ota_t *mod, uint16_t onid, uint16_t tsid,
     int period, int interval, const char *name );
+void epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota );
 
 /*
  * Delete
index db27e3ce19044fe16a9c1501d7b6081094302c8a..a90fc6fcb1acfba407b1b337b8a5cc51adc9f6c9 100644 (file)
@@ -1740,14 +1740,8 @@ dvb_sdt_callback
   if (tableid != 0x42 && tableid != 0x46) return -1;
   r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len,
                       tableid, extraid, 8, &st, &sect, &last, &ver, 0);
-  if (r != 1) {
-    if (r == 0) {
-      /* install EIT handlers, but later than from optional NIT */
-      if (mm->mm_start_monoclock + sec2mono(10) < mclk())
-        eit_sdt_callback(mt, mt->mt_priv);
-    }
+  if (r != 1)
     return r;
-  }
 
   /* ID */
   tvhdebug(mt->mt_subsys, "%s: onid %04X (%d) tsid %04X (%d)",
@@ -1777,6 +1771,8 @@ dvb_sdt_callback
       }
   }
 
+  eit_sdt_callback(mt, mt->mt_priv);
+
   /* Done */
   return dvb_table_end((mpegts_psi_table_t *)mt, st, sect);
 }