]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epg: add auto-ota-module detection
authorJaroslav Kysela <perex@perex.cz>
Tue, 8 Jan 2019 10:53:42 +0000 (11:53 +0100)
committerJaroslav Kysela <perex@perex.cz>
Tue, 8 Jan 2019 12:58:04 +0000 (13:58 +0100)
src/epggrab.h
src/epggrab/module/eit.c
src/epggrab/module/opentv.c
src/epggrab/module/psip.c
src/epggrab/otamux.c
src/epggrab/private.h
src/input/mpegts.h
src/input/mpegts/mpegts_mux.c

index 230cef30f77b38caa4db969aca2ed72b0bb6f52e..b8f2798cefea7858864d2726e8dee812179e2666 100644 (file)
@@ -273,7 +273,6 @@ struct epggrab_ota_map
   epggrab_module_ota_t               *om_module;
   int                                 om_complete;
   uint8_t                             om_first;
-  uint8_t                             om_forced;
   uint64_t                            om_tune_count;
   RB_HEAD(,epggrab_ota_svc_link)      om_svcs;         ///< Services we carry data for
   void                               *om_opaque;
index 13c0e0e03fadc8d2cdb273bbc9b656064f551250..8aca5af087e52e0c1b24d2632870c1f7bc8b76a3 100644 (file)
@@ -1103,11 +1103,6 @@ complete:
 static int _eit_start
   ( epggrab_ota_map_t *map, mpegts_mux_t *dm )
 {
-  epggrab_module_ota_t *m = map->om_module;
-
-  /* Disabled */
-  if (!m->enabled && !map->om_forced) return -1;
-
   return 0;
 }
 
@@ -1138,30 +1133,37 @@ static void _eit_install_handlers
   epggrab_module_ota_t *m, *m2;
   epggrab_ota_mux_eit_plist_t *plist;
   eit_private_t *priv, *priv2;
+  const char *modname;
 
   om = epggrab_ota_find_mux(dm);
   if (!om)
     return;
+  modname = om->om_force_modname;
 
   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) {
-      /* ignore priority for the slave, always prefer master */
-      if (priv && strcmp(priv->slave, priv2->module->id) == 0)
-        continue;
-      /* find the ota map */
-      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;
+  if (strempty(modname)) {
+    LIST_FOREACH(plist, &om->om_eit_plist, link) {
+      priv2 = (eit_private_t *)plist->priv;
+      if (!priv || priv->module->priority < priv2->module->priority) {
+        /* ignore priority for the slave, always prefer master */
+        if (priv && strcmp(priv->slave, priv2->module->id) == 0)
+          continue;
+        /* find the ota map */
+        m = priv2->module;
+        map = epggrab_ota_find_map(om, m);
+        if (!map || !m->enabled) {
+          tvhtrace(m->subsys, "handlers - module '%s' not enabled", m->id);
+          continue;
+        }
+        priv = priv2;
       }
-      priv = priv2;
+    }
+  } else {
+    m = (epggrab_module_ota_t *)epggrab_module_find_by_id(modname);
+    if (m) {
+      priv = (eit_private_t *)m->opaque;
+      map = epggrab_ota_find_map(om, m);
     }
   }
 
@@ -1181,10 +1183,8 @@ static void _eit_install_handlers
 
   if (!strempty(priv->slave)) {
     m2 = (epggrab_module_ota_t *)epggrab_module_find_by_id(priv->slave);
-    if (m2 && m2->enabled) {
-      LIST_FOREACH(map2, &om->om_modules, om_link)
-        if (map2->om_module == m2)
-         break;
+    if (m2) {
+      map2 = epggrab_ota_find_map(om, m2);
       if (map2) {
         tvhtrace(m->subsys, "handlers - detected slave module '%s'", m2->id);
         _eit_install_one_handler(dm, map2);
@@ -1193,6 +1193,8 @@ static void _eit_install_handlers
   }
 
   _eit_install_one_handler(dm, map);
+
+  mpegts_mux_set_epg_module(dm, m->id);
 }
 
 static int _eit_activate(void *m, int e)
@@ -1223,15 +1225,11 @@ static int _eit_tune
   ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm )
 {
   int r = 0;
-  epggrab_module_ota_t *m = map->om_module;
   mpegts_service_t *s;
   epggrab_ota_svc_link_t *osl, *nxt;
 
   lock_assert(&global_lock);
 
-  /* Disabled */
-  if (!m->enabled) return 0;
-
   /* Have gathered enough info to decide */
   if (!om->om_complete)
     return 1;
index eae73d30a6d47cf8e5ae777e949bbd75a111f61d..814ab89f4358cd02bdeb857a33ebef5a2864c1fb 100644 (file)
@@ -813,7 +813,6 @@ static int _opentv_start
   };
 
   /* Ignore */
-  if (!m->enabled && !map->om_forced) return -1;
   if (mod->tsid != mm->mm_tsid) return -1;
 
   /* Install tables */
@@ -967,11 +966,9 @@ static void _opentv_done( void *m )
 static int _opentv_tune
   ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm )
 {
-  epggrab_module_ota_t *m = map->om_module;
-  opentv_module_t *mod = (opentv_module_t*)m;
+  opentv_module_t *mod = (opentv_module_t*)map->om_module;
 
   /* Ignore */
-  if (!m->enabled) return 0;
   if (mod->tsid != mm->mm_tsid) return 0;
 
   return 1;
index aaf14dc0cd96b7ca224c0d288d05c0f0037deabd..d979ba12c79bca5d0a7d2d2251c4b5ebc3a39aeb 100644 (file)
@@ -697,13 +697,9 @@ _psip_mgt_callback
 static int _psip_start
   ( epggrab_ota_map_t *map, mpegts_mux_t *dm )
 {
-  epggrab_module_ota_t *m = map->om_module;
   mpegts_table_t *mt;
   psip_status_t *ps;
 
-  /* Disabled */
-  if (!m->enabled && !map->om_forced) return -1;
-
   ps = calloc(1, sizeof(*ps));
   TAILQ_INIT(&ps->ps_tables);
   ps->ps_mod      = map->om_module;
@@ -730,15 +726,11 @@ static int _psip_tune
   ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm )
 {
   int r = 0;
-  epggrab_module_ota_t *m = map->om_module;
   mpegts_service_t *s;
   epggrab_ota_svc_link_t *osl, *nxt;
 
   lock_assert(&global_lock);
 
-  /* Disabled */
-  if (!m->enabled) return 0;
-
   /* Have gathered enough info to decide */
   if (!om->om_complete)
     return 1;
index d493eb773e2d30ce60c5a25f826bfa25bd43666f..1a6e6661b84d8c46bd7acc07463faabe1c6e064e 100644 (file)
@@ -76,7 +76,18 @@ static void epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota
  * Utilities
  * *************************************************************************/
 
-htsmsg_t *epggrab_ota_module_id_list ( const char *lang )
+epggrab_ota_map_t *epggrab_ota_find_map
+  ( epggrab_ota_mux_t *om, epggrab_module_ota_t *m )
+{
+  epggrab_ota_map_t *map;
+
+  LIST_FOREACH(map, &om->om_modules, om_link)
+    if (map->om_module == m)
+      return map;
+  return NULL;
+}
+
+htsmsg_t *epggrab_ota_module_id_list( const char *lang )
 {
   htsmsg_t *l = eit_module_id_list(lang);
   htsmsg_concat(l, opentv_module_id_list(lang));
@@ -279,7 +290,8 @@ epggrab_ota_complete_mark ( epggrab_ota_mux_t *om, int done )
 static void
 epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm )
 {
-  epggrab_module_t  *m;
+  epggrab_module_t *m;
+  epggrab_module_ota_t *omod;
   epggrab_ota_map_t *map;
   char *modname = om->om_force_modname;
   mpegts_mux_instance_t *mmi = mm->mm_active;
@@ -299,8 +311,12 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm )
                  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 (strempty(modname)) {
+    mtimer_arm_rel(&om->om_data_timer, epggrab_ota_handlers_timeout_cb, om,
+                   sec2mono(5 + grace));
+  } else {
+    mtimer_disarm(&om->om_data_timer);
+  }
   if (modname) {
     LIST_FOREACH(m, &epggrab_modules, link)
       if (!strcmp(m->id, modname)) {
@@ -310,15 +326,20 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm )
   }
   epggrab_ota_free_eit_plist(om);
   LIST_FOREACH(map, &om->om_modules, om_link) {
-    map->om_first    = 1;
-    map->om_forced   = 0;
-    if (modname && !strcmp(modname, map->om_module->id))
-      map->om_forced = 1;
+    omod = map->om_module;
+    map->om_first = 1;
     map->om_complete = 0;
-    if (map->om_module->start(map, mm) < 0) {
+    if (omod->enabled && !strempty(modname) && strcmp(modname, omod->id)) {
       map->om_complete = 1;
-    } else
-      tvhdebug(map->om_module->subsys, "%s: grab started", map->om_module->id);
+      continue;
+    }
+    if (!omod->enabled || omod->start(map, mm) < 0) {
+      map->om_complete = 1;
+    } else {
+      tvhdebug(map->om_module->subsys, "%s: grab started", omod->id);
+    }
+    if (!strempty(modname))
+      omod->handlers(map, mm);
   }
 }
 
@@ -397,10 +418,8 @@ epggrab_ota_register
     }
   }
   
-  /* Find module entry */
-  LIST_FOREACH(map, &ota->om_modules, om_link)
-    if (map->om_module == mod)
-      break;
+  /* Find module map */
+  map = epggrab_ota_find_map(ota, mod);
   if (!map) {
     map = calloc(1, sizeof(epggrab_ota_map_t));
     RB_INIT(&map->om_svcs);
@@ -611,11 +630,15 @@ next_one:
   epg_flag = MM_EPG_DISABLE;
   if (mm->mm_is_enabled(mm)) {
     epg_flag = mm->mm_is_epg(mm);
-    if (epg_flag > MM_EPG_LAST) {
-      epg_flag = MM_EPG_ENABLE;
-    } else if (epg_flag == MM_EPG_MANUAL) {
+    modname = NULL;
+    if (epg_flag == MM_EPG_MANUAL || epg_flag == MM_EPG_DETECTED) {
       modname = epggrab_ota_check_module_id(mm->mm_epg_module_id);
-      if (!modname) epg_flag = MM_EPG_ENABLE;
+      if (strempty(modname)) {
+        epg_flag = MM_EPG_ENABLE;
+        modname = NULL;
+      }
+    } else if (epg_flag > MM_EPG_FORCE) {
+      epg_flag = MM_EPG_ENABLE;
     }
   }
 
@@ -627,7 +650,7 @@ next_one:
   /* Check we have modules attached and enabled */
   i = r = 0;
   LIST_FOREACH(map, &om->om_modules, om_link) {
-    if (map->om_module->tune(map, om, mm)) {
+    if (map->om_module->enabled && map->om_module->tune(map, om, mm)) {
       i++;
       if (modname && !strcmp(modname, map->om_module->id))
         r = 1;
@@ -638,10 +661,10 @@ next_one:
     goto done;
   }
 
-  /* Some init stuff */
-  free(om->om_force_modname);
-  om->om_force_modname = modname ? strdup(modname) : NULL;
+  /* Force the grabber */
+  tvh_str_set(&om->om_force_modname, modname);
 
+  /* Subscribe */
   om->om_requeue = 1;
   if ((r = mpegts_mux_subscribe(mm, NULL, "epggrab",
                                 SUBSCRIPTION_PRIO_EPG,
index 5f211ab631835d0fc5305f97afa5d9ca12d4d50b..bc7aa53063c8155974239aee342ff98ca033d2bc 100644 (file)
@@ -141,6 +141,9 @@ void epggrab_ota_create_and_register_by_id
     int period, int interval, const char *name );
 void epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota );
 
+epggrab_ota_map_t *epggrab_ota_find_map
+  ( epggrab_ota_mux_t *om, epggrab_module_ota_t *m );
+
 /*
  * Delete
  */
index 5054190770de686151baec858cd68c269febb98c..270666c4d06f234c8d8ede06cdb25a6c602494ca 100644 (file)
@@ -411,9 +411,9 @@ enum mpegts_mux_epg_flag
   MM_EPG_DISABLE,
   MM_EPG_ENABLE,
   MM_EPG_FORCE,
-  MM_EPG_MANUAL
+  MM_EPG_MANUAL = 100,
+  MM_EPG_DETECTED
 };
-#define MM_EPG_LAST MM_EPG_MANUAL
 
 enum mpegts_mux_ac3_flag
 {
@@ -942,6 +942,7 @@ int mpegts_mux_set_network_name ( mpegts_mux_t *mm, const char *name );
 int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint16_t tsid, int force );
 int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint16_t onid );
 int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth );
+int mpegts_mux_set_epg_module ( mpegts_mux_t *mm, const char *modid );
 
 void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe );
 void mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt );
index 9d3bbbdd78d724d0f214e410afce6fe2fe3dcd5e..c19621be05ff1cc785aff5cc8e1185472fb4b20d 100644 (file)
@@ -484,6 +484,7 @@ mpegts_mux_epg_list ( void *o, const char *lang )
     { N_("Enable (auto)"),            MM_EPG_ENABLE },
     { N_("Force (auto)"),             MM_EPG_FORCE },
     { N_("Manual selection"),         MM_EPG_MANUAL },
+    { N_("Auto-Detected"),            MM_EPG_DETECTED },
   };
   return strtab2htsmsg(tab, 1, lang);
 }
@@ -1356,6 +1357,25 @@ mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth )
   return 1;
 }
 
+int
+mpegts_mux_set_epg_module ( mpegts_mux_t *mm, const char *modid )
+{
+  switch (mm->mm_epg) {
+  case MM_EPG_ENABLE:
+  case MM_EPG_DETECTED:
+    break;
+  default:
+    return 0;
+  }
+  if (modid && !strcmp(modid, mm->mm_epg_module_id ?: ""))
+    return 0;
+  mm->mm_epg = MM_EPG_DETECTED;
+  tvh_str_update(&mm->mm_epg_module_id, modid);
+  tvhtrace(LS_MPEGTS, "%s - set EPG module id %s", mm->mm_nicename, modid);
+  idnode_changed(&mm->mm_id);
+  return 1;
+}
+
 void
 mpegts_mux_nice_name( mpegts_mux_t *mm, char *buf, size_t len )
 {