From a29b4e9ece15bc11281b59196f39d29bc9ddeb87 Mon Sep 17 00:00:00 2001 From: Lauri Myllari Date: Thu, 8 Jan 2015 10:33:44 -0800 Subject: [PATCH] epggrab: add framework for an ATSC EPG grabber --- Makefile | 1 + src/config.c | 1 + src/epggrab.c | 1 + src/epggrab/module/psip.c | 212 ++++++++++++++++++++++++++++++++++++++ src/epggrab/otamux.c | 1 + src/epggrab/private.h | 5 + src/input/mpegts.h | 1 + 7 files changed, 222 insertions(+) create mode 100644 src/epggrab/module/psip.c diff --git a/Makefile b/Makefile index 24ddfb1b3..e73c93f0d 100644 --- a/Makefile +++ b/Makefile @@ -322,6 +322,7 @@ I18N-C += $(SRCS-MPEGTS-DVB) SRCS-MPEGTS-EPG = \ src/epggrab/otamux.c\ src/epggrab/module/eit.c \ + src/epggrab/module/psip.c \ src/epggrab/support/freesat_huffman.c \ src/epggrab/module/opentv.c SRCS-$(CONFIG_MPEGTS) += $(SRCS-MPEGTS-EPG) diff --git a/src/config.c b/src/config.c index af7fe9b4d..6bd9bb5a7 100644 --- a/src/config.c +++ b/src/config.c @@ -596,6 +596,7 @@ config_migrate_v6 ( void ) m = htsmsg_get_map(c, "mod_enabled"); } htsmsg_add_u32(m, "eit", 1); + htsmsg_add_u32(m, "psip", 1); htsmsg_add_u32(m, "uk_freesat", 1); htsmsg_add_u32(m, "uk_freeview", 1); htsmsg_add_u32(m, "viasat_baltic", 1); diff --git a/src/epggrab.c b/src/epggrab.c index 52f9687e1..ed0011d04 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -360,6 +360,7 @@ void epggrab_init ( void ) /* Initialise modules */ #if ENABLE_MPEGTS eit_init(); + psip_init(); opentv_init(); #endif pyepg_init(); diff --git a/src/epggrab/module/psip.c b/src/epggrab/module/psip.c new file mode 100644 index 000000000..8019c8ff4 --- /dev/null +++ b/src/epggrab/module/psip.c @@ -0,0 +1,212 @@ +/* + * Electronic Program Guide - psip grabber + * Copyright (C) 2012 Adam Sutton + * 2014 Lauri Mylläri + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include "tvheadend.h" +#include "channels.h" +#include "service.h" +#include "epg.h" +#include "epggrab.h" +#include "epggrab/private.h" +#include "input.h" +#include "input/mpegts/dvb_charset.h" + +/* ************************************************************************ + * Status handling + * ***********************************************************************/ + +typedef struct psip_event +{ + char uri[257]; + char suri[257]; + + lang_str_t *title; + lang_str_t *summary; + lang_str_t *desc; + + const char *default_charset; + + htsmsg_t *extra; + + epg_genre_list_t *genre; + + uint8_t hd, ws; + uint8_t ad, st, ds; + uint8_t bw; + + uint8_t parental; + +} psip_event_t; + +/* ************************************************************************ + * Diagnostics + * ***********************************************************************/ + + +/* ************************************************************************ + * EIT Event descriptors + * ***********************************************************************/ + + +/* ************************************************************************ + * EIT Event + * ***********************************************************************/ + + +static int +_psip_callback + (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) +{ +#if 0 + int r; + int sect, last, ver, save, resched; + uint8_t seg; + uint16_t onid, tsid, sid; + uint32_t extraid; + mpegts_service_t *svc; + mpegts_mux_t *mm = mt->mt_mux; + epggrab_ota_map_t *map = mt->mt_opaque; + epggrab_module_t *mod = (epggrab_module_t *)map->om_module; + epggrab_ota_mux_t *ota = NULL; + mpegts_table_state_t *st; +#endif + int r; + int sect, last, ver; + int count, i; + uint16_t tsid; + uint32_t extraid; + mpegts_table_state_t *st; + + tvhtrace("psip", "tableid='0x%04x'", tableid); + + /* Validate */ + if (tableid != 0xc7) return -1; + + /* Extra ID */ + tsid = ptr[0] << 8 | ptr[1]; + extraid = tsid; + + /* Begin */ + r = dvb_table_begin(mt, ptr, len, tableid, extraid, 7, + &st, §, &last, &ver); + if (r != 1) return r; + tvhdebug("psip", "tsid %04X (%d), ver %04X", tsid, tsid, ver); + + /* # tables */ + count = ptr[6] << 9 | ptr[7]; + tvhdebug("psip", "table count %d", count); + ptr += 8; + len -= 8; + + for (i = 0; i < count && len >= 11; i++) { + unsigned int type, tablepid, tablever, tablesize; + unsigned int dlen; + dlen = ((ptr[9] & 0x3) << 8) | ptr[10]; + if (dlen + 11 > len) return -1; + + type = ptr[0] << 8 | ptr[1]; + tablepid = (ptr[2] & 0x1f) << 8 | ptr[3]; + tablever = ptr[4] & 0x1f; + tablesize = ptr[5] << 24 | ptr[6] << 16 | ptr[7] << 8 | ptr[8]; + + tvhdebug("psip", "table %d", i); + tvhdebug("psip", " type %04X", type); + tvhdebug("psip", " pid %04X", tablepid); + tvhdebug("psip", " ver %04X", tablever); + tvhdebug("psip", " size %08X", tablesize); + + /* Move on */ +// next: + ptr += dlen + 11; + len -= dlen + 11; + } + + return dvb_table_end(mt, st, sect); +} + +/* ************************************************************************ + * Module Setup + * ***********************************************************************/ + +static int _psip_start + ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) +{ + epggrab_module_ota_t *m = map->om_module; + int pid, opts = 0; + + /* Disabled */ + if (!m->enabled && !map->om_forced) return -1; + + pid = 0x1FFB; + opts = MT_RECORD; + + mpegts_table_add(dm, 0xC7, 0xFF, _psip_callback, map, m->id, MT_CRC | opts, pid); + tvhlog(LOG_DEBUG, m->id, "installed table handlers"); + return 0; +} + +static int _psip_tune + ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm ) +{ + int r = 0; + epggrab_module_ota_t *m = map->om_module; + mpegts_service_t *s; + epggrab_ota_svc_link_t *osl, *nxt; + + lock_assert(&global_lock); + + /* Disabled */ + if (!m->enabled) return 0; + + /* Have gathered enough info to decide */ + if (!om->om_complete) + return 1; + + /* Check if any services are mapped */ + // TODO: using indirect ref's like this is inefficient, should + // consider changeing it? + for (osl = RB_FIRST(&map->om_svcs); osl != NULL; osl = nxt) { + nxt = RB_NEXT(osl, link); + /* rule: if 5 mux scans fail for this service, remove it */ + if (osl->last_tune_count + 5 <= map->om_tune_count || + !(s = mpegts_service_find_by_uuid(osl->uuid))) { + epggrab_ota_service_del(map, om, osl, 1); + } else { + if (LIST_FIRST(&s->s_channels)) + r = 1; + } + } + + return r; +} + +void psip_init ( void ) +{ + static epggrab_ota_module_ops_t ops = { + .start = _psip_start, + .tune = _psip_tune, + }; + + epggrab_module_ota_create(NULL, "psip", "PSIP: ATSC Grabber", 1, &ops, NULL); +} + +void psip_done ( void ) +{ +} diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index b541c0e69..ae813166e 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -465,6 +465,7 @@ epggrab_ota_kick_cb ( void *p ) [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_VIASAT_BALTIC] = "viasat_baltic", diff --git a/src/epggrab/private.h b/src/epggrab/private.h index 660b74b39..b7db9fa88 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -203,4 +203,9 @@ void xmltv_init ( void ); void xmltv_done ( void ); void xmltv_load ( void ); +/* PSIP module */ +void psip_init ( void ); +void psip_done ( void ); +void psip_load ( void ); + #endif /* __EPGGRAB_PRIVATE_H__ */ diff --git a/src/input/mpegts.h b/src/input/mpegts.h index eb0a05743..bc748eb0a 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -357,6 +357,7 @@ enum mpegts_mux_epg_flag MM_EPG_ENABLE, MM_EPG_FORCE, MM_EPG_ONLY_EIT, + MM_EPG_ONLY_PSIP, MM_EPG_ONLY_UK_FREESAT, MM_EPG_ONLY_UK_FREEVIEW, MM_EPG_ONLY_VIASAT_BALTIC, -- 2.47.3