From: Jaroslav Kysela Date: Thu, 13 Sep 2018 15:04:57 +0000 (+0200) Subject: epggrab: eit - reimplement the EIT grabber selection X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cbb9cfb0a11dcafd8206db6332bf7f31da84d5b1;p=thirdparty%2Ftvheadend.git epggrab: eit - reimplement the EIT grabber selection --- diff --git a/src/epggrab.h b/src/epggrab.h index 6fd72e232..60d84994d 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -34,6 +34,7 @@ typedef struct epggrab_module_ext epggrab_module_ext_t; typedef struct epggrab_module_ota epggrab_module_ota_t; typedef struct epggrab_module_ota_scraper epggrab_module_ota_scraper_t; typedef struct epggrab_ota_mux epggrab_ota_mux_t; +typedef struct epggrab_ota_mux_eit_plist epggrab_ota_mux_eit_plist_t; typedef struct epggrab_ota_map epggrab_ota_map_t; typedef struct epggrab_ota_svc_link epggrab_ota_svc_link_t; @@ -226,6 +227,12 @@ struct epggrab_ota_svc_link RB_ENTRY(epggrab_ota_svc_link) link; }; +struct epggrab_ota_mux_eit_plist { + LIST_ENTRY(epggrab_ota_mux_eit_plist) link; + const char *src; + void *priv; +}; + /* * TODO: this could be embedded in the mux itself, but by using a soft-link * and keeping it here I can somewhat isolate it from the mpegts code @@ -253,6 +260,9 @@ struct epggrab_ota_mux TAILQ_ENTRY(epggrab_ota_mux) om_q_link; RB_ENTRY(epggrab_ota_mux) om_global_link; + + LIST_HEAD(, epggrab_ota_mux_eit_plist) om_eit_plist; + mtimer_t om_eit_timer; }; /* @@ -266,11 +276,6 @@ struct epggrab_ota_map uint8_t om_first; uint8_t om_forced; uint64_t om_tune_count; - enum { - EPGGRAB_OTA_MUX_EIT_IDLE, - EPGGRAB_OTA_MUX_EIT_NIT, - EPGGRAB_OTA_MUX_EIT_SDT - } om_eit_state; RB_HEAD(,epggrab_ota_svc_link) om_svcs; ///< Muxes we carry data for void *om_opaque; }; @@ -284,6 +289,7 @@ struct epggrab_module_ota /* Transponder tuning */ int (*start) ( epggrab_ota_map_t *map, struct mpegts_mux *mm ); + int (*stop) ( epggrab_ota_map_t *map, struct mpegts_mux *mm ); int (*tune) ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, struct mpegts_mux *mm ); void *opaque; diff --git a/src/epggrab/module.c b/src/epggrab/module.c index aac9884cf..faf29dd3c 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -727,6 +727,7 @@ epggrab_module_ota_t *epggrab_module_ota_create skel->type = EPGGRAB_OTA; skel->activate = ops->activate; skel->start = ops->start; + skel->stop = ops->stop; skel->done = ops->done; skel->tune = ops->tune; skel->process_data = ops->process_data; diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index e76f15e4c..39953c7b1 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -103,6 +103,8 @@ typedef struct eit_module_t static TAILQ_HEAD(, eit_private) eit_private_list; +static void eit_install_handlers(void *aux); + /* ************************************************************************ * Status handling * ***********************************************************************/ @@ -1102,10 +1104,28 @@ static int _eit_start ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) { epggrab_module_ota_t *m = map->om_module; + epggrab_ota_mux_t *om; /* Disabled */ if (!m->enabled && !map->om_forced) return -1; + om = epggrab_ota_find_mux(dm); + if (!om) return -1; + + mtimer_arm_rel(&om->om_eit_timer, eit_install_handlers, dm, sec2mono(20)); + return 0; +} + +static int _eit_stop + ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) +{ + epggrab_ota_mux_t *om; + + om = epggrab_ota_find_mux(dm); + if (!om) return -1; + + mtimer_disarm(&om->om_eit_timer); + return 0; } @@ -1180,45 +1200,48 @@ static int eit_nit_array_check(uint16_t val, uint16_t *array, int array_count) return 1; } -static void eit_install_handlers - (mpegts_mux_t *dm, eit_private_t *priv, const char *src, int state) +static void eit_install_handlers(void *aux) { + mpegts_mux_t *dm = aux; epggrab_ota_mux_t *om; epggrab_ota_map_t *map; - epggrab_module_ota_t *m = priv->module; - int pid, opts = 0; - - if (priv->bat_pid) { - mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL, - "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT); - } + epggrab_module_ota_t *m; + epggrab_ota_mux_eit_plist_t *plist; + eit_private_t *priv, *priv2; + int pid, opts; om = epggrab_ota_find_mux(dm); if (!om) return; - if (state == EPGGRAB_OTA_MUX_EIT_SDT) { - /* check, if NIT EIT is already installed */ - LIST_FOREACH(map, &om->om_modules, om_link) - if (map->om_eit_state == EPGGRAB_OTA_MUX_EIT_NIT) - return; - } - LIST_FOREACH(map, &om->om_modules, om_link) { - if (map->om_module == m) - break; - } - if (!map || (!m->enabled && !map->om_forced)) { - tvhtrace(m->subsys, "%s - module '%s' not enabled", src, m->id); - return; + + priv = NULL; + LIST_FOREACH(plist, &om->om_eit_plist, link) { + priv2 = (eit_private_t *)plist->priv; + if (!priv || priv->module->priority < priv2->module->priority) { + m = priv->module; + LIST_FOREACH(map, &om->om_modules, om_link) { + if (map->om_module == m) + break; + } + if (!map || (!m->enabled && !map->om_forced)) { + tvhtrace(m->subsys, "handlers - module '%s' not enabled", m->id); + continue; + } + priv = priv2; + } } - if (map->om_eit_state != EPGGRAB_OTA_MUX_EIT_IDLE) { - tvhtrace(m->subsys, "%s - module '%s' already installed", src, m->id); - return; + + if (priv->bat_pid) { + mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL, + "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT); } - map->om_eit_state = state; - tvhtrace(m->subsys, "%s - detected module '%s'", src, m->id); + m = priv->module; + + tvhtrace(m->subsys, "handlers - detected module '%s'", m->id); priv = (eit_private_t *)m->opaque; pid = priv->pid; + opts = 0; /* Standard (0x12) */ if (pid == 0) { @@ -1229,7 +1252,28 @@ static void eit_install_handlers mpegts_table_add(dm, 0, 0, _eit_callback, map, map->om_module->id, LS_TBL_EIT, MT_CRC | opts, pid, MPS_WEIGHT_EIT); // TODO: might want to limit recording to EITpf only - tvhdebug(m->subsys, "%s: installed table handlers (%s)", m->id, src); + tvhdebug(m->subsys, "%s: installed table handlers", m->id); +} + +static void eit_queue_priv + (mpegts_mux_t *dm, const char *src, eit_private_t *priv) +{ + epggrab_ota_mux_t *om; + epggrab_ota_mux_eit_plist_t *plist, *plist2; + + om = epggrab_ota_find_mux(dm); + if (!om) + return; + + LIST_FOREACH(plist2, &om->om_eit_plist, link) + if (plist2->priv == priv) + return; + + tvhtrace(LS_TBL_EIT, "%s - detected module '%s'", src, priv->module->id); + plist = calloc(1, sizeof(*plist)); + plist->src = src; + plist->priv = priv; + LIST_INSERT_HEAD(&om->om_eit_plist, plist, link); } void eit_nit_callback @@ -1267,7 +1311,7 @@ void eit_nit_callback if (!priv) return; - eit_install_handlers(dm, priv, "NIT", EPGGRAB_OTA_MUX_EIT_NIT); + eit_queue_priv(dm, "NIT", priv); } void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv) @@ -1276,12 +1320,6 @@ void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv) eit_sdt_t *sdt; eit_private_t *priv = NULL; - /* do not rerun */ - assert(mt->mt_bat == NULL || mt->mt_bat == mt); - if (mt->mt_bat) - return; - mt->mt_bat = mt; - tvhtrace(LS_TBL_EIT, "SDT - tsid %04X (%d) onid %04X (%d) private %08X", dm->mm_tsid, dm->mm_tsid, dm->mm_onid, dm->mm_onid, sdtpriv); @@ -1308,7 +1346,7 @@ void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv) if (!priv) return; - eit_install_handlers(dm, priv, "SDT", EPGGRAB_OTA_MUX_EIT_SDT); + eit_queue_priv(dm, "SDT", priv); } static void _eit_scrape_clear(eit_module_t *mod) @@ -1514,6 +1552,7 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) ops = calloc(1, sizeof(*ops)); priv = calloc(1, sizeof(*priv)); ops->start = _eit_start; + ops->stop = _eit_stop; ops->done = _eit_done; ops->activate = _eit_activate; ops->process_data = _eit_process_data; diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 917741974..6e16c82ab 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -113,6 +113,15 @@ epggrab_ota_timeout_get ( void ) return timeout; } +static void +epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota ) +{ + epggrab_ota_mux_eit_plist_t *plist; + + while ((plist = LIST_FIRST(&ota->om_eit_plist)) != NULL) + free(plist); +} + static int epggrab_ota_queue_one( epggrab_ota_mux_t *om ) { @@ -209,6 +218,9 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason ) assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE); TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link); om->om_q_type = EPGGRAB_OTA_MUX_IDLE; + LIST_FOREACH(map, &om->om_modules, om_link) + if (map->om_module->stop) + map->om_module->stop(map, mm); if (reason == EPGGRAB_OTA_DONE_STOLEN) { /* Do not requeue completed muxes */ if (!om->om_done && om->om_requeue) { @@ -274,13 +286,13 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm ) break; } } + epggrab_ota_free_eit_plist(om); LIST_FOREACH(map, &om->om_modules, om_link) { map->om_first = 1; map->om_forced = 0; if (modname && !strcmp(modname, map->om_module->id)) map->om_forced = 1; map->om_complete = 0; - map->om_eit_state = EPGGRAB_OTA_MUX_EIT_IDLE; if (map->om_module->start(map, mm) < 0) { map->om_complete = 1; } else @@ -777,6 +789,7 @@ epggrab_ota_load_one tvhtrace(LS_EPGGRAB, "loading config for %s", mm->mm_nicename); ota = calloc(1, sizeof(epggrab_ota_mux_t)); + LIST_INIT(&ota->om_eit_plist); ota->om_mux_uuid = mm->mm_id.in_uuid; if (RB_INSERT_SORTED(&epggrab_ota_all, ota, om_global_link, om_id_cmp)) { free(ota); @@ -895,6 +908,7 @@ epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota ) free(map); } free(ota->om_force_modname); + epggrab_ota_free_eit_plist(ota); free(ota); } diff --git a/src/epggrab/private.h b/src/epggrab/private.h index 8b32c5b0f..47a7c949a 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -100,6 +100,7 @@ epggrab_module_ext_t *epggrab_module_ext_create typedef struct epggrab_ota_module_ops { int (*start) (epggrab_ota_map_t *map, struct mpegts_mux *mm); + int (*stop) (epggrab_ota_map_t *map, struct mpegts_mux *mm); int (*activate) (void *m, int e); void (*done) (void *m); int (*tune) (epggrab_ota_map_t *map, epggrab_ota_mux_t *om,