]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
EPG: don't track EPG for disabled channels, fix PSIP EPG - multiple channels
authorJaroslav Kysela <perex@perex.cz>
Wed, 28 Oct 2015 20:36:17 +0000 (21:36 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 28 Oct 2015 20:36:17 +0000 (21:36 +0100)
src/epggrab/channel.c
src/epggrab/module/eit.c
src/epggrab/module/opentv.c
src/epggrab/module/psip.c
src/epggrab/module/pyepg.c
src/epggrab/module/xmltv.c

index f82876160ccfbb823cc9edfe73bec7d863e152ea..fe06053d54c2fb0f07f0dcd129b18798c6124ca3 100644 (file)
@@ -42,7 +42,8 @@ int epggrab_channel_match ( epggrab_channel_t *ec, channel_t *ch )
   const char *chid, *s;
   htsmsg_field_t *f;
 
-  if (!ec || !ch || !ch->ch_epgauto || !ch->ch_enabled || !ec->enabled) return 0;
+  if (!ec || !ch || !ch->ch_epgauto || !ch->ch_enabled || ch->ch_epg_parent ||
+      !ec->enabled) return 0;
   if (ec->only_one && LIST_FIRST(&ec->channels)) return 0; // ignore already paired
 
   chid = channel_get_epgid(ch);
index 51dcbd3e928506bef378fc4ac6ce688984907cb5..06a77916101e182e62df10c1cf5315ce3ec81dac 100644 (file)
@@ -558,14 +558,17 @@ static int _eit_process_event
     int local, int *resched, int *save )
 {
   idnode_list_mapping_t *ilm;
+  channel_t *ch;
   int ret = 0;
 
   if ( len < 12 ) return -1;
 
-  LIST_FOREACH(ilm, &svc->s_channels, ilm_in1_link)
-    ret = _eit_process_event_one(mod, tableid, svc,
-                                 (channel_t *)ilm->ilm_in2,
+  LIST_FOREACH(ilm, &svc->s_channels, ilm_in1_link) {
+    ch = (channel_t *)ilm->ilm_in2;
+    if (!ch->ch_enabled || ch->ch_epg_parent) continue;
+    ret = _eit_process_event_one(mod, tableid, svc, ch,
                                  ptr, len, local, resched, save);
+  }
   return ret;
 }
 
index 30bb6712bd3ba2657ab8788c125abd7ed028f6a4..2e8adef6bd1d72065f13574d6cd80360f83c9efe 100644 (file)
@@ -439,6 +439,7 @@ opentv_parse_event_section
     const uint8_t *buf, int len )
 {
   opentv_module_t *mod = sta->os_mod;
+  channel_t *ch;
   epggrab_channel_t *ec;
   idnode_list_mapping_t *ilm;
   const char *lang = NULL;
@@ -453,10 +454,12 @@ opentv_parse_event_section
   if (!(ec = _opentv_find_epggrab_channel(mod, cid, 0, NULL))) return 0;
 
   /* Iterate all channels */
-  LIST_FOREACH(ilm, &ec->channels, ilm_in2_link)
-    save |= opentv_parse_event_section_one(sta, cid, mjd,
-                                           (channel_t *)ilm->ilm_in2,
+  LIST_FOREACH(ilm, &ec->channels, ilm_in2_link) {
+    ch = (channel_t *)ilm->ilm_in2;
+    if (!ch->ch_enabled || ch->ch_epg_parent) continue;
+    save |= opentv_parse_event_section_one(sta, cid, mjd, ch,
                                            lang, buf, len);
+  }
 
   /* Update EPG */
   if (save) epg_updated();
index 4064111744b7055bbdee542e6003615c690800ea..95c6a1ad4bb706efb08695bf583e2662bbc833f9 100644 (file)
@@ -69,13 +69,70 @@ typedef struct psip_event
  * EIT Event
  * ***********************************************************************/
 
+static int
+_psip_eit_callback_channel
+  (epggrab_module_t *mod, channel_t *ch, const uint8_t *ptr, int count)
+{
+  uint16_t eventid;
+  uint32_t starttime, length;
+  time_t start, stop;
+  int save = 0, save2, i;
+  uint8_t titlelen;
+  unsigned int dlen;
+  char buf[512];
+  epg_broadcast_t *ebc;
+  epg_episode_t *ee;
+  lang_str_t *title;
+
+  for (i = 0; i < count && count >= 12; ) {
+    eventid = (ptr[0] & 0x3f) << 8 | ptr[1];
+    starttime = ptr[2] << 24 | ptr[3] << 16 | ptr[4] << 8 | ptr[5];
+    start = atsc_convert_gpstime(starttime);
+    length = (ptr[6] & 0x0f) << 16 | ptr[7] << 8 | ptr[8];
+    stop = start + length;
+    titlelen = ptr[9];
+    dlen = ((ptr[10+titlelen] & 0x0f) << 8) | ptr[11+titlelen];
+    // tvhtrace("psip", "  %03d: titlelen %d, dlen %d", i, titlelen, dlen);
+
+    if (titlelen + dlen + 12 > count) break;
+
+    atsc_get_string(buf, sizeof(buf), &ptr[10], titlelen, "eng");
+
+    tvhtrace("psip", "  %03d: 0x%04x at %"PRItime_t", duration %d, title: '%s' (%d bytes)",
+      i, eventid, start, length, buf, titlelen);
+
+    ebc = epg_broadcast_find_by_time(ch, start, stop, eventid, 1, &save2);
+    tvhtrace("psip", "  ch='%s', eid=%5d, start=%"PRItime_t","
+        " stop=%"PRItime_t", ebc=%p",
+        ch ? channel_get_name(ch) : "(null)",
+        eventid, start, stop, ebc);
+    if (!ebc) goto next;
+    save |= save2;
+
+    title = lang_str_create();
+    lang_str_add(title, buf, "eng", 0);
+
+    ee = epg_broadcast_get_episode(ebc, 1, &save2);
+    save2 |= epg_episode_set_title2(ee, title, mod);
+    save |= save2;
+
+    lang_str_destroy(title);
+
+    /* Move on */
+next:
+    ptr += titlelen + dlen + 12;
+    i   += titlelen + dlen + 12;
+  }
+  return save;
+}
+
 static int
 _psip_eit_callback
   (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid)
 {
   int r;
   int sect, last, ver;
-  int count, i;
+  int count;
   int save = 0;
   uint16_t tsid;
   uint32_t extraid;
@@ -83,8 +140,10 @@ _psip_eit_callback
   epggrab_ota_map_t    *map = mt->mt_opaque;
   epggrab_module_t     *mod = (epggrab_module_t *)map->om_module;
   epggrab_ota_mux_t    *ota = NULL;
+  channel_t            *ch;
   mpegts_service_t     *svc;
   mpegts_psi_table_state_t *st;
+  idnode_list_mapping_t *ilm;
   char ubuf[UUID_HEX_SIZE];
 
   /* Validate */
@@ -120,64 +179,18 @@ _psip_eit_callback
   ptr  += 7;
   len  -= 7;
 
+  /* Sanity check */
+  if (count > len) goto done;
+
   /* Register this */
   if (ota)
     epggrab_ota_service_add(map, ota, idnode_uuid_as_str(&svc->s_id, ubuf), 1);
 
-  /* No point processing */
-  if (!LIST_FIRST(&svc->s_channels))
-    goto done;
-
-  for (i = 0; i < count && len >= 12; i++) {
-    uint16_t eventid;
-    uint32_t starttime, length;
-    time_t start, stop;
-    int save2 = 0;
-    uint8_t titlelen;
-    unsigned int dlen;
-    char buf[512];
-    epg_broadcast_t *ebc;
-    epg_episode_t *ee;
-    channel_t *ch = (channel_t *)LIST_FIRST(&svc->s_channels)->ilm_in2;
-    lang_str_t       *title;
-
-    eventid = (ptr[0] & 0x3f) << 8 | ptr[1];
-    starttime = ptr[2] << 24 | ptr[3] << 16 | ptr[4] << 8 | ptr[5];
-    start = atsc_convert_gpstime(starttime);
-    length = (ptr[6] & 0x0f) << 16 | ptr[7] << 8 | ptr[8];
-    stop = start + length;
-    titlelen = ptr[9];
-    dlen = ((ptr[10+titlelen] & 0x0f) << 8) | ptr[11+titlelen];
-    // tvhtrace("psip", "  %03d: titlelen %d, dlen %d", i, titlelen, dlen);
-
-    if (titlelen + dlen + 12 > len) return -1;
-
-    atsc_get_string(buf, sizeof(buf), &ptr[10], titlelen, "eng");
-
-    tvhtrace("psip", "  %03d: 0x%04x at %"PRItime_t", duration %d, title: '%s' (%d bytes)",
-      i, eventid, start, length, buf, titlelen);
-
-    ebc = epg_broadcast_find_by_time(ch, start, stop, eventid, 1, &save2);
-    tvhtrace("psip", "  svc='%s', ch='%s', eid=%5d, start=%"PRItime_t","
-        " stop=%"PRItime_t", ebc=%p",
-        svc->s_dvb_svcname ?: "(null)", ch ? channel_get_name(ch) : "(null)",
-        eventid, start, stop, ebc);
-    if (!ebc) goto next;
-
-    title = lang_str_create();
-    lang_str_add(title, buf, "eng", 0);
-
-    ee = epg_broadcast_get_episode(ebc, 1, &save2);
-    save2 |= epg_episode_set_title2(ee, title, mod);
-
-    lang_str_destroy(title);
-
-    save |= save2;
-
-    /* Move on */
-next:
-    ptr += titlelen + dlen + 12;
-    len -= titlelen + dlen + 12;
+  /* For each associated channels */
+  LIST_FOREACH(ilm, &svc->s_channels, ilm_in1_link) {
+    ch = (channel_t *)ilm->ilm_in2;
+    if (!ch->ch_enabled || ch->ch_epg_parent) continue;
+    save |= _psip_eit_callback_channel(mod, ch, ptr, count);
   }
 
   if (save)
index bcf53753dc599540d253af7443a2ad921ad3ee90..1d28dbcf0f13699d6ac404c68189177a449e93a8 100644 (file)
@@ -340,6 +340,7 @@ static int _pyepg_parse_schedule
   int save = 0;
   htsmsg_t *attr, *tags;
   htsmsg_field_t *f;
+  channel_t *ch;
   epggrab_channel_t *ec;
   const char *str;
   idnode_list_mapping_t *ilm;
@@ -354,9 +355,12 @@ static int _pyepg_parse_schedule
   HTSMSG_FOREACH(f, tags) {
     if (strcmp(f->hmf_name, "broadcast") == 0) {
       ec->laststamp = dispatch_clock;
-      LIST_FOREACH(ilm, &ec->channels, ilm_in2_link)
+      LIST_FOREACH(ilm, &ec->channels, ilm_in2_link) {
+        ch = (channel_t *)ilm->ilm_in2;
+        if (!ch->ch_enabled || ch->ch_epg_parent) continue;
         save |= _pyepg_parse_broadcast(mod, htsmsg_get_map_by_field(f),
-                                       (channel_t *)ilm->ilm_in2, stats);
+                                       ch, stats);
+      }
     }
   }
 
index 18d2322cb12070e584e6b2b9671cb0fd7260639e..47faf28662191a15dd4e1800438e9763d4b993e8 100644 (file)
@@ -570,6 +570,7 @@ static int _xmltv_parse_programme
   htsmsg_t *attribs, *tags, *subtag;
   const char *s, *chid, *icon = NULL;
   time_t start, stop;
+  channel_t *ch;
   epggrab_channel_t *ec;
   idnode_list_mapping_t *ilm;
 
@@ -596,9 +597,12 @@ static int _xmltv_parse_programme
   if(stop <= start || stop <= dispatch_clock) return 0;
 
   ec->laststamp = dispatch_clock;
-  LIST_FOREACH(ilm, &ec->channels, ilm_in2_link)
-    save |= _xmltv_parse_programme_tags(mod, (channel_t *)ilm->ilm_in2, tags,
+  LIST_FOREACH(ilm, &ec->channels, ilm_in2_link) {
+    ch = (channel_t *)ilm->ilm_in2;
+    if (!ch->ch_enabled || ch->ch_epg_parent) continue;
+    save |= _xmltv_parse_programme_tags(mod, ch, tags,
                                         start, stop, icon, stats);
+  }
   return save;
 }