From: Jaroslav Kysela Date: Fri, 2 Feb 2018 20:07:43 +0000 (+0100) Subject: eit: rewrite special eit grabbers activation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6dcdd5dfa33e241ddc5e2a0821cf043417674152;p=thirdparty%2Ftvheadend.git eit: rewrite special eit grabbers activation --- diff --git a/src/epggrab.h b/src/epggrab.h index 30250fc39..5967c435a 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -267,6 +267,7 @@ struct epggrab_ota_map uint8_t om_forced; uint64_t om_tune_count; RB_HEAD(,epggrab_ota_svc_link) om_svcs; ///< Muxes we carry data for + void *om_opaque; }; /* @@ -381,6 +382,7 @@ void epggrab_channel_mod ( struct channel *ch ); * OTA kick */ void epggrab_ota_queue_mux( struct mpegts_mux *mm ); +epggrab_ota_mux_t *epggrab_ota_find_mux ( struct mpegts_mux *mm ); #endif /* __EPGGRAB_H__ */ diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index 2ac39d453..b5871115e 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -35,12 +35,22 @@ typedef struct eit_private { + int id; uint16_t pid; int conv; int spec; } eit_private_t; -#define EIT_CONV_HUFFMAN 1 +#define EIT_ID_STANDARD 0 +#define EIT_ID_UK_FREESAT 1 +#define EIT_ID_UK_FREEVIEW 2 +#define EIT_ID_NZ_FREEVIEW1 3 +#define EIT_ID_NZ_FREEVIEW2 4 +#define EIT_ID_BALTIC 5 +#define EIT_ID_BULSAT 6 +#define EIT_ID_UK_CABLE_VIRGIN 7 + +#define EIT_CONV_HUFFMAN 1 #define EIT_SPEC_UK_FREESAT 1 #define EIT_SPEC_NZ_FREEVIEW 2 @@ -930,7 +940,7 @@ _eit_callback mm = mt->mt_mux; map = mt->mt_opaque; mod = (epggrab_module_t *)map->om_module; - spec = atomic_get(&((eit_private_t *)((epggrab_module_ota_t *)mod)->opaque)->spec); + spec = ((eit_private_t *)((epggrab_module_ota_t *)mod)->opaque)->spec; /* Statistics */ ths = mpegts_mux_find_subscription_by_name(mm, "epggrab"); @@ -957,12 +967,6 @@ _eit_callback tvhtrace(LS_TBL_EIT, "%s: sid %i tsid %04x onid %04x seg %02x", mt->mt_name, sid, tsid, onid, seg); - /* Local EIT contents - give them another priority to override main events */ - if (spec == EIT_SPEC_NZ_FREEVIEW && - ((tsid > 0x19 && tsid < 0x1d) || - (tsid > 0x1e && tsid < 0x21))) - mod = epggrab_module_find_by_id("nz_freeview"); - /* Register interest */ if (tableid == 0x4e || (tableid >= 0x50 && tableid < 0x60) || spec == EIT_SPEC_UK_FREESAT /* uk_freesat hack */) @@ -1096,54 +1100,11 @@ complete: static int _eit_start ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) { - epggrab_module_ota_t *m = map->om_module, *eit = NULL; - eit_private_t *priv = (eit_private_t *)m->opaque; - int pid, opts = 0, spec; + epggrab_module_ota_t *m = map->om_module; /* Disabled */ if (!m->enabled && !map->om_forced) return -1; - spec = priv->spec; - - /* Do string conversions also for the EIT table */ - /* FIXME: It should be done only for selected muxes or networks */ - if (((eit_private_t *)m->opaque)->conv) { - eit = (epggrab_module_ota_t*)epggrab_module_find_by_id("eit"); - atomic_set(&((eit_private_t *)eit->opaque)->spec, priv->spec); - atomic_set(&((eit_private_t *)eit->opaque)->conv, priv->conv); - } - - if (spec == EIT_SPEC_NZ_FREEVIEW) { - if (eit == NULL) - eit = (epggrab_module_ota_t*)epggrab_module_find_by_id("eit"); - if (eit->enabled) - map->om_complete = 1; - } - - pid = priv->pid; - - /* Freeview UK/NZ (switch to EIT, ignore if explicitly enabled) */ - /* Note: do this as PID is the same */ - if (pid == 0 && strcmp(m->id, "eit")) { - if (eit == NULL) - eit = (epggrab_module_ota_t*)epggrab_module_find_by_id("eit"); - if (eit->enabled) return -1; - } - - /* Freesat (3002/3003) */ - if (pid == 3003 && !strcmp("uk_freesat", m->id)) - mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL, - "bat", LS_TBL_BASE, MT_CRC, 3002, MPS_WEIGHT_EIT); - - /* Standard (0x12) */ - if (pid == 0) { - pid = DVB_EIT_PID; - opts = MT_RECORD; - } - - mpegts_table_add(dm, 0, 0, _eit_callback, map, m->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", m->id); return 0; } @@ -1206,6 +1167,88 @@ static int _eit_tune return r; } +#define PRIV_FSAT (('F' << 24) | ('S' << 16) | ('A' << 8) | 'T') + +static epggrab_ota_map_t *eit_find_epggrab_map(epggrab_ota_mux_t *om, int id) +{ + epggrab_ota_map_t *map; + + LIST_FOREACH(map, &om->om_modules, om_link) { + if (((eit_private_t *)(map->om_module)->opaque)->id == id) + return map; + } + return NULL; +} + +void eit_nit_callback(mpegts_table_t *mt, uint16_t nbid, const char *name, uint32_t nitpriv) +{ + mpegts_mux_t *dm = mt->mt_mux; + epggrab_ota_mux_t *om = epggrab_ota_find_mux(dm); + epggrab_ota_map_t *map; + epggrab_module_ota_t *m = NULL; + eit_private_t *priv = NULL; + int id = EIT_ID_STANDARD, pid, opts = 0; + + tvhtrace(LS_TBL_EIT, "NIT - tsid %04X (%d) onid %04X (%d) nbid %04X (%d) network name '%s' private %08X", + dm->mm_tsid, dm->mm_tsid, dm->mm_onid, dm->mm_onid, nbid, nbid, name, nitpriv); + + if (nitpriv == PRIV_FSAT && strcmp(name, "Freesat") == 0) + id = EIT_ID_UK_FREESAT; + else if ((strcmp(name, "Sirius") == 0 && nbid == 0x55) || + (strcmp(name, "Viasat") == 0 && nbid == 0x56)) + id = EIT_ID_BALTIC; + else if (strcmp(name, "Freeview ") == 0 && dm->mm_onid == 0x222a && + nbid >= 0x3401 && nbid < 0x3500) { + id = EIT_ID_NZ_FREEVIEW1; + if ((dm->mm_tsid > 0x19 && dm->mm_tsid < 0x1d) || + (dm->mm_tsid > 0x1e && dm->mm_tsid < 0x21)) + id = EIT_ID_NZ_FREEVIEW2; + } + + while (1) { + map = eit_find_epggrab_map(om, id); + if (map == NULL) + return; + + m = map->om_module; + if (!m->enabled && !map->om_forced) { + if (id != EIT_ID_STANDARD) { + if (id == EIT_ID_NZ_FREEVIEW2) + id = EIT_ID_NZ_FREEVIEW1; + else + id = EIT_ID_STANDARD; + continue; + } + return; + } + } + + tvhtrace(m->subsys, "NIT - detected module '%s'", m->id); + priv = (eit_private_t *)m->opaque; + pid = priv->pid; + + map->om_opaque = NULL; + switch (id) { + case EIT_ID_UK_FREESAT: + mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL, + "fsat-bat", LS_TBL_BASE, MT_CRC, 3002, MPS_WEIGHT_EIT); + break; + default: + break; + } + + /* Standard (0x12) */ + if (pid == 0) { + pid = DVB_EIT_PID; + opts = MT_RECORD; + } + + 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", m->id); +} + static void _eit_scrape_clear(eit_module_t *mod) { eit_pattern_free_list(&mod->p_snum); @@ -1346,8 +1389,9 @@ static eit_module_t *eit_module_ota_create return mod; } -#define EIT_OPS(name, _pid, _conv, _spec) \ +#define EIT_OPS(name, _id, _pid, _conv, _spec) \ static eit_private_t opaque_##name = { \ + .id = (_id), \ .pid = (_pid), \ .conv = (_conv), \ .spec = (_spec), \ @@ -1366,18 +1410,20 @@ static eit_module_t *eit_module_ota_create void eit_init ( void ) { - EIT_OPS(ops, 0, 0, 0); - EIT_OPS(ops_uk_freesat, 3003, EIT_CONV_HUFFMAN, EIT_SPEC_UK_FREESAT); - EIT_OPS(ops_uk_freeview, 0, EIT_CONV_HUFFMAN, 0); - EIT_OPS(ops_nz_freeview, 0, EIT_CONV_HUFFMAN, EIT_SPEC_NZ_FREEVIEW); - EIT_OPS(ops_baltic, 0x39, 0, 0); - EIT_OPS(ops_bulsat, 0x12b, 0, 0); - EIT_OPS(ops_uk_cable_virgin, 0x2bc, 0, EIT_SPEC_UK_CABLE_VIRGIN); + EIT_OPS(ops, EIT_ID_STANDARD, 0, 0, 0); + EIT_OPS(ops_uk_freesat, EIT_ID_UK_FREESAT, 3003, EIT_CONV_HUFFMAN, EIT_SPEC_UK_FREESAT); + EIT_OPS(ops_uk_freeview, EIT_ID_UK_FREEVIEW, 0, EIT_CONV_HUFFMAN, 0); + EIT_OPS(ops_nz_freeview1, EIT_ID_NZ_FREEVIEW1, 0, EIT_CONV_HUFFMAN, EIT_SPEC_NZ_FREEVIEW); + EIT_OPS(ops_nz_freeview2, EIT_ID_NZ_FREEVIEW2, 0, EIT_CONV_HUFFMAN, EIT_SPEC_NZ_FREEVIEW); + EIT_OPS(ops_baltic, EIT_ID_BALTIC, 0x39, 0, 0); + EIT_OPS(ops_bulsat, EIT_ID_BULSAT, 0x12b, 0, 0); + EIT_OPS(ops_uk_cable_virgin, EIT_ID_UK_CABLE_VIRGIN, 0x2bc, 0, EIT_SPEC_UK_CABLE_VIRGIN); EIT_CREATE("eit", "EIT: DVB Grabber", 1, &ops); EIT_CREATE("uk_freesat", "UK: Freesat", 5, &ops_uk_freesat); EIT_CREATE("uk_freeview", "UK: Freeview", 5, &ops_uk_freeview); - EIT_CREATE("nz_freeview", "New Zealand: Freeview", 5, &ops_nz_freeview); + EIT_CREATE("nz_freeview1", "New Zealand: Freeview Base", 1, &ops_nz_freeview1); + EIT_CREATE("nz_freeview2", "New Zealand: Freeview Local", 5, &ops_nz_freeview2); EIT_CREATE("viasat_baltic", "VIASAT: Baltic", 5, &ops_baltic); EIT_CREATE("Bulsatcom_39E", "Bulsatcom: Bula 39E", 5, &ops_bulsat); EIT_CREATE("uk_cable_virgin", "UK: Cable Virgin", 5, &ops_uk_cable_virgin); diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 99d338265..f9f588a81 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -125,6 +125,14 @@ epggrab_ota_queue_one( epggrab_ota_mux_t *om ) return 1; } +epggrab_ota_mux_t *epggrab_ota_find_mux ( mpegts_mux_t *mm ) +{ + epggrab_ota_mux_t *om, tmp; + tmp.om_mux_uuid = mm->mm_id.in_uuid; + om = RB_FIND(&epggrab_ota_all, &tmp, om_global_link, om_id_cmp); + return om; +} + void epggrab_ota_queue_mux( mpegts_mux_t *mm ) { @@ -139,12 +147,9 @@ epggrab_ota_queue_mux( mpegts_mux_t *mm ) epg_flag = mm->mm_is_epg(mm); if (epg_flag < 0 || epg_flag == MM_EPG_DISABLE) return; - RB_FOREACH(om, &epggrab_ota_all, om_global_link) - if (!uuid_cmp(&om->om_mux_uuid, &mm->mm_id.in_uuid)) { - if (epggrab_ota_queue_one(om)) - epggrab_ota_kick(4); - break; - } + om = epggrab_ota_find_mux(mm); + if (om && epggrab_ota_queue_one(om)) + epggrab_ota_kick(4); } static void diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 3d38e5cdb..76d81fe77 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -1192,6 +1192,11 @@ LIST_HEAD(,mpegts_listener) mpegts_listeners; if (ml->op) ml->op(t, ml->ml_opaque, arg1);\ } (void)0 +/* + * misc + */ +void eit_nit_callback(mpegts_table_t *mt, uint16_t nbid, const char *name, uint32_t priv); + #endif /* __TVH_MPEGTS_H__ */ /****************************************************************************** diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index e3a5ff315..5fe624275 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -172,6 +172,7 @@ struct lang_str; #define DVB_DESC_BSKYB_NVOD 0xC0 +#define DVB_DESC_FREESAT_NIT 0xD2 #define DVB_DESC_FREESAT_LCN 0xD3 #define DVB_DESC_FREESAT_REGIONS 0xD4 diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 7367990ff..85b5bf6f6 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -1531,14 +1531,14 @@ dvb_nit_callback // TODO: implement this? break; case DVB_DESC_PRIVATE_DATA: - if (tableid == 0x4A && dlen == 4) { + if (dlen == 4) { priv = extract_4byte(dptr); tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv); } break; - case DVB_DESC_FREESAT_REGIONS: + case DVB_DESC_FREESAT_REGIONS: #if ENABLE_MPEGTS_DVB - if (priv == PRIV_FSAT) + if (tableid == 0x4A && priv == PRIV_FSAT) dvb_freesat_regions(bi, mt, dptr, dlen); #endif break; @@ -1612,6 +1612,10 @@ dvb_nit_callback /* End */ if (retry) return 0; + + if (tableid == 0x40) + eit_nit_callback(mt, nbid, name, priv); + return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); dvberr: