]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
* Try to detect duplicate EPG entries from the DVB feed and adjust
authorAndreas Öman <andreas@lonelycoder.com>
Sat, 18 Jul 2009 20:07:47 +0000 (20:07 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Sat, 18 Jul 2009 20:07:47 +0000 (20:07 +0000)
    EPG accordingly. The EPG code will search for events with the same
    DVB event ID +- 2 events from the current one. If the event id is
    equal, the prvious (old) entry will be removed in favor of the new one.
    Reason for not blindingly trusting the event id is that some networks
    seem to (incorrectly) reuse IDs.
    Ticket #65

debian/changelog
src/dvb/dvb_tables.c
src/epg.c
src/epg.h
src/xmltv.c

index c801cb35daeb0c670d91a13b63f6aa5ec575bf05..616931dbc2e8a5de93afb627e2afc5f74f14eb8b 100644 (file)
@@ -69,6 +69,13 @@ hts-tvheadend (2.3) hts; urgency=low
   * Add exponential backoff for reconnect attempt in code word client.
     Ticket #80
 
+  * Try to detect duplicate EPG entries from the DVB feed and adjust
+    EPG accordingly. The EPG code will search for events with the same
+    DVB event ID +- 2 events from the current one. If the event id is
+    equal, the prvious (old) entry will be removed in favor of the new one.
+    Reason for not blindingly trusting the event id is that some networks
+    seem to (incorrectly) reuse IDs.
+
 hts-tvheadend (2.2) hts; urgency=low
 
   * Set $HOME so forked processes (XMLTV) will have correct environment
index 34addda2f156f94f46bff40377c737c90af1718a..2364b7c6579c366ea1607e66f370318edf0850b4 100644 (file)
@@ -522,7 +522,8 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
       continue;
     }
 
-    if((e = epg_event_create(ch, start_time, start_time + duration)) == NULL) {
+    if((e = epg_event_create(ch, start_time, start_time + duration,
+                            event_id)) == NULL) {
       len -= dllen;
       ptr += dllen;
       continue;
index 938a1c3c1612ece5acd112e2da2726b861a07a1c..ce2a5630c2797f500f08534b2bba00ffde1751b4 100644 (file)
--- a/src/epg.c
+++ b/src/epg.c
@@ -165,14 +165,74 @@ epg_event_set_content_type(event_t *e, epg_content_type_t *ect)
 }
 
 
+
+/**
+ *
+ */
+static void
+epg_event_destroy(event_t *e)
+{
+  if(e->e_content_type != NULL)
+    LIST_REMOVE(e, e_content_type_link);
+
+  free((void *)e->e_title);
+  free((void *)e->e_desc);
+  LIST_REMOVE(e, e_global_link);
+  free(e);
+}
+
+/**
+ *
+ */
+static void
+epg_event_unref(event_t *e)
+{
+  if(e->e_refcount > 1) {
+    e->e_refcount--;
+    return;
+  }
+  assert(e->e_refcount == 1);
+  epg_event_destroy(e);
+}
+
+/**
+ *
+ */
+static void
+epg_remove_event_from_channel(channel_t *ch, event_t *e)
+{
+  int wasfirst = e == RB_FIRST(&ch->ch_epg_events);
+  event_t *n = RB_NEXT(e, e_channel_link);
+
+  assert(e->e_channel == ch);
+
+  RB_REMOVE(&ch->ch_epg_events, e, e_channel_link);
+  e->e_channel = NULL;
+  epg_event_unref(e);
+
+  if(ch->ch_epg_current == e) {
+    epg_set_current(ch, NULL);
+
+    if(n != NULL)
+      gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
+                    ch, n->e_start);
+  }
+
+  if(wasfirst && (e = RB_FIRST(&ch->ch_epg_events)) != NULL) {
+    gtimer_arm_abs(&ch->ch_epg_timer_head, epg_expire_event_from_channel,
+                  ch, e->e_stop);
+  }
+}
+
+
 /**
  *
  */
 event_t *
-epg_event_create(channel_t *ch, time_t start, time_t stop)
+epg_event_create(channel_t *ch, time_t start, time_t stop, int dvb_id)
 {
   static event_t *skel;
-  event_t *e;
+  event_t *e, *p, *n;
   static int tally;
 
   if((stop - start) > 11 * 3600)
@@ -196,6 +256,7 @@ epg_event_create(channel_t *ch, time_t start, time_t stop)
 
     e->e_id = ++tally;
     e->e_stop = stop;
+    e->e_dvb_id = dvb_id;
 
     LIST_INSERT_HEAD(&epg_hash[e->e_id & EPG_GLOBAL_HASH_MASK], e,
                     e_global_link);
@@ -228,7 +289,7 @@ epg_event_create(channel_t *ch, time_t start, time_t stop)
       printf("Event %s on %s extended stop time\n", e->e_title,
             e->e_channel->ch_name);
       printf("Previous %s", ctime(&e->e_stop));
-       printf("     New %s", ctime(&stop));
+      printf("     New %s", ctime(&stop));
 #endif
       e->e_stop = stop;
       epg_event_changed(e);
@@ -239,6 +300,29 @@ epg_event_create(channel_t *ch, time_t start, time_t stop)
       }
     }
   }
+
+
+  if(dvb_id != -1) {
+    /* Erase any close events with the same DVB event id */
+
+    if((p = RB_PREV(e, e_channel_link)) != NULL) {
+      if(p->e_dvb_id == dvb_id) {
+       epg_remove_event_from_channel(ch, p);
+      } else if((p = RB_PREV(p, e_channel_link)) != NULL) {
+       if(p->e_dvb_id == dvb_id)
+         epg_remove_event_from_channel(ch, p);
+      }
+    }
+
+    if((n = RB_NEXT(e, e_channel_link)) != NULL) {
+      if(n->e_dvb_id == dvb_id) {
+       epg_remove_event_from_channel(ch, n);
+      } else if((n = RB_NEXT(n, e_channel_link)) != NULL) {
+       if(n->e_dvb_id == dvb_id)
+         epg_remove_event_from_channel(ch, n);
+      }
+    }
+  }
   return e;
 }
 
@@ -274,64 +358,6 @@ epg_event_find_by_id(int eventid)
 }
 
 
-/**
- *
- */
-static void
-epg_event_destroy(event_t *e)
-{
-  if(e->e_content_type != NULL)
-    LIST_REMOVE(e, e_content_type_link);
-
-  free((void *)e->e_title);
-  free((void *)e->e_desc);
-  LIST_REMOVE(e, e_global_link);
-  free(e);
-}
-
-/**
- *
- */
-static void
-epg_event_unref(event_t *e)
-{
-  if(e->e_refcount > 1) {
-    e->e_refcount--;
-    return;
-  }
-  assert(e->e_refcount == 1);
-  epg_event_destroy(e);
-}
-
-/**
- *
- */
-static void
-epg_remove_event_from_channel(channel_t *ch, event_t *e)
-{
-  int wasfirst = e == RB_FIRST(&ch->ch_epg_events);
-  event_t *n = RB_NEXT(e, e_channel_link);
-
-  assert(e->e_channel == ch);
-
-  RB_REMOVE(&ch->ch_epg_events, e, e_channel_link);
-  e->e_channel = NULL;
-  epg_event_unref(e);
-
-  if(ch->ch_epg_current == e) {
-    epg_set_current(ch, NULL);
-
-    if(n != NULL)
-      gtimer_arm_abs(&ch->ch_epg_timer_current, epg_ch_check_current_event,
-                    ch, n->e_start);
-  }
-
-  if(wasfirst && (e = RB_FIRST(&ch->ch_epg_events)) != NULL) {
-    gtimer_arm_abs(&ch->ch_epg_timer_head, epg_expire_event_from_channel,
-                  ch, e->e_stop);
-  }
-}
-
 
 /**
  *
index 3a3952b16c259e508bb26a49e92c1c1137f89709..9c922e2d260ea90a109eb5fbda9dcf2ab10d37c0 100644 (file)
--- a/src/epg.h
+++ b/src/epg.h
@@ -61,10 +61,7 @@ typedef struct event {
   const char *e_title;   /* UTF-8 encoded */
   const char *e_desc;    /* UTF-8 encoded */
 
-  int e_source; /* higer is better, and we never downgrade */
-
-#define EVENT_SRC_XMLTV 1
-#define EVENT_SRC_DVB   2
+  int e_dvb_id;
 
 } event_t;
 
@@ -80,7 +77,8 @@ void epg_event_set_desc(event_t *e, const char *desc);
 
 void epg_event_set_content_type(event_t *e, epg_content_type_t *ect);
 
-event_t *epg_event_create(channel_t *ch, time_t start, time_t stop);
+event_t *epg_event_create(channel_t *ch, time_t start, time_t stop,
+                         int dvb_id);
 
 event_t *epg_event_find_by_time(channel_t *ch, time_t t);
 
index 247d7db576fc8acdaa93e495ecd7e379acc0022e..db03b1eaafba5ed6b110ff20e631458374b572a4 100644 (file)
@@ -334,7 +334,7 @@ xmltv_parse_programme_tags(xmltv_channel_t *xc, htsmsg_t *tags,
   const char *desc  = xmltv_get_cdata_by_tag(tags, "desc");
 
   LIST_FOREACH(ch, &xc->xc_channels, ch_xc_link) {
-    if((e = epg_event_create(ch, start, stop)) == NULL)
+    if((e = epg_event_create(ch, start, stop, -1)) == NULL)
       continue;
 
     if(title != NULL) epg_event_set_title(e, title);