From: Jaroslav Kysela Date: Fri, 30 Oct 2015 13:30:56 +0000 (+0100) Subject: DVR: improve EPG event update scheme, always check broadcast duration in fuzzy match X-Git-Tag: v4.2.1~1727 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=23576ab53a704f23b21d5e93b35b0e9b043d219b;p=thirdparty%2Ftvheadend.git DVR: improve EPG event update scheme, always check broadcast duration in fuzzy match --- diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index e1c2f289d..1439580df 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -497,6 +497,8 @@ void dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new); void dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e); +void dvr_event_removed(epg_broadcast_t *e); + void dvr_event_updated(epg_broadcast_t *e); dvr_entry_t *dvr_entry_find_by_id(int id); diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 25b502efd..2c6198c6d 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -111,6 +111,7 @@ dvr_entry_assign_broadcast(dvr_entry_t *de, epg_broadcast_t *bcast) de->de_bcast->putref((epg_object_t*)de->de_bcast); notify_delayed(id, "epg", "dvr_delete"); de->de_bcast = NULL; + de->de_dvb_eid = 0; } if (bcast) { bcast->getref((epg_object_t*)bcast); @@ -582,6 +583,12 @@ dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e, uint16_t eid, int64_t const char *title1, *title2; char buf[64]; + /* Wrong length (+/-20%) */ + t1 = de->de_stop - de->de_start; + t2 = e->stop - e->start; + if (abs(t2 - t1) > (t1 / 5)) + return 0; + /* Matching ID */ if (de->de_dvb_eid && eid && de->de_dvb_eid == eid) return 1; @@ -592,12 +599,6 @@ dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e, uint16_t eid, int64_t if (!(title2 = lang_str_get(de->de_title, NULL))) return 0; - /* Wrong length (+/-20%) */ - t1 = de->de_stop - de->de_start; - t2 = e->stop - e->start; - if ( abs(t2 - t1) > (t1 / 5) ) - return 0; - /* Outside of window */ if ((int64_t)llabs(e->start - de->de_start) > time_window) return 0; @@ -1448,7 +1449,7 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) assert(new_e != NULL); /* Ignore */ - if ( e == new_e ) return; + if (e == new_e) return; /* Existing entry */ if ((de = dvr_entry_find_by_event(e))) { @@ -1472,6 +1473,7 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) /* Find match */ } else { + RB_FOREACH(e, &e->channel->ch_epg_schedule, sched_link) { if (dvr_entry_fuzzy_match(de, e, e->dvb_eid, de->de_config->dvr_update_window)) { @@ -1481,17 +1483,34 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) epg_broadcast_get_title(e, NULL), channel_get_name(e->channel), e->start, e->stop); - dvr_entry_assign_broadcast(de, e); - _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0); + _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL, NULL, + 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0); return; } } dvr_entry_assign_broadcast(de, NULL); + } } } -void dvr_event_updated ( epg_broadcast_t *e ) +/** + * Used to notify the DVR that an event has been removed + */ +void +dvr_event_removed(epg_broadcast_t *e) +{ + dvr_entry_t *de = dvr_entry_find_by_event(e); + if (de) { + dvr_entry_assign_broadcast(de, NULL); + dvr_entry_save(de); + } +} + +/** + * Event was updated in epg + */ +void dvr_event_updated(epg_broadcast_t *e) { dvr_entry_t *de; de = dvr_entry_find_by_event(e); @@ -1511,7 +1530,6 @@ void dvr_event_updated ( epg_broadcast_t *e ) epg_broadcast_get_title(e, NULL), channel_get_name(e->channel), e->start, e->stop); - dvr_entry_assign_broadcast(de, e); _dvr_entry_update(de, -1, e, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0); break; } diff --git a/src/epg.c b/src/epg.c index 6b0dddc8f..bb915dd01 100644 --- a/src/epg.c +++ b/src/epg.c @@ -1397,12 +1397,16 @@ epg_serieslink_t *epg_serieslink_deserialize * *************************************************************************/ static void _epg_channel_rem_broadcast - ( channel_t *ch, epg_broadcast_t *ebc, epg_broadcast_t *new ) + ( channel_t *ch, epg_broadcast_t *ebc, epg_broadcast_t *ebc_new ) { - if (new) dvr_event_replaced(ebc, new); RB_REMOVE(&ch->ch_epg_schedule, ebc, sched_link); if (ch->ch_epg_now == ebc) ch->ch_epg_now = NULL; if (ch->ch_epg_next == ebc) ch->ch_epg_next = NULL; + if (ebc_new) { + dvr_event_replaced(ebc, ebc_new); + } else { + dvr_event_removed(ebc); + } _epg_object_putref(ebc); }