]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
* Cancel DVR entries for events that are removed from EPG
authorChris <thaelim@gmail.com>
Fri, 9 Sep 2011 10:24:49 +0000 (20:24 +1000)
committerChris <thaelim@gmail.com>
Fri, 9 Sep 2011 10:24:49 +0000 (20:24 +1000)
* Handle networks that change DVB event ID when updating event details

src/dvr/dvr.h
src/dvr/dvr_db.c
src/epg.c

index d2d6d476d69f815ea91357a66c1cd1407c344cc2..169886ddd126b414b5452da3875ad25bac06be30 100644 (file)
@@ -254,6 +254,8 @@ void dvr_rec_subscribe(dvr_entry_t *de);
 
 void dvr_rec_unsubscribe(dvr_entry_t *de, int stopcode);
 
+void dvr_event_cancelled(event_t *e);
+
 dvr_entry_t *dvr_entry_find_by_id(int id);
 
 dvr_entry_t *dvr_entry_find_by_event(event_t *e);
index 6a31b2d42037db37d5dc260ed7038f3fccff8057..84462f5febad75435ea044a0470f512dcededa43 100644 (file)
@@ -630,6 +630,23 @@ dvr_entry_update(dvr_entry_t *de, const char* de_title, int de_start, int de_sto
   return de;
 }
 
+/**
+ * Used to notify the DVR that an event has been removed from the EPG
+ */
+void 
+dvr_event_cancelled(event_t *e)
+{
+  dvr_entry_t *de;
+
+  de = dvr_entry_find_by_event(e);
+  if (de != NULL) {
+    if (de->de_sched_state == DVR_SCHEDULED)
+      dvr_entry_cancel(de);
+  }
+      
+    
+}
+
 /**
  *
  */
@@ -721,8 +738,7 @@ dvr_entry_find_by_event(event_t *e)
 }
 
 /**
- * Find event with same title starting and ending around same time
- * on same channel
+ * Find dvr entry using 'fuzzy' search
  */
 dvr_entry_t *
 dvr_entry_find_by_event_fuzzy(event_t *e)
@@ -730,10 +746,8 @@ dvr_entry_find_by_event_fuzzy(event_t *e)
   dvr_entry_t *de;
 
   LIST_FOREACH(de, &e->e_channel->ch_dvrs, de_channel_link)
-    if(strcmp(de->de_title, e->e_title) == 0) {
-        if ((abs(de->de_start - e->e_start) < 600) && (abs(de->de_stop - e->e_stop) < 600))
-           return de;
-    }
+    if (abs(de->de_start - e->e_start) < 600 && abs(de->de_stop - e->e_stop) < 600)
+      return de;
   return NULL;
 }
 
index 49d007405528dc2a3dd8c381ddb9ef985a20ac20..40be000196fc2177e057571a42661ab24ab65726 100644 (file)
--- a/src/epg.c
+++ b/src/epg.c
@@ -41,6 +41,9 @@ static struct event_list epg_hash[EPG_GLOBAL_HASH_WIDTH];
 
 static void epg_expire_event_from_channel(void *opauqe);
 static void epg_ch_check_current_event(void *aux);
+/* helper function to fuzzy compare two events */
+static int epg_event_cmp_overlap(event_t *e1, event_t *e2);
+static void epg_erase_duplicates(event_t *e, channel_t *ch);
 
 
 static int
@@ -330,7 +333,7 @@ epg_event_create(channel_t *ch, time_t start, time_t stop, int dvb_id,
                 int *created)
 {
   static event_t *skel;
-  event_t *e, *p, *n;
+  event_t *e;
   static int tally;
 
   if(created != NULL)
@@ -404,31 +407,71 @@ epg_event_create(channel_t *ch, time_t start, time_t stop, int dvb_id,
     }
   }
 
+  epg_erase_duplicates(e, ch);
+  return e;
+}
+
+static void
+epg_erase_duplicates(event_t *e, channel_t *ch) {
+
+  event_t *p, *n;
+  int dvb_id = e->e_dvb_id;
 
   if(dvb_id != -1) {
-    /* Erase any close events with the same DVB event id */
+    /* Erase any close events with the same DVB event id or are very similar*/
 
     if((p = RB_PREV(e, e_channel_link)) != NULL) {
-      if(p->e_dvb_id == dvb_id) {
+      if(p->e_dvb_id == dvb_id || epg_event_cmp_overlap(p, e)) {
+        tvhlog(LOG_DEBUG, "epg",
+               "Removing overlapping event instance %s from EPG", p->e_title);
+        dvr_event_cancelled(p);
        epg_remove_event_from_channel(ch, p);
       } else if((p = RB_PREV(p, e_channel_link)) != NULL) {
-       if(p->e_dvb_id == dvb_id)
+       if(p->e_dvb_id == dvb_id || epg_event_cmp_overlap(p, e)) {
+          tvhlog(LOG_DEBUG, "epg",
+                 "Removing overlapping event instance %s from EPG", p->e_title);
+          dvr_event_cancelled(p);
          epg_remove_event_from_channel(ch, p);
+        }
       }
     }
 
     if((n = RB_NEXT(e, e_channel_link)) != NULL) {
-      if(n->e_dvb_id == dvb_id) {
+      if(n->e_dvb_id == dvb_id || epg_event_cmp_overlap(n, e)) {
+        tvhlog(LOG_DEBUG, "epg",
+               "Removing overlapping event instance %s from EPG", n->e_title);
+        dvr_event_cancelled(n);
        epg_remove_event_from_channel(ch, n);
       } else if((n = RB_NEXT(n, e_channel_link)) != NULL) {
-       if(n->e_dvb_id == dvb_id)
+       if(n->e_dvb_id == dvb_id || epg_event_cmp_overlap(n, e)) {
+          tvhlog(LOG_DEBUG, "epg",
+                 "Removing overlapping event instance %s from EPG", n->e_title);
+          dvr_event_cancelled(n);
          epg_remove_event_from_channel(ch, n);
+        }   
       }
     }
   }
-  return e;
+  
 }
 
+static int
+epg_event_cmp_overlap(event_t *e1, event_t *e2)
+{
+  if ((e1->e_title == NULL) || (e2->e_title == NULL))
+    return 0;
+  
+  if ((e1->e_stop < e2->e_start) || (e2->e_stop < e1->e_start)) {
+    return 0;
+  } else {
+    if ((e1->e_start < e2->e_stop) && (e2->e_start < e1->e_stop)) {
+    if ((e1->e_stop - e2->e_start) > 60 || (e2->e_stop - e1->e_start) > 60)
+        return 1;
+    }
+  }
+
+  return 0;
+}
 
 /**
  *