From: Jaroslav Kysela Date: Fri, 2 Jun 2017 08:24:28 +0000 (+0200) Subject: epg: add support for EITp/f when configured with other grabbers with lower priority X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3c44ff21e66ff617d760818d4c809cded416def1;p=thirdparty%2Ftvheadend.git epg: add support for EITp/f when configured with other grabbers with lower priority --- diff --git a/src/config.c b/src/config.c index 09b509ed7..fef8b7e3c 100644 --- a/src/config.c +++ b/src/config.c @@ -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 }, diff --git a/src/config.h b/src/config.h index 65c63f07a..ae03dcb90 100644 --- a/src/config.h +++ b/src/config.h @@ -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; diff --git a/src/dvr/dvr_config.c b/src/dvr/dvr_config.c index 9e1acf329..1d4fc3a56 100644 --- a/src/dvr/dvr_config.c +++ b/src/dvr/dvr_config.c @@ -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, diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index aa2c37526..b79af632f 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -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 */ diff --git a/src/epg.c b/src/epg.c index e2d22f654..79539c8ca 100644 --- 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 * *************************************************************************/ diff --git a/src/epg.h b/src/epg.h index bcbb694fc..7be7b245a 100644 --- 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 diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index 78f4ecdbb..66441bbff 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -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); } }