]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epggrab: ota - improve save caching and add no data timeout
authorJaroslav Kysela <perex@perex.cz>
Wed, 30 Jul 2014 10:06:51 +0000 (12:06 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 30 Jul 2014 10:09:41 +0000 (12:09 +0200)
- fix the complete flag load
- improve the save request caching
- mark as completed all timeout states (no data, EPG timeout)

src/epggrab.h
src/epggrab/module/eit.c
src/epggrab/otamux.c

index ed4dbd5bd32ac95a1468153677ccb9ade758ffe5..d507ba0479aa0ebdecd74eaea2b18a79f20f16b1 100644 (file)
@@ -203,7 +203,9 @@ struct epggrab_ota_mux
   LIST_HEAD(,epggrab_ota_map)        om_modules;      ///< List of linked mods
   
   int                                om_complete;     ///< Has completed a scan
+  int                                om_save;         ///< something changed
   gtimer_t                           om_timer;        ///< Per mux active timer
+  gtimer_t                           om_data_timer;   ///< Any EPG data seen?
 
   char                              *om_force_modname;///< Force this module
 
index 14825dce8b88315c4932b879b7eb236d0c5b806b..12faaf9d11f62a78b4bfb9f40a334f4342148acf 100644 (file)
@@ -608,16 +608,16 @@ _eit_callback
   if(!mm)
     goto done;
 
-  if (map->om_first) {
-    map->om_tune_count++;
-    map->om_first = 0;
-  }
-
   /* Get service */
   svc = mpegts_mux_find_service(mm, sid);
   if (!svc)
     goto done;
 
+  if (map->om_first) {
+    map->om_tune_count++;
+    map->om_first = 0;
+  }
+
   /* Register this */
   if (ota)
     epggrab_ota_service_add(map, ota, idnode_uuid_as_str(&svc->s_id), 1);
index 5ef1d7a829bc30d2c4410012849f99062b2062cd..12e7a8cf5cf72d3d5d74915f1fbe8c3db0e93800 100644 (file)
@@ -36,7 +36,8 @@
 
 #define EPGGRAB_OTA_DONE_COMPLETE    0
 #define EPGGRAB_OTA_DONE_TIMEOUT     1
-#define EPGGRAB_OTA_DONE_STOLEN      2
+#define EPGGRAB_OTA_DONE_NO_DATA     2
+#define EPGGRAB_OTA_DONE_STOLEN      3
 
 typedef TAILQ_HEAD(epggrab_ota_head,epggrab_ota_mux) epggrab_ota_head_t;
 
@@ -60,6 +61,7 @@ SKEL_DECLARE(epggrab_ota_mux_skel, epggrab_ota_mux_t);
 SKEL_DECLARE(epggrab_svc_link_skel, epggrab_ota_svc_link_t);
 
 static void epggrab_ota_timeout_cb ( void *p );
+static void epggrab_ota_data_timeout_cb ( void *p );
 static void epggrab_ota_kick_cb ( void *p );
 
 static void epggrab_ota_save ( epggrab_ota_mux_t *ota );
@@ -129,17 +131,25 @@ epggrab_ota_kick ( int delay )
 static void
 epggrab_ota_done ( epggrab_ota_mux_t *om, int reason )
 {
+  static const char *reasons[] = {
+    [EPGGRAB_OTA_DONE_COMPLETE]    = "complete",
+    [EPGGRAB_OTA_DONE_TIMEOUT]     = "timeout",
+    [EPGGRAB_OTA_DONE_NO_DATA]     = "no data",
+    [EPGGRAB_OTA_DONE_STOLEN]      = "stolen"
+  };
   char name[256];
   mpegts_mux_t *mm;
   epggrab_ota_map_t *map;
 
+  if (om->om_save)
+    epggrab_ota_save(om);
+
   mm = mpegts_mux_find(om->om_mux_uuid);
   mpegts_mux_nice_name(mm, name, sizeof(name));
-  tvhdebug("epggrab", "grab done for %s (%s)", name,
-           reason == EPGGRAB_OTA_DONE_TIMEOUT ? "timeout" :
-           (reason == EPGGRAB_OTA_DONE_STOLEN ? "stolen" : "complete"));
+  tvhdebug("epggrab", "grab done for %s (%s)", name, reasons[reason]);
 
   gtimer_disarm(&om->om_timer);
+  gtimer_disarm(&om->om_data_timer);
 
   assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE);
   TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link);
@@ -161,6 +171,15 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason )
   epggrab_ota_kick(1);
 }
 
+static void
+epggrab_ota_complete_mark ( epggrab_ota_mux_t *om )
+{
+  if (!om->om_complete) {
+    om->om_complete = 1;
+    epggrab_ota_save(om);
+  }
+}
+
 static void
 epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm )
 {
@@ -168,6 +187,7 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm )
   epggrab_ota_map_t *map;
   char *modname = om->om_force_modname;
   mpegts_mux_instance_t *mmi = mm->mm_active;
+  int grace;
 
   /* In pending queue? Remove.. */
   if (om->om_q_type == EPGGRAB_OTA_MUX_PENDING)
@@ -177,8 +197,11 @@ 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;
+  grace = mpegts_input_grace(mmi->mmi_input, mm);
   gtimer_arm(&om->om_timer, epggrab_ota_timeout_cb, om,
-             epggrab_ota_timeout_get() + mpegts_input_grace(mmi->mmi_input, mm));
+             epggrab_ota_timeout_get() + grace);
+  gtimer_arm(&om->om_data_timer, epggrab_ota_data_timeout_cb, om,
+             30 + grace); /* 30 seconds to receive any EPG info */
   if (modname) {
     LIST_FOREACH(m, &epggrab_modules, link)
       if (!strcmp(m->id, modname)) {
@@ -299,11 +322,7 @@ epggrab_ota_complete
   lock_assert(&global_lock);
   tvhdebug(mod->id, "grab complete");
 
-  /* Mark */
-  if (!ota->om_complete) {
-    ota->om_complete = 1;
-    epggrab_ota_save(ota);
-  }
+  epggrab_ota_complete_mark(ota);
 
   /* Test for completion */
   LIST_FOREACH(map, &ota->om_modules, om_link) {
@@ -340,8 +359,36 @@ epggrab_ota_timeout_cb ( void *p )
   if (!om)
     return;
 
-  /* Re-queue */
+  /* Abort */
   epggrab_ota_done(om, EPGGRAB_OTA_DONE_TIMEOUT);
+  /* Not completed, but no further data for a long period */
+  /* wait for a manual mux tuning */
+  epggrab_ota_complete_mark(om);
+}
+
+static void
+epggrab_ota_data_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 (map == NULL) {
+    /* Abort */
+    epggrab_ota_done(om, EPGGRAB_OTA_DONE_NO_DATA);
+    /* Not completed, but no data - wait for a manual mux tuning */
+    epggrab_ota_complete_mark(om);
+  }
 }
 
 static void
@@ -461,6 +508,15 @@ done:
     goto next_one;
   if (kick)
     epggrab_ota_kick(64); /* a random number? */
+
+#if ENABLE_TRACE
+  i = r = 0;
+  RB_FOREACH(om, &epggrab_ota_all, om_global_link)
+    i++;
+  TAILQ_FOREACH(om, &epggrab_ota_pending, om_q_link)
+    r++;
+  tvhtrace("epggrab", "mux stats - all %i pending %i", i, r);
+#endif
 }
 
 /*
@@ -539,8 +595,8 @@ epggrab_ota_service_add ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota,
     svcl = epggrab_svc_link_skel;
     SKEL_USED(epggrab_svc_link_skel);
     svcl->uuid = strdup(uuid);
-    if (save && ota->om_complete)
-      epggrab_ota_save(ota);
+    if (save)
+      ota->om_save = 1;
     epggrab_ota_service_trace(ota, svcl, "add new");
   }
 }
@@ -556,7 +612,7 @@ epggrab_ota_service_del ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota,
   free(svcl->uuid);
   free(svcl);
   if (save)
-    epggrab_ota_save(ota);
+    ota->om_save = 1;
 }
 
 /* **************************************************************************
@@ -570,6 +626,7 @@ epggrab_ota_save ( epggrab_ota_mux_t *ota )
   epggrab_ota_svc_link_t *svcl;
   htsmsg_t *e, *l, *l2, *c = htsmsg_create_map();
 
+  ota->om_save = 0;
   htsmsg_add_u32(c, "complete", ota->om_complete);
   l = htsmsg_create_list();
   LIST_FOREACH(map, &ota->om_modules, om_link) {
@@ -621,6 +678,7 @@ epggrab_ota_load_one
     free(ota);
     return;
   }
+  htsmsg_get_u32(c, "complete", (uint32_t *)&ota->om_complete);
   
   if (!(l = htsmsg_get_list(c, "modules"))) return;
   HTSMSG_FOREACH(f, l) {