More hacking around the opentv code will now build a full EPG with title and summary. The other info is currently not included and things need a good tidy up.

This commit is contained in:
Adam Sutton 2012-06-18 01:01:22 +01:00
parent 28030b9159
commit f456446dff
3 changed files with 55 additions and 53 deletions

View file

@ -1318,6 +1318,15 @@ epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, channel_t *ch )
return (epg_broadcast_t*)_epg_object_find_by_id(id);
}
epg_broadcast_t *epg_broadcast_find_by_eid ( int eid, channel_t *ch )
{
epg_broadcast_t *e;
RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) {
if (e->dvb_eid == eid) return e;
}
return NULL;
}
int epg_broadcast_set_episode
( epg_broadcast_t *broadcast, epg_episode_t *episode )
{

View file

@ -283,6 +283,7 @@ struct epg_broadcast
{
epg_object_t; ///< Parent object
int dvb_eid; ///< DVB Event ID
time_t start; ///< Start time
time_t stop; ///< End time
@ -312,6 +313,7 @@ struct epg_broadcast
epg_broadcast_t *epg_broadcast_find_by_time
( struct channel *ch, time_t start, time_t stop, int create, int *save );
epg_broadcast_t *epg_broadcast_find_by_id ( uint64_t id, struct channel *ch );
epg_broadcast_t *epg_broadcast_find_by_eid ( int eid, struct channel *ch );
/* Mutators */
int epg_broadcast_set_episode ( epg_broadcast_t *b, epg_episode_t *e )

View file

@ -168,21 +168,28 @@ static int _opentv_prov_load ( const char *key, htsmsg_t *m )
* Parser
* ***********************************************************************/
static epggrab_channel_t *_opentv_find_channel ( int cid, int create, int *save )
{
char chid[16];
sprintf(chid, "opentv-%d", cid);
return epggrab_module_channel_find(&_opentv_mod, chid, create, save);
}
static char *_parse_string ( opentv_prov_t *prov, uint8_t *buf, int len )
{
return huffman_decode(prov->dict->codes, buf, len, 0x20);
}
static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t eid )
static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, epg_broadcast_t *ebc, int *save )
{
epg_episode_t *ee;
char *str;
uint8_t rtag = buf[0];
uint8_t rlen = buf[1];
printf("_parse_record(): rtag=%02X, rlen=%d\n", rtag, rlen);
if (rlen+2 > len) return rlen+2;
switch (rtag) {
case 0xb5:
#if 0
case 0xb5:
str = _parse_string(buf+2, rlen);
if (str) {
printf("EID: %d, TITLE: %s\n", eid, str);
@ -193,16 +200,17 @@ static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t
case 0xb9:
str = _parse_string(prov, buf+2, rlen);
if (str) {
printf("EID: %d, SUMMARY: %s\n", eid, str);
char *uri = md5sum(str);
ee = epg_episode_find_by_uri(uri, 1, save);
if (ee) *save |= epg_episode_set_summary(ee, str);
if (ee) *save |= epg_broadcast_set_episode(ebc, ee);
free(str);
free(uri);
}
break;
case 0xbb:
str = _parse_string(prov, buf+2, rlen);
if (str) {
printf("EID: %d, DESCRIPTION: %s\n", eid, str);
free(str);
}
//str = _parse_string(prov, buf+2, rlen);
// TODO
break;
case 0xc1:
//_parse_series_link(buf+2, rlen);
@ -213,15 +221,16 @@ static int _parse_record ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t
return rlen + 2;
}
static int _parse_summary ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t cid )
static int _parse_summary ( opentv_prov_t *prov, uint8_t *buf, int len, channel_t *ch, int *save )
{
epg_broadcast_t *ebc;
uint16_t eid = ((uint16_t)buf[0] << 8) | buf[1];
int slen = ((int)buf[2] & 0xf << 8) | buf[3];
int i = 4;
printf("_parse_summary(): cid=%d, eid=%d, slen=%d\n", cid, eid, slen);
if (!(ebc = epg_broadcast_find_by_eid(eid, ch))) return slen+4;
if (slen+4 > len) return slen+4;
while (i < slen+4) {
i += _parse_record(prov, buf+i, len-i, eid);
i += _parse_record(prov, buf+i, len-i, ebc, save);
}
return slen+4;
}
@ -229,21 +238,20 @@ static int _parse_summary ( opentv_prov_t *prov, uint8_t *buf, int len, uint16_t
static int _opentv_summary_callback
( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p )
{
// TODO: currently this will only get summary tables!
int save = 0;
int i = 0;
uint16_t cid, mjd;
//if (len < 20) return 0;
uint16_t cid;//, mjd;
epggrab_channel_t *ec;
if (len < 20) return 0;
cid = ((uint16_t)buf[0] << 8) | buf[1];
mjd = ((uint16_t)buf[5] << 8) | buf[6];
printf("summary callback(): len=%d, cid=%d, mjd=%d\n", len, cid, mjd);
for ( i = 0; i < 100; i++ ) {
printf("0x%02x ", buf[i]);
}
printf("\n");
if (!(ec = _opentv_find_channel(cid, 0, NULL))) return 0;
if (!ec->channel) return 0;
//mjd = ((uint16_t)buf[5] << 8) | buf[6];
i = 7;
while (i < len) {
i += _parse_summary((opentv_prov_t*)p, buf+i, len-i, cid);
i += _parse_summary((opentv_prov_t*)p, buf+i, len-i, ec->channel, &save);
}
if (save) epg_updated();
return 0;
}
@ -268,20 +276,15 @@ static int _opentv_channel_callback
( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p )
{
static epggrab_channel_t *ec;
int tsid, cid, cnum, bid;
int tsid, cid, cnum;
uint16_t sid;
int i, j, k, tdlen, dlen, dtag, tslen;
char chid[16];
channel_t *ch;
if (tid != 0x4a) return 0;
// TODO: bouqets
bid = ((int)buf[0] << 8) | buf[1];
printf("BID: %d\n", bid);
i = 7 + ((((int)buf[5] & 0xf) << 8) | buf[6]);
tslen = (((int)buf[i] & 0xf) << 8) | buf[i+1];
printf("TSLEN: %d\n", tslen);
// TODO: this isn't quite right (should use tslen)
i += 2;
while (tslen > 0) {
tsid = ((int)buf[i] << 8) | buf[i+1];
@ -296,7 +299,6 @@ static int _opentv_channel_callback
k = j + 2;
j += (dlen + 2);
tdlen -= (dlen + 2);
printf("dtag = 0x%02x, dlen=%d\n", dtag, dlen);
if (dtag == 0xb1) {
k += 2;
dlen -= 2;
@ -308,18 +310,13 @@ static int _opentv_channel_callback
/* Find the channel */
ch = _find_channel(tsid, sid);
if (ch) {
printf("FOUND tsid=%d, sid=%d, cid=%d, num=%d, ch=%s\n",
tsid, sid, cid, cnum, ch->ch_name);
int save = 0;
sprintf(chid, "opentv-%u", cid);
ec = epggrab_module_channel_find(&_opentv_mod, chid, 1, &save);
ec = _opentv_find_channel(cid, 1, &save);
if (save) {
ec->channel = ch; // Note: could use set_sid() but not nec.
epggrab_channel_set_number(ec, cnum);
epggrab_channel_updated(ec);
}
} else {
printf("NOT FOUND tsid=%d, cid=%d, cnum=%d\n", tsid, cid, cnum);
}
k += 9;
dlen -= 9;
@ -334,16 +331,15 @@ static int _opentv_title_callback
( th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len, uint8_t tid, void *p )
{
int save = 0, save2 = 0;
char chid[16];
int cid, mjd, i, eid;
time_t start, stop;
//uint8_t cat;
int l1, l2;
char *title;
epggrab_channel_t *ec;
channel_t *ch;
opentv_prov_t *prov = (opentv_prov_t*)p;
epg_broadcast_t *ebc;
epg_episode_t *ee;
char *uri;
if (len < 20) return 0;
@ -351,40 +347,36 @@ static int _opentv_title_callback
/* Get channel/time */
cid = ((int)buf[0] << 8) | buf[1];
mjd = ((int)buf[5] << 8) | buf[6];
sprintf(chid, "opentv-%d", cid);
epggrab_channel_t *ec = epggrab_module_channel_find(&_opentv_mod, chid, 0, NULL);
if (!ec || !ec->channel) {
printf("NOT FOUND cid=%d\n", cid);
return 0;
}
if (!(ec = _opentv_find_channel(cid, 0, NULL))) return 0;
if (!ec->channel) return 0;
ch = ec->channel;
printf("opentv channel %s, len=%d\n", ch->ch_name, len);
/* Process events */
i = 7;
while ( i < len ) {
eid = ((int)buf[i] << 8) | buf[i+1];
l1 = (((int)buf[i+2] & 0xf) << 8) | buf[i+3];
printf("l1 = %d\n", l1);
if (buf[i+4] != 0xb5) return 0;
i += 4;
l2 = buf[i+1] - 7;
printf("l2 = %d\n", l2);
start = ((mjd - 40587) * 86400) + (((int)buf[i+2] << 9) | (buf[i+3] << 1));
stop = start + (((int)buf[i+4] << 9) | (buf[i+5] << 1));
title = huffman_decode(prov->dict->codes, buf+i+9, l2, 0x20);
uri = md5sum(title);
//cat = buf[i+6];
printf("ch=%s, eid=%d, start=%lu, stop=%lu, title=%s\n",
ch->ch_name, eid, start, stop, title);
i += l1;
save = 0;
ebc = epg_broadcast_find_by_time(ch, start, stop, 1, &save);
save2 |= save;
if (ebc) {
ee = epg_episode_find_by_uri(uri, 1, &save);
save |= epg_episode_set_title(ee, title);
save |= epg_broadcast_set_episode(ebc, ee);
save2 = 1;
// TODO: if EIDs do not match?
if (ebc->dvb_eid != eid) {
ebc->dvb_eid = eid;
save2 = 1;
}
if (ebc->episode) {
save2 |= epg_episode_set_title(ebc->episode, title);
}
}
free(uri);
free(title);
@ -411,7 +403,6 @@ static void _opentv_prov_add_tables
fp->filter.filter[0] = 0x4a;
fp->filter.mask[0] = 0xff;
// TODO: what about 0x46 (service description)
printf("add filter pid=%d\n", *t);
tdt_add(tdmi, fp, _opentv_channel_callback, prov,
"opentv-c", TDT_CRC, *t++, NULL);
}