Updated EIT code to (hopefully) more robust implementation and included the primary service checking.
This commit is contained in:
parent
d9f6fd39e9
commit
d6ca0eb120
1 changed files with 308 additions and 241 deletions
|
@ -38,6 +38,24 @@ typedef struct eit_status
|
|||
int sec;
|
||||
} eit_status_t;
|
||||
|
||||
typedef struct eit_event
|
||||
{
|
||||
char title[256];
|
||||
char summary[256];
|
||||
char desc[2000];
|
||||
|
||||
char *default_charset;
|
||||
|
||||
htsmsg_t *extra;
|
||||
|
||||
epg_genre_list_t *genre;
|
||||
|
||||
uint8_t hd, ws;
|
||||
uint8_t ad, st, ds;
|
||||
uint8_t bw;
|
||||
|
||||
} eit_event_t;
|
||||
|
||||
/* ************************************************************************
|
||||
* Diagnostics
|
||||
* ***********************************************************************/
|
||||
|
@ -61,86 +79,304 @@ static void _eit_dtag_dump ( uint8_t dtag, uint8_t dlen, uint8_t *buf )
|
|||
}
|
||||
|
||||
/* ************************************************************************
|
||||
* Processing
|
||||
* EIT Event descriptors
|
||||
* ***********************************************************************/
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Short Event
|
||||
/*
|
||||
* Short Event - 0x4d
|
||||
*/
|
||||
static int
|
||||
dvb_desc_short_event(uint8_t *ptr, int len,
|
||||
char *title, size_t titlelen,
|
||||
char *desc, size_t desclen,
|
||||
char *dvb_default_charset)
|
||||
static int _eit_desc_short_event
|
||||
( uint8_t *ptr, int len, eit_event_t *ev )
|
||||
{
|
||||
int r;
|
||||
|
||||
if(len < 4)
|
||||
return -1;
|
||||
ptr += 3; len -= 3;
|
||||
if ( len < 5 ) return -1;
|
||||
|
||||
if((r = dvb_get_string_with_len(title, titlelen, ptr, len, dvb_default_charset)) < 0)
|
||||
return -1;
|
||||
ptr += r; len -= r;
|
||||
/* Language (skip) */
|
||||
len -= 3;
|
||||
ptr += 3;
|
||||
|
||||
if((r = dvb_get_string_with_len(desc, desclen, ptr, len, dvb_default_charset)) < 0)
|
||||
/* Title */
|
||||
if ( (r = dvb_get_string_with_len(ev->title, sizeof(ev->title),
|
||||
ptr, len, ev->default_charset)) < 0 )
|
||||
return -1;
|
||||
|
||||
len -= r;
|
||||
ptr += r;
|
||||
if ( len < 1 ) return -1;
|
||||
|
||||
/* Summary */
|
||||
if ( (r = dvb_get_string_with_len(ev->summary, sizeof(ev->summary),
|
||||
ptr, len, ev->default_charset)) < 0 )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* DVB Descriptor; Extended Event
|
||||
/*
|
||||
* Extended Event - 0x4e
|
||||
*/
|
||||
static int
|
||||
dvb_desc_extended_event(uint8_t *ptr, int len,
|
||||
char *desc, size_t desclen,
|
||||
htsmsg_t *extra,
|
||||
char *dvb_default_charset)
|
||||
static int _eit_desc_ext_event
|
||||
( uint8_t *ptr, int len, eit_event_t *ev )
|
||||
{
|
||||
int ilen, nitems = ptr[4];
|
||||
int r, nitem;
|
||||
char ikey[256], ival[256];
|
||||
if (len < 8) return -1;
|
||||
ptr += 5;
|
||||
len -= 5;
|
||||
|
||||
/* key/value items */
|
||||
while (nitems-- > 0) {
|
||||
if (len < 6) return -1;
|
||||
|
||||
/* key */
|
||||
ilen = *ptr;
|
||||
if (ilen+1 > len) return -1;
|
||||
if(dvb_get_string_with_len(ikey, sizeof(ikey),
|
||||
ptr+1, ilen,
|
||||
dvb_default_charset) < 0) return -1;
|
||||
/* Descriptor numbering (skip) */
|
||||
len -= 1;
|
||||
ptr += 1;
|
||||
|
||||
/* Language (skip) */
|
||||
len -= 3;
|
||||
ptr += 3;
|
||||
|
||||
/* Key/Value items */
|
||||
nitem = *ptr;
|
||||
len -= 1;
|
||||
ptr += 1;
|
||||
if (len < (2 * nitem) + 1) return -1;
|
||||
|
||||
while (nitem--) {
|
||||
|
||||
/* Key */
|
||||
if ( (r = dvb_get_string_with_len(ikey, sizeof(ikey),
|
||||
ptr, len, ev->default_charset)) < 0 )
|
||||
return -1;
|
||||
ptr += (ilen + 1);
|
||||
len -= (ilen + 1);
|
||||
|
||||
/* value */
|
||||
ilen = *ptr;
|
||||
if (ilen+1 > len) return -1;
|
||||
if(dvb_get_string_with_len(ival, sizeof(ival),
|
||||
ptr, ilen,
|
||||
dvb_default_charset) < 0) return -1;
|
||||
ptr += (ilen + 1);
|
||||
len -= (ilen + 1);
|
||||
len -= r;
|
||||
ptr += r;
|
||||
|
||||
// TODO: should this extend existing strings?
|
||||
htsmsg_add_str(extra, ikey, ival);
|
||||
/* Value */
|
||||
if ( (r = dvb_get_string_with_len(ival, sizeof(ival),
|
||||
ptr, len, ev->default_charset)) < 0 )
|
||||
return -1;
|
||||
|
||||
len -= r;
|
||||
ptr += r;
|
||||
|
||||
/* Store */
|
||||
// TODO: extend existing?
|
||||
if (*ikey && *ival)
|
||||
htsmsg_add_str(ev->extra, ikey, ival);
|
||||
}
|
||||
|
||||
/* raw text (append) */
|
||||
ilen = *ptr;
|
||||
if (ilen+1 > len) return -1;
|
||||
if(dvb_get_string_with_len(desc + strlen(desc),
|
||||
desclen - strlen(desc),
|
||||
ptr+1, ilen,
|
||||
dvb_default_charset) < 0) return -1;
|
||||
/* Description */
|
||||
if ( dvb_get_string_with_len(ev->desc + strlen(ev->desc),
|
||||
sizeof(ev->desc) - strlen(ev->desc),
|
||||
ptr, len,
|
||||
ev->default_charset) < 0 )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Component Descriptor - 0x50
|
||||
*/
|
||||
|
||||
static int _eit_desc_component
|
||||
( uint8_t *ptr, int len, eit_event_t *ev )
|
||||
{
|
||||
uint8_t c, t;
|
||||
|
||||
if (len < 6) return -1;
|
||||
|
||||
/* Stream Content and Type */
|
||||
c = *ptr & 0x0f;
|
||||
t = ptr[1];
|
||||
|
||||
/* MPEG2 (video) */
|
||||
if (c == 0x1) {
|
||||
if (t > 0x08 && t < 0x11) {
|
||||
ev->hd = 1;
|
||||
if ( t != 0x09 && t != 0x0d )
|
||||
ev->ws = 1;
|
||||
} else if (t == 0x02 || t == 0x03 || t == 0x04 ||
|
||||
t == 0x06 || t == 0x07 || t == 0x08 ) {
|
||||
ev->ws = 1;
|
||||
}
|
||||
|
||||
/* MPEG2 (audio) */
|
||||
} else if (c == 0x2) {
|
||||
|
||||
/* Described */
|
||||
if (t == 0x40 || t == 0x41)
|
||||
ev->ad = 1;
|
||||
|
||||
/* Misc */
|
||||
} else if (c == 0x3) {
|
||||
if (t == 0x1 || (t >= 0x10 && t <= 0x14) || (t >= 0x20 && t <= 0x24))
|
||||
ev->st = 1;
|
||||
else if (t == 0x30 || t == 0x31)
|
||||
ev->ds = 1;
|
||||
|
||||
/* H264 */
|
||||
} else if (c == 0x5) {
|
||||
if (t == 0x0b || t == 0x0c || t == 0x10)
|
||||
ev->hd = ev->ws = 1;
|
||||
else if (t == 0x03 || t == 0x04 || t == 0x07 || t == 0x08)
|
||||
ev->ws = 1;
|
||||
|
||||
/* AAC */
|
||||
} else if ( c == 0x6 ) {
|
||||
|
||||
/* Described */
|
||||
if (t == 0x40 || t == 0x44)
|
||||
ev->ad = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Content Descriptor - 0x54
|
||||
*/
|
||||
|
||||
static int _eit_desc_content
|
||||
( uint8_t *ptr, int len, eit_event_t *ev )
|
||||
{
|
||||
while (len > 1) {
|
||||
if (*ptr == 0xb1)
|
||||
ev->bw = 1;
|
||||
else if (*ptr < 0xb0) {
|
||||
if (!ev->genre) ev->genre = calloc(1, sizeof(epg_genre_list_t));
|
||||
epg_genre_list_add_by_eit(ev->genre, *ptr);
|
||||
}
|
||||
len -= 2;
|
||||
ptr += 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************************************************************************
|
||||
* EIT Event
|
||||
* ***********************************************************************/
|
||||
|
||||
static int _eit_process_event
|
||||
( epggrab_module_t *mod, int tableid,
|
||||
service_t *svc, uint8_t *ptr, int len,
|
||||
int *resched, int *save )
|
||||
{
|
||||
int save2 = 0;
|
||||
int ret, dllen;
|
||||
time_t start, stop;
|
||||
uint16_t eid;
|
||||
uint8_t dtag, dlen;
|
||||
epg_broadcast_t *ebc;
|
||||
epg_episode_t *ee;
|
||||
eit_event_t ev;
|
||||
|
||||
if ( len < 12 ) return -1;
|
||||
|
||||
/* Core fields */
|
||||
eid = ptr[0] << 8 | ptr[1];
|
||||
start = dvb_convert_date(&ptr[2]);
|
||||
stop = start + bcdtoint(ptr[7] & 0xff) * 3600 +
|
||||
bcdtoint(ptr[8] & 0xff) * 60 +
|
||||
bcdtoint(ptr[9] & 0xff);
|
||||
dllen = ((ptr[10] & 0x0f) << 8) | ptr[11];
|
||||
|
||||
len -= 12;
|
||||
ptr += 12;
|
||||
if ( len < dllen ) return -1;
|
||||
ret = 12 + dllen;
|
||||
|
||||
/* Find broadcast */
|
||||
ebc = epg_broadcast_find_by_time(svc->s_ch, start, stop, eid, 1, &save2);
|
||||
if (!ebc) return dllen + 12;
|
||||
tvhlog(LOG_DEBUG, "eit", "process eid %d event %p %"PRIu64" on %s",
|
||||
eid, ebc, ebc->id, svc->s_ch->ch_name);
|
||||
|
||||
/* Mark re-schedule detect (only now/next) */
|
||||
if (save2 && tableid < 0x50) *resched = 1;
|
||||
*save |= save2;
|
||||
|
||||
/* Process tags */
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.default_charset = svc->s_dvb_default_charset;
|
||||
while (dllen > 2) {
|
||||
int r;
|
||||
dtag = ptr[0];
|
||||
dlen = ptr[1];
|
||||
|
||||
dllen -= 2;
|
||||
ptr += 2;
|
||||
if (dllen < dlen) return ret;
|
||||
|
||||
switch (dtag) {
|
||||
case DVB_DESC_SHORT_EVENT:
|
||||
r = _eit_desc_short_event(ptr, dlen, &ev);
|
||||
break;
|
||||
case DVB_DESC_EXT_EVENT:
|
||||
r = _eit_desc_ext_event(ptr, dlen, &ev);
|
||||
break;
|
||||
case DVB_DESC_CONTENT:
|
||||
r = _eit_desc_content(ptr, dlen, &ev);
|
||||
break;
|
||||
case DVB_DESC_COMPONENT:
|
||||
r = _eit_desc_component(ptr, dlen, &ev);
|
||||
break;
|
||||
#if TODO_AGE_RATING
|
||||
case DVB_DESC_PARENTAL_RAT:
|
||||
r = _eit_desc_parental(ptr, dlen, &ev);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
r = 0;
|
||||
_eit_dtag_dump(dtag, dlen, ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
if (r < 0) return ret;
|
||||
dllen -= dlen;
|
||||
ptr += dlen;
|
||||
}
|
||||
|
||||
/* Metadata */
|
||||
*save |= epg_broadcast_set_is_hd(ebc, ev.hd, mod);
|
||||
*save |= epg_broadcast_set_is_widescreen(ebc, ev.ws, mod);
|
||||
*save |= epg_broadcast_set_is_audio_desc(ebc, ev.ad, mod);
|
||||
*save |= epg_broadcast_set_is_subtitled(ebc, ev.st, mod);
|
||||
*save |= epg_broadcast_set_is_deafsigned(ebc, ev.ds, mod);
|
||||
|
||||
/* Create episode */
|
||||
ee = ebc->episode;
|
||||
if ( !ee ) {
|
||||
char *uri;
|
||||
uri = epg_hash(ev.title, ev.summary, ev.desc);
|
||||
if (uri) {
|
||||
if ((ee = epg_episode_find_by_uri(uri, 1, save)))
|
||||
*save |= epg_broadcast_set_episode(ebc, ee, mod);
|
||||
free(uri);
|
||||
}
|
||||
}
|
||||
|
||||
/* Episode data */
|
||||
if (ee) {
|
||||
*save |= epg_episode_set_is_bw(ee, ev.bw, mod);
|
||||
if ( *ev.title )
|
||||
*save |= epg_episode_set_title(ee, ev.title, mod);
|
||||
if ( *ev.summary )
|
||||
*save |= epg_episode_set_summary(ee, ev.summary, mod);
|
||||
if ( *ev.desc )
|
||||
*save |= epg_episode_set_description(ee, ev.desc, mod);
|
||||
if ( ev.genre )
|
||||
*save |= epg_episode_set_genre(ee, ev.genre, mod);
|
||||
#if TODO_ADD_EXTRA
|
||||
if ( extra )
|
||||
*save |= epg_episode_set_extra(ee, extra, mod);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Tidy up */
|
||||
if (ev.extra) free(ev.extra);
|
||||
if (ev.genre) epg_genre_list_destroy(ev.genre);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _eit_callback
|
||||
( th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len,
|
||||
uint8_t tableid, void *opaque )
|
||||
|
@ -149,19 +385,9 @@ static int _eit_callback
|
|||
epggrab_ota_mux_t *ota;
|
||||
th_dvb_adapter_t *tda;
|
||||
service_t *svc;
|
||||
channel_t *ch;
|
||||
epg_broadcast_t *ebc;
|
||||
epg_episode_t *ee;
|
||||
epg_genre_list_t *egl = NULL;
|
||||
eit_status_t *sta;
|
||||
int resched = 0, save = 0, save2 = 0, dllen, dtag, dlen;
|
||||
uint16_t tsid, sid, eid;
|
||||
uint8_t bw, hd, ws, ad, ds, st;
|
||||
time_t start, stop;
|
||||
char title[256];
|
||||
char summary[256];
|
||||
char desc[5000];
|
||||
htsmsg_t *extra;
|
||||
int resched = 0, save = 0;
|
||||
uint16_t tsid, sid;
|
||||
|
||||
/* Invalid */
|
||||
if(tableid < 0x4e || tableid > 0x6f || len < 11)
|
||||
|
@ -169,7 +395,7 @@ static int _eit_callback
|
|||
|
||||
/* Get OTA */
|
||||
ota = epggrab_ota_find((epggrab_module_ota_t*)mod, tdmi);
|
||||
if (!ota || !ota->status) return 0;
|
||||
if (!ota || !ota->status) return -1;
|
||||
sta = ota->status;
|
||||
|
||||
/* Already complete */
|
||||
|
@ -187,14 +413,16 @@ static int _eit_callback
|
|||
sta->sec = ptr[3];
|
||||
|
||||
/* Complete */
|
||||
} else if (sta->tid == tableid && sta->sec == ptr[3] && sta->tsid == tsid && sta->sid == sid) {
|
||||
} else if (sta->tid == tableid &&
|
||||
sta->sec == ptr[3] &&
|
||||
sta->tsid == tsid &&
|
||||
sta->sid == sid) {
|
||||
epggrab_ota_complete(ota);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Don't process */
|
||||
if((ptr[2] & 1) == 0)
|
||||
return 0;
|
||||
if((ptr[2] & 1) == 0) return 0;
|
||||
|
||||
/* Get transport stream */
|
||||
// Note: tableid=0x4f,0x60-0x6f is other TS
|
||||
|
@ -209,11 +437,14 @@ static int _eit_callback
|
|||
|
||||
/* Get service */
|
||||
svc = dvb_transport_find(tdmi, sid, 0, NULL);
|
||||
if (!svc || !svc->s_enabled || !(ch = svc->s_ch)) return 0;
|
||||
if (!svc || !svc->s_enabled || !svc->s_ch) return 0;
|
||||
|
||||
/* Ignore (disabled) */
|
||||
if (!svc->s_dvb_eit_enable) return 0;
|
||||
|
||||
/* Ignore (not primary EPG service) */
|
||||
if (!service_is_primary_epg(svc)) return 0;
|
||||
|
||||
/* Register as interesting */
|
||||
if (tableid < 0x50)
|
||||
epggrab_ota_register(ota, 20, 300); // 20s grab, 5min interval
|
||||
|
@ -232,177 +463,13 @@ static int _eit_callback
|
|||
/* Process events */
|
||||
len -= 11;
|
||||
ptr += 11;
|
||||
while(len >= 12) {
|
||||
eid = ptr[0] << 8 | ptr[1];
|
||||
start = dvb_convert_date(&ptr[2]);
|
||||
stop = start + bcdtoint(ptr[7] & 0xff) * 3600 +
|
||||
bcdtoint(ptr[8] & 0xff) * 60 +
|
||||
bcdtoint(ptr[9] & 0xff);
|
||||
dllen = ((ptr[10] & 0x0f) << 8) | ptr[11];
|
||||
|
||||
len -= 12;
|
||||
ptr += 12;
|
||||
if(dllen > len) break;
|
||||
|
||||
/* Get the event */
|
||||
ebc = epg_broadcast_find_by_time(ch, start, stop, eid, 1, &save2);
|
||||
if (!ebc) {
|
||||
len -= dllen;
|
||||
ptr += dllen;
|
||||
continue;
|
||||
}
|
||||
tvhlog(LOG_DEBUG, "eit", "process tid 0x%02x eid %d event %p %"PRIu64" on %s", tableid, eid, ebc, ebc->id, ch->ch_name);
|
||||
|
||||
/* Mark re-schedule detect (only now/next) */
|
||||
if (save2 && tableid < 0x50) resched = 1;
|
||||
|
||||
/* Process tags */
|
||||
*title = *summary = *desc = 0;
|
||||
extra = NULL;
|
||||
hd = ws = bw = ad = st = ds = 0;
|
||||
while(dllen > 0) {
|
||||
dtag = ptr[0];
|
||||
dlen = ptr[1];
|
||||
|
||||
len -= 2; ptr += 2; dllen -= 2;
|
||||
|
||||
if(dlen > len) break;
|
||||
|
||||
switch(dtag) {
|
||||
|
||||
/* Short descriptor (title/summary) */
|
||||
case DVB_DESC_SHORT_EVENT:
|
||||
dvb_desc_short_event(ptr, dlen,
|
||||
title, sizeof(title),
|
||||
summary, sizeof(summary),
|
||||
svc->s_dvb_default_charset);
|
||||
break;
|
||||
|
||||
/* Extended (description) */
|
||||
case DVB_DESC_EXT_EVENT:
|
||||
if (!extra) extra = htsmsg_create_map();
|
||||
dvb_desc_extended_event(ptr, dlen,
|
||||
desc, sizeof(desc),
|
||||
extra,
|
||||
svc->s_dvb_default_charset);
|
||||
break;
|
||||
|
||||
/* Content type */
|
||||
case DVB_DESC_CONTENT:
|
||||
while (dlen > 0) {
|
||||
ptr += 2;
|
||||
dlen -= 2;
|
||||
if ( *ptr == 0xb1 )
|
||||
bw = 1;
|
||||
else if ( *ptr < 0xb0 ) {
|
||||
if (!egl) egl = calloc(1, sizeof(epg_genre_list_t));
|
||||
epg_genre_list_add_by_eit(egl, *ptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Component descriptor */
|
||||
case DVB_DESC_COMPONENT: {
|
||||
uint8_t c = *ptr & 0x0f;
|
||||
uint8_t t = ptr[1];
|
||||
|
||||
/* MPEG2 (video) */
|
||||
if (c == 0x1) {
|
||||
if (t > 0x08 && t < 0x11) {
|
||||
hd = 1;
|
||||
if ( t != 0x09 && t != 0x0d )
|
||||
ws = 1;
|
||||
} else if (t == 0x02 || t == 0x03 || t == 0x04 ||
|
||||
t == 0x06 || t == 0x07 || t == 0x08 ) {
|
||||
ws = 1;
|
||||
}
|
||||
|
||||
/* MPEG2 (audio) */
|
||||
} else if (c == 0x2) {
|
||||
|
||||
/* Described */
|
||||
if (t == 0x40 || t == 0x41)
|
||||
ad = 1;
|
||||
|
||||
/* Subtitles */
|
||||
} else if (c == 0x3) {
|
||||
st = 1;
|
||||
|
||||
/* H264 */
|
||||
} else if (c == 0x5) {
|
||||
if (t == 0x0b || t == 0x0c || t == 0x10)
|
||||
hd = ws = 1;
|
||||
else if (t == 0x03 || t == 0x04 || t == 0x07 || t == 0x08)
|
||||
ws = 1;
|
||||
|
||||
/* AAC */
|
||||
} else if ( c == 0x6 ) {
|
||||
|
||||
/* Described */
|
||||
if (t == 0x40 || t == 0x44)
|
||||
ad = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Parental Rating */
|
||||
#if TODO_AGE_RATING
|
||||
case DVB_DESC_PARENTAL_RAT:
|
||||
if (*ptr > 0 && *ptr < 15)
|
||||
minage = *ptr + 3;
|
||||
#endif
|
||||
|
||||
/* Ignore */
|
||||
default:
|
||||
_eit_dtag_dump(dtag, dlen, ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
len -= dlen; ptr += dlen; dllen -= dlen;
|
||||
}
|
||||
|
||||
/* Metadata */
|
||||
if ( save2 ) {
|
||||
save |= epg_broadcast_set_is_hd(ebc, hd, mod);
|
||||
save |= epg_broadcast_set_is_widescreen(ebc, ws, mod);
|
||||
save |= epg_broadcast_set_is_audio_desc(ebc, ad, mod);
|
||||
save |= epg_broadcast_set_is_subtitled(ebc, st, mod);
|
||||
save |= epg_broadcast_set_is_deafsigned(ebc, ds, mod);
|
||||
}
|
||||
|
||||
/* Create episode */
|
||||
ee = ebc->episode;
|
||||
if ( !ee || save2 ) {
|
||||
char *uri;
|
||||
uri = epg_hash(title, summary, desc);
|
||||
if (uri) {
|
||||
if ((ee = epg_episode_find_by_uri(uri, 1, &save2)))
|
||||
save |= epg_broadcast_set_episode(ebc, ee, mod);
|
||||
free(uri);
|
||||
}
|
||||
}
|
||||
save |= save2;
|
||||
|
||||
/* Episode data */
|
||||
if (ee) {
|
||||
save |= epg_episode_set_is_bw(ee, bw, mod);
|
||||
if ( *title )
|
||||
save |= epg_episode_set_title(ee, title, mod);
|
||||
if ( *summary )
|
||||
save |= epg_episode_set_summary(ee, summary, mod);
|
||||
if ( *desc )
|
||||
save |= epg_episode_set_description(ee, desc, mod);
|
||||
if ( egl )
|
||||
save |= epg_episode_set_genre(ee, egl, mod);
|
||||
#if TODO_ADD_EXTRA
|
||||
if ( extra )
|
||||
save |= epg_episode_set_extra(ee, extra, mod);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Tidy up */
|
||||
if (extra) free(extra);
|
||||
if (egl) epg_genre_list_destroy(egl);
|
||||
while (len) {
|
||||
int r;
|
||||
if ((r = _eit_process_event(mod, tableid, svc, ptr, len,
|
||||
&resched, &save)) < 0)
|
||||
break;
|
||||
len -= r;
|
||||
ptr += r;
|
||||
}
|
||||
|
||||
/* Update EPG */
|
||||
|
|
Loading…
Add table
Reference in a new issue