Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
epggrab: add framework for an ATSC EPG grabber
  • Loading branch information
laurimyllari authored and perexg committed Oct 22, 2015
1 parent 628a114 commit a29b4e9
Show file tree
Hide file tree
Showing 7 changed files with 222 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions src/config.c
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions src/epggrab.c
Expand Up @@ -360,6 +360,7 @@ void epggrab_init ( void )
/* Initialise modules */
#if ENABLE_MPEGTS
eit_init();
psip_init();
opentv_init();
#endif
pyepg_init();
Expand Down
212 changes: 212 additions & 0 deletions 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 <http://www.gnu.org/licenses/>.
*/

#include <string.h>

#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, &sect, &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 )
{
}
1 change: 1 addition & 0 deletions src/epggrab/otamux.c
Expand Up @@ -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",
Expand Down
5 changes: 5 additions & 0 deletions src/epggrab/private.h
Expand Up @@ -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__ */
1 change: 1 addition & 0 deletions src/input/mpegts.h
Expand Up @@ -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,
Expand Down

0 comments on commit a29b4e9

Please sign in to comment.