From: Jaroslav Kysela Date: Mon, 7 Jan 2019 10:01:27 +0000 (+0100) Subject: epggrab: reimplement the OTA grabber selection per mux X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cb01c36843aca863049350da192fac0740155ae5;p=thirdparty%2Ftvheadend.git epggrab: reimplement the OTA grabber selection per mux --- diff --git a/src/epggrab.h b/src/epggrab.h index 728b4bab2..230cef30f 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -396,6 +396,8 @@ void epggrab_channel_mod ( struct channel *ch ); */ void epggrab_ota_queue_mux( struct mpegts_mux *mm ); epggrab_ota_mux_t *epggrab_ota_find_mux ( struct mpegts_mux *mm ); +htsmsg_t *epggrab_ota_module_id_list( const char *lang ); +const char *epggrab_ota_check_module_id( const char *id ); #endif /* __EPGGRAB_H__ */ diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index 93d2dfe76..13c0e0e03 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -55,6 +55,7 @@ typedef struct eit_sdt { typedef struct eit_private { TAILQ_ENTRY(eit_private) link; + lang_str_t *name; epggrab_module_ota_t *module; uint16_t pid; uint16_t bat_pid; @@ -1457,6 +1458,7 @@ static void _eit_done0( eit_private_t *priv ) free(nit); } free(priv->ops); + lang_str_destroy(priv->name); free(priv); } @@ -1619,6 +1621,7 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) } } } + priv->name = name_str; if (name_str) { priv->module = (epggrab_module_ota_t *) eit_module_ota_create(id, LS_TBL_EIT, NULL, @@ -1629,7 +1632,6 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) tvherror(LS_TBL_EIT, "missing name for '%s' in config", id); _eit_done0(priv); } - lang_str_destroy(name_str); } void eit_init ( void ) @@ -1651,6 +1653,34 @@ void eit_init ( void ) htsmsg_destroy(c); } +htsmsg_t *eit_module_id_list( const char *lang ) +{ + eit_private_t *priv, *priv2; + htsmsg_t *e, *l = htsmsg_create_list(); + + TAILQ_FOREACH(priv, &eit_private_list, link) { + TAILQ_FOREACH(priv2, &eit_private_list, link) + if (strcmp(priv2->slave, priv->module->id) == 0) + break; + if (priv2) continue; /* show only parents */ + e = htsmsg_create_key_val(priv->module->id, lang_str_get(priv->name, lang)); + htsmsg_add_msg(l, NULL, e); + } + return l; +} + +const char *eit_check_module_id ( const char *id ) +{ + eit_private_t *priv; + + if (!id) return NULL; + TAILQ_FOREACH(priv, &eit_private_list, link) { + if (strcmp(id, priv->module->id) == 0) + return priv->module->id; + } + return NULL; +} + void eit_done ( void ) { } diff --git a/src/epggrab/module/opentv.c b/src/epggrab/module/opentv.c index 62f8ff8e0..eae73d30a 100644 --- a/src/epggrab/module/opentv.c +++ b/src/epggrab/module/opentv.c @@ -1066,6 +1066,31 @@ static void _opentv_prov_load ( htsmsg_t *m ) htsmsg_destroy(m); } +htsmsg_t *opentv_module_id_list( const char *lang ) +{ + epggrab_module_t *m; + htsmsg_t *e, *l = htsmsg_create_list(); + + LIST_FOREACH(m, &epggrab_modules, link) { + if (strncmp(m->id, "opentv-", 7)) continue; + e = htsmsg_create_key_val(m->id, m->name); + htsmsg_add_msg(l, NULL, e); + } + return l; +} + +const char *opentv_check_module_id ( const char *id ) +{ + epggrab_module_t *m; + + if (!id || strncmp(id, "opentv-", 7)) + return NULL; + LIST_FOREACH(m, &epggrab_modules, link) + if (strcmp(m->id, id) == 0) + return m->id; + return NULL; +} + /* ************************************************************************ * Module Setup * ***********************************************************************/ diff --git a/src/epggrab/module/psip.c b/src/epggrab/module/psip.c index 719e8a16b..aaf14dc0c 100644 --- a/src/epggrab/module/psip.c +++ b/src/epggrab/module/psip.c @@ -762,6 +762,21 @@ static int _psip_tune return r; } +htsmsg_t *psip_module_id_list( const char *lang ) +{ + htsmsg_t *e, *l = htsmsg_create_list(); + e = htsmsg_create_key_val("psip", "PSIP: ATSC Grabber"); + htsmsg_add_msg(l, NULL, e); + return l; +} + +const char *psip_check_module_id ( const char *id ) +{ + if (id && strcmp(id, "psip") == 0) + return "psip"; + return NULL; +} + void psip_init ( void ) { static epggrab_ota_module_ops_t ops = { diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 97128efdd..d493eb773 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -76,6 +76,21 @@ static void epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota * Utilities * *************************************************************************/ +htsmsg_t *epggrab_ota_module_id_list ( const char *lang ) +{ + htsmsg_t *l = eit_module_id_list(lang); + htsmsg_concat(l, opentv_module_id_list(lang)); + htsmsg_concat(l, psip_module_id_list(lang)); + return l; +} + +const char *epggrab_ota_check_module_id( const char *id ) +{ + return eit_check_module_id(id) ?: + opentv_check_module_id(id) ?: + psip_check_module_id(id); +} + static int om_id_cmp ( epggrab_ota_mux_t *a, epggrab_ota_mux_t *b ) { @@ -547,21 +562,6 @@ epggrab_ota_kick_cb ( void *p ) } networks[64], *net; /* more than 64 networks? - you're a king */ int i, r, networks_count = 0, epg_flag, kick = 1; const char *modname; - static const char *modnames[] = { - [MM_EPG_DISABLE] = NULL, - [MM_EPG_ENABLE] = NULL, - [MM_EPG_FORCE] = NULL, - [MM_EPG_ONLY_EIT] = "eit", - [MM_EPG_ONLY_PSIP] = "psip", - [MM_EPG_ONLY_UK_FREESAT] = "uk_freesat", - [MM_EPG_ONLY_UK_FREEVIEW] = "uk_freeview", - [MM_EPG_ONLY_UK_CABLE_VIRGIN] = "uk_cable_virgin", - [MM_EPG_ONLY_VIASAT_BALTIC] = "viasat_baltic", - [MM_EPG_ONLY_BULSATCOM_39E] = "Bulsatcom_39E", - [MM_EPG_ONLY_OPENTV_SKY_UK] = "opentv-skyuk", - [MM_EPG_ONLY_OPENTV_SKY_ITALIA] = "opentv-skyit", - [MM_EPG_ONLY_OPENTV_SKY_AUSAT] = "opentv-ausat", - }; lock_assert(&global_lock); @@ -611,9 +611,12 @@ next_one: epg_flag = MM_EPG_DISABLE; if (mm->mm_is_enabled(mm)) { epg_flag = mm->mm_is_epg(mm); - if (epg_flag > MM_EPG_LAST) + if (epg_flag > MM_EPG_LAST) { epg_flag = MM_EPG_ENABLE; - modname = epg_flag >= 0 ? modnames[epg_flag] : NULL; + } else if (epg_flag == MM_EPG_MANUAL) { + modname = epggrab_ota_check_module_id(mm->mm_epg_module_id); + if (!modname) epg_flag = MM_EPG_ENABLE; + } } if (epg_flag < 0 || epg_flag == MM_EPG_DISABLE) { diff --git a/src/epggrab/private.h b/src/epggrab/private.h index 9dbc5a9c9..5f211ab63 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -208,11 +208,17 @@ void eit_init ( void ); void eit_done ( void ); void eit_load ( void ); +htsmsg_t *eit_module_id_list( const char *lang ); +const char *eit_check_module_id ( const char *id ); + /* OpenTV module */ void opentv_init ( void ); void opentv_done ( void ); void opentv_load ( void ); +htsmsg_t *opentv_module_id_list( const char *lang ); +const char *opentv_check_module_id ( const char *id ); + /* XMLTV module */ void xmltv_init ( void ); void xmltv_done ( void ); @@ -223,4 +229,8 @@ void psip_init ( void ); void psip_done ( void ); void psip_load ( void ); +htsmsg_t *psip_module_id_list( const char *lang ); +const char *psip_check_module_id ( const char *id ); + + #endif /* __EPGGRAB_PRIVATE_H__ */ diff --git a/src/htsmsg.c b/src/htsmsg.c index 734419aa3..5466cc136 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -266,6 +266,23 @@ htsmsg_create_list(void) } + +/* + * + */ +void +htsmsg_concat(htsmsg_t *msg, htsmsg_t *sub) +{ + if (sub == NULL) + return; + assert(msg->hm_islist == sub->hm_islist); + if (msg->hm_islist != sub->hm_islist) + return; + TAILQ_CONCAT(&msg->hm_fields, &sub->hm_fields, hmf_link); + htsmsg_destroy(sub); +} + + /* * */ diff --git a/src/htsmsg.h b/src/htsmsg.h index d15c547e5..1be066e72 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -130,6 +130,11 @@ htsmsg_t *htsmsg_create_map(void); */ htsmsg_t *htsmsg_create_list(void); +/** + * Concat msg2 to msg1 (list or map) + */ +void htsmsg_concat(htsmsg_t *msg1, htsmsg_t *msg2); + /** * Remove a given field from a msg */ diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 542640ce6..505419077 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -411,18 +411,9 @@ enum mpegts_mux_epg_flag MM_EPG_DISABLE, MM_EPG_ENABLE, MM_EPG_FORCE, - MM_EPG_ONLY_EIT, - MM_EPG_ONLY_UK_FREESAT, - MM_EPG_ONLY_UK_FREEVIEW, - MM_EPG_ONLY_VIASAT_BALTIC, - MM_EPG_ONLY_OPENTV_SKY_UK, - MM_EPG_ONLY_OPENTV_SKY_ITALIA, - MM_EPG_ONLY_OPENTV_SKY_AUSAT, - MM_EPG_ONLY_BULSATCOM_39E, - MM_EPG_ONLY_PSIP, - MM_EPG_ONLY_UK_CABLE_VIRGIN + MM_EPG_MANUAL }; -#define MM_EPG_LAST MM_EPG_ONLY_UK_CABLE_VIRGIN +#define MM_EPG_LAST MM_EPG_MANUAL enum mpegts_mux_ac3_flag { @@ -540,6 +531,7 @@ struct mpegts_mux char *mm_crid_authority; int mm_enabled; int mm_epg; + char *mm_epg_module_id; char *mm_charset; int mm_pmt_ac3; int mm_eit_tsid_nocheck; diff --git a/src/input/mpegts/iptv/iptv_auto.c b/src/input/mpegts/iptv/iptv_auto.c index 0ee497df8..88fb7c1b5 100644 --- a/src/input/mpegts/iptv/iptv_auto.c +++ b/src/input/mpegts/iptv/iptv_auto.c @@ -22,6 +22,7 @@ #include "iptv_private.h" #include "channels.h" #include "download.h" +#include "epggrab.h" #include "misc/m3u.h" #include @@ -36,7 +37,7 @@ typedef struct auto_private { /* * */ -static int _epgcfg_from_str(const char *str) +static int _epgcfg_from_str(const char *str, char *manual, size_t manual_len) { static struct strtab cfgs[] = { { "0", MM_EPG_DISABLE }, @@ -48,18 +49,19 @@ static int _epgcfg_from_str(const char *str) { "enable", MM_EPG_ENABLE }, { "on", MM_EPG_ENABLE }, { "force", MM_EPG_FORCE }, - { "eit", MM_EPG_ONLY_EIT }, - { "uk_freesat", MM_EPG_ONLY_UK_FREESAT }, - { "uk_freeview", MM_EPG_ONLY_UK_FREEVIEW }, - { "viasat_baltic", MM_EPG_ONLY_VIASAT_BALTIC }, - { "opentv_sky_uk", MM_EPG_ONLY_OPENTV_SKY_UK }, - { "opentv_sky_italia", MM_EPG_ONLY_OPENTV_SKY_ITALIA }, - { "opentv_sky_ausat", MM_EPG_ONLY_OPENTV_SKY_AUSAT }, - { "bulsatcom_39e", MM_EPG_ONLY_BULSATCOM_39E }, - { "psip", MM_EPG_ONLY_PSIP }, { NULL } }; - return str ? str2val(str, cfgs) : -1; + int r = str ? str2val(str, cfgs) : -1; + if (manual) *manual = '\0'; + if (r < 0) { + const char *s = epggrab_ota_check_module_id(str); + if (s) { + r = MM_EPG_MANUAL; + if (manual) + strlcpy(manual, s, manual_len); + } + } + return r; } /* @@ -86,7 +88,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, int64_t chnum2, vlcprog; const char *url, *url2, *name, *logo, *epgid, *tags; char *s; - char custom[512], name2[128], buf[32], *n; + char custom[512], name2[128], buf[32], *moduleid, *n; url = htsmsg_get_str(item, "m3u-url"); @@ -126,7 +128,8 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, logo = htsmsg_get_str(item, "logo"); epgid = htsmsg_get_str(item, "tvg-id"); - epgcfg = _epgcfg_from_str(htsmsg_get_str(item, "tvh-epg")); + moduleid = alloca(64); + epgcfg = _epgcfg_from_str(htsmsg_get_str(item, "tvh-epg"), moduleid, 64); tags = htsmsg_get_str(item, "tvh-tags"); if (!tags) tags = htsmsg_get_str(item, "group-title"); if (tags) { @@ -260,6 +263,11 @@ skip_url: im->mm_epg = epgcfg; change = 1; } + if (moduleid[0] && strcmp(im->mm_epg_module_id ?: "", moduleid)) { + free(im->mm_epg_module_id); + im->mm_epg_module_id = strdup(moduleid); + change = 1; + } if (muxprio >= 0 && im->mm_iptv_priority != muxprio) { im->mm_iptv_priority = muxprio; change = 1; @@ -300,6 +308,8 @@ skip_url: htsmsg_add_str(conf, "iptv_hdr", custom); if (epgcfg >= 0) htsmsg_add_s32(conf, "epg", epgcfg); + if (moduleid[0]) + htsmsg_add_str(conf, "epg_module_id", moduleid); if (in->in_tsid_accept_zero_value) htsmsg_add_s32(conf, "tsid_zero", 1); if (!htsmsg_get_s64(item, "vlc-program", &vlcprog) && diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 58b132bb7..9d3bbbdd7 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -26,6 +26,7 @@ #include "access.h" #include "profile.h" #include "dvb_charset.h" +#include "epggrab.h" #include @@ -482,20 +483,17 @@ mpegts_mux_epg_list ( void *o, const char *lang ) { N_("Disable"), MM_EPG_DISABLE }, { N_("Enable (auto)"), MM_EPG_ENABLE }, { N_("Force (auto)"), MM_EPG_FORCE }, - { N_("Only EIT"), MM_EPG_ONLY_EIT }, - { N_("Only PSIP (ATSC)"), MM_EPG_ONLY_PSIP }, - { N_("Only UK Freesat"), MM_EPG_ONLY_UK_FREESAT }, - { N_("Only UK Freeview"), MM_EPG_ONLY_UK_FREEVIEW }, - { N_("Only UK Cable Virgin"), MM_EPG_ONLY_UK_CABLE_VIRGIN }, - { N_("Only Viasat Baltic"), MM_EPG_ONLY_VIASAT_BALTIC }, - { N_("Only Bulsatcom 39E"), MM_EPG_ONLY_BULSATCOM_39E }, - { N_("Only OpenTV Sky UK"), MM_EPG_ONLY_OPENTV_SKY_UK }, - { N_("Only OpenTV Sky Italia"), MM_EPG_ONLY_OPENTV_SKY_ITALIA }, - { N_("Only OpenTV Sky Ausat"), MM_EPG_ONLY_OPENTV_SKY_AUSAT }, + { N_("Manual selection"), MM_EPG_MANUAL }, }; return strtab2htsmsg(tab, 1, lang); } +static htsmsg_t * +mpegts_mux_epg_module_id_list ( void *o, const char *lang ) +{ + return epggrab_ota_module_id_list(lang); +} + static htsmsg_t * mpegts_mux_ac3_list ( void *o, const char *lang ) { @@ -544,6 +542,16 @@ const idclass_t mpegts_mux_class = .list = mpegts_mux_epg_list, .opts = PO_DOC_NLIST, }, + { + .type = PT_STR, + .id = "epg_module_id", + .name = N_("EPG module id"), + .desc = N_("The EPG grabber to use on the mux. " + "The 'EPG scan' field must be set to 'manual'."), + .off = offsetof(mpegts_mux_t, mm_epg_module_id), + .list = mpegts_mux_epg_module_id_list, + .opts = PO_DOC_NLIST, + }, { .type = PT_STR, .id = "network", @@ -755,6 +763,7 @@ mpegts_mux_free ( mpegts_mux_t *mm ) free(mm->mm_provider_network_name); free(mm->mm_crid_authority); free(mm->mm_charset); + free(mm->mm_epg_module_id); free(mm->mm_nicename); free(mm); }