]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
epg: add support for EITp/f when configured with other grabbers with lower priority
authorJaroslav Kysela <perex@perex.cz>
Fri, 2 Jun 2017 08:24:28 +0000 (10:24 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 2 Jun 2017 08:24:28 +0000 (10:24 +0200)
src/config.c
src/config.h
src/dvr/dvr_config.c
src/dvr/dvr_db.c
src/epg.c
src/epg.h
src/epggrab/module/eit.c

index 09b509ed72ad32cbf84fa438a43ca6509c54c5d6..fef8b7e3c2fa8ef337b36f2ec722081b889f0065 100644 (file)
@@ -1676,7 +1676,8 @@ config_boot ( const char *path, gid_t gid, uid_t uid )
   config.dscp = -1;
   config.descrambler_buffer = 9000;
   config.epg_compress = 1;
-  config.epg_cutwindow = 5*60;
+  config.epg_cut_window = 5*60;
+  config.epg_update_window = 24*3600;
   config_scanfile_ok = 0;
   config.theme_ui = strdup("blue");
 
@@ -2274,7 +2275,17 @@ const idclass_t config_class = {
       .id     = "epg_cutwindow",
       .name   = N_("EPG overlap cut"),
       .desc   = N_("The time window to cut the stop time from the overlapped event in seconds."),
-      .off    = offsetof(config_t, epg_cutwindow),
+      .off    = offsetof(config_t, epg_cut_window),
+      .opts   = PO_EXPERT,
+      .group  = 2
+    },
+    {
+      .type   = PT_U32,
+      .id     = "epg_window",
+      .name   = N_("EPG update window"),
+      .desc   = N_("Maximum allowed difference between event start time when "
+                   "the EPG event is changed in seconds."),
+      .off    = offsetof(config_t, epg_update_window),
       .opts   = PO_EXPERT,
       .group  = 2
     },
index 65c63f07a0dd4a7db22e8c8d9cff91f1e02f2f30..ae03dcb9090521092336069a9f04069687eff6a1 100644 (file)
@@ -61,7 +61,8 @@ typedef struct config {
   int caclient_ui;
   int parser_backlog;
   int epg_compress;
-  uint32_t epg_cutwindow;
+  uint32_t epg_cut_window;
+  uint32_t epg_update_window;
 } config_t;
 
 extern const idclass_t config_class;
index 9e1acf329e9073ef7148bae756c0ee7a9cd1b56b..1d4fc3a5691eea0def30fe79a490b52df626c3fc 100644 (file)
@@ -997,7 +997,7 @@ const idclass_t dvr_config_class = {
       .id       = "epg-update-window",
       .name     = N_("EPG update window"),
       .desc     = N_("Maximum allowed difference between event start time when "
-                     "the EPG event is changed."),
+                     "the EPG event is changed in seconds."),
       .off      = offsetof(dvr_config_t, dvr_update_window),
       .list     = dvr_config_entry_class_update_window_list,
       .def.u32  = 24*3600,
index aa2c375265302e2a91193f3075c755d5fa4485da..b79af632ffc97555f715bc0af3b4261187d6a719 100644 (file)
@@ -846,7 +846,7 @@ dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e, uint16_t eid, int64_t
     return 0;
   
   /* Title match (or contains?) */
-  if (strcmp(title1, title2))
+  if (strcasecmp(title1, title2))
     return 0;
 
   /* episode check */
index e2d22f654ce8208ca5a1198199d032a87c17f215..79539c8caabc5715fbb0607f5245f54f34b3c341 100644 (file)
--- a/src/epg.c
+++ b/src/epg.c
@@ -1721,8 +1721,8 @@ static epg_broadcast_t *_epg_channel_add_broadcast
       _epg_channel_rem_broadcast(ch, ret, NULL);
       return NULL;
     }
-    if (config.epg_cutwindow && ebc->stop - ebc->start > config.epg_cutwindow * 2 &&
-        ebc->stop - ret->start <= config.epg_cutwindow) {
+    if (config.epg_cut_window && ebc->stop - ebc->start > config.epg_cut_window * 2 &&
+        ebc->stop - ret->start <= config.epg_cut_window) {
       tvhtrace(LS_EPG, "cut stop for overlap (b) event %u (%s) on %s @ %s to %s",
                ebc->id, epg_broadcast_get_title(ebc, NULL),
                channel_get_name(ch, channel_blank_name),
@@ -1748,8 +1748,8 @@ static epg_broadcast_t *_epg_channel_add_broadcast
       _epg_channel_rem_broadcast(ch, ret, NULL);
       return NULL;
     }
-    if (config.epg_cutwindow && ret->stop - ret->start > config.epg_cutwindow * 2 &&
-        ret->stop - ebc->start <= config.epg_cutwindow) {
+    if (config.epg_cut_window && ret->stop - ret->start > config.epg_cut_window * 2 &&
+        ret->stop - ebc->start <= config.epg_cut_window) {
       tvhtrace(LS_EPG, "cut stop for overlap (a) event %u (%s) on %s @ %s to %s",
                ebc->id, epg_broadcast_get_title(ebc, NULL),
                channel_get_name(ch, channel_blank_name),
@@ -1790,6 +1790,66 @@ void epg_channel_unlink ( channel_t *ch )
   gtimer_disarm(&ch->ch_epg_timer);
 }
 
+static int epg_match_event_fuzzy(epg_broadcast_t *a, epg_broadcast_t *b)
+{
+  time_t t1, t2;
+  const char *title1, *title2;
+  epg_episode_num_t num1, num2;
+
+  /* Matching ID */
+  if (a->dvb_eid) {
+    if (b->dvb_eid && a->dvb_eid == b->dvb_eid)
+      return 1;
+    return 0;
+  }
+
+  /* Wrong length (+/-20%) */
+  t1 = a->stop - a->start;
+  t2 = b->stop - b->start;
+  if (labs((long)(t2 - t1)) > (t1 / 5))
+    return 0;
+
+  /* No title */
+  if (!(title1 = epg_broadcast_get_title(a, NULL)))
+    return 0;
+  if (!(title2 = epg_broadcast_get_title(b, NULL)))
+    return 0;
+
+  /* Outside of window */
+  if ((int64_t)llabs(b->start - a->start) > config.epg_update_window)
+    return 0;
+
+  /* Title match (or contains?) */
+  if (strcasecmp(title1, title2))
+    return 0;
+
+  /* episode check */
+  if (a->episode && b->episode) {
+    epg_episode_get_epnum(a->episode, &num1);
+    epg_episode_get_epnum(b->episode, &num2);
+    if (epg_episode_number_cmp(&num1, &num2) == 0)
+      return 1;
+  }
+
+  return 0;
+}
+
+epg_broadcast_t *epg_match_now_next ( channel_t *ch, epg_broadcast_t *ebc )
+{
+  epg_broadcast_t *ret;
+
+  if (epg_match_event_fuzzy(ch->ch_epg_now, ebc))
+    ret = ch->ch_epg_now;
+  else if (epg_match_event_fuzzy(ch->ch_epg_next, ebc))
+    ret = ch->ch_epg_next;
+  else
+    return NULL;
+  /* update eid for further lookups */
+  if (ret->dvb_eid != ebc->dvb_eid && ret->dvb_eid == 0 && ebc->dvb_eid)
+    ret->dvb_eid = ebc->dvb_eid;
+  return ret;
+}
+
 /* **************************************************************************
  * Broadcast
  * *************************************************************************/
index bcbb694fc1d26add49d246c8bb9297f52ab97cb3..7be7b245a54a6f4ec962ba503c695314b71ad9ab 100644 (file)
--- a/src/epg.h
+++ b/src/epg.h
@@ -604,6 +604,8 @@ epg_broadcast_t *epg_broadcast_deserialize
 
 /* Unlink */
 void epg_channel_unlink ( struct channel *ch );
+/* Match now / next events */
+epg_broadcast_t *epg_match_now_next ( struct channel *ch, epg_broadcast_t *ebc );
 
 /* ************************************************************************
  * Global config
index 78f4ecdbb445bf8803101b824fde258e76ff6754..66441bbfffa6b3555ae6775131886dadd33ed13f 100644 (file)
@@ -421,12 +421,12 @@ static int _eit_process_event_one
     const uint8_t *ptr, int len,
     int local, int *resched, int *save )
 {
-  int dllen, save2 = 0;
+  int dllen, save2 = 0, rsonly = 0;
   time_t start, stop;
   uint16_t eid;
   uint8_t dtag, dlen, running;
-  epg_broadcast_t *ebc;
-  epg_episode_t *ee = NULL;
+  epg_broadcast_t *ebc, _ebc;
+  epg_episode_t *ee = NULL, _ee;
   epg_serieslink_t *es;
   epg_running_t run;
   eit_event_t ev;
@@ -455,11 +455,18 @@ static int _eit_process_event_one
            eid, tableid, running,
            gmtime2local(start, tm1, sizeof(tm1)),
            gmtime2local(stop, tm2, sizeof(tm2)), ebc);
-  if (!ebc) return 0;
+  if (!ebc) {
+    if (tableid == 0x4e)
+      rsonly = 1;
+    else
+      return 0;
+  }
 
   /* Mark re-schedule detect (only now/next) */
-  if (save2 && tableid < 0x50) *resched = 1;
-  *save |= save2;
+  if (!rsonly) {
+    if (save2 && tableid < 0x50) *resched = 1;
+    *save |= save2;
+  }
 
   /* Process tags */
   memset(&ev, 0, sizeof(ev));
@@ -507,6 +514,28 @@ static int _eit_process_event_one
     ptr   += dlen;
   }
 
+  if (rsonly) {
+    memset(&_ebc, 0, sizeof(_ebc));
+    if (*ev.suri)
+      if ((es = epg_serieslink_find_by_uri(ev.suri, mod, 0, 0, NULL)))
+        _ebc.serieslink = es;
+    
+    if (*ev.uri && (ee = epg_episode_find_by_uri(ev.uri, mod, 0, 0, NULL))) {
+      _ee = *ee;
+    } else {
+      memset(&_ee, 0, sizeof(_ee));
+    }
+    _ebc.episode = &_ee;
+    _ebc.dvb_eid = eid;
+    _ebc.start = start;
+    _ebc.stop = stop;
+    _ee.title = ev.title;
+
+    ebc = epg_match_now_next(ch, &_ebc);
+    tvhtrace(mod->subsys, "%s:  running state only ebc=%p", svc->s_dvb_svcname ?: "(null)", ebc);
+    goto tidy;
+  }
+
   /*
    * Broadcast
    */
@@ -569,6 +598,8 @@ static int _eit_process_event_one
 
   *save |= epg_broadcast_change_finish(ebc, changes2, 0);
 
+
+tidy:
   /* Tidy up */
 #if TODO_ADD_EXTRA
   if (ev.extra)   htsmsg_destroy(ev.extra);
@@ -579,7 +610,7 @@ static int _eit_process_event_one
   if (ev.desc)    lang_str_destroy(ev.desc);
 
   /* use running flag only for current broadcast */
-  if (running && tableid == 0x4e) {
+  if (ebc && running && tableid == 0x4e) {
     if (sect == 0) {
       switch (running) {
       case 2:  run = EPG_RUNNING_WARM;  break;
@@ -589,7 +620,6 @@ static int _eit_process_event_one
       }
       epg_broadcast_notify_running(ebc, EPG_SOURCE_EIT, run);
     } else if (sect == 1 && running != 2 && running != 3 && running != 4) {
-      epg_broadcast_notify_running(ebc, EPG_SOURCE_EIT, EPG_RUNNING_STOP);
     }
   }