Some further improvements to the EIT scanning. Attempt to ensure we see

the entire carousel before we mark as completed.

Also some tidying up of some of the logging
This commit is contained in:
Adam Sutton 2012-09-25 10:35:56 +01:00
parent 6678303e7c
commit f214bb27e9

View file

@ -31,48 +31,53 @@
* Status handling
* ***********************************************************************/
typedef struct eit_status
typedef struct eit_table_status
{
LIST_ENTRY(eit_status) link;
int tid;
uint16_t tsid;
uint16_t sid;
uint32_t sec[8];
uint8_t ver;
LIST_ENTRY(eit_table_status) link;
int tid;
uint16_t tsid;
uint16_t sid;
uint32_t sec[8];
uint8_t ver;
enum {
EIT_STATUS_START,
EIT_STATUS_PROCESS,
EIT_STATUS_LAST,
EIT_STATUS_DONE
} state;
} eit_status_t;
typedef LIST_HEAD(, eit_status) eit_status_list_t;
} state;
} eit_table_status_t;
static eit_status_t *eit_status_find
( eit_status_list_t *el, int tableid, uint16_t tsid, uint16_t sid,
typedef struct eit_status
{
eit_table_status_t *first;
LIST_HEAD(, eit_table_status) tables;
} eit_status_t;
static eit_table_status_t *eit_status_find
( eit_status_t *status, int tableid, uint16_t tsid, uint16_t sid,
uint8_t sec, uint8_t lst, uint8_t seg, uint8_t ver )
{
int i, sec_index;
uint32_t sec_seen_mask;
eit_status_t *sta, *ret;
eit_table_status_t *sta;
/* Find */
LIST_FOREACH(sta, el, link)
LIST_FOREACH(sta, &status->tables, link)
if (sta->tid == tableid && sta->tsid == tsid && sta->sid == sid)
break;
/* Already complete */
if (sta && sta->state == EIT_STATUS_DONE && sta->ver == ver) return NULL;
if (sta && sta->state == EIT_STATUS_DONE && sta->ver == ver) return sta;
/* Insert new entry */
if (!sta) {
sta = calloc(1, sizeof(eit_status_t));
LIST_INSERT_HEAD(el, sta, link);
sta = calloc(1, sizeof(eit_table_status_t));
LIST_INSERT_HEAD(&status->tables, sta, link);
sta->tid = tableid;
sta->tsid = tsid;
sta->sid = sid;
sta->ver = 255; // Note: force update below
}
ret = sta;
/* Reset */
if (sta->ver != ver) {
@ -115,9 +120,9 @@ static eit_status_t *eit_status_find
if (!(sta->sec[sec_index] & sec_seen_mask)) {
if (sta->state == EIT_STATUS_START) {
sta->state = EIT_STATUS_DONE;
ret = NULL;
goto done;
}
return NULL;
}
/* Update */
@ -125,14 +130,14 @@ static eit_status_t *eit_status_find
/* Check complete? */
done:
sta->state = EIT_STATUS_DONE;
sta->state = EIT_STATUS_LAST;
for (i = 0; i < 8; i++ ) {
if (sta->sec[i]) {
sta->state = EIT_STATUS_PROCESS;
break;
}
}
return ret;
return sta;
}
typedef struct eit_event
@ -643,8 +648,8 @@ static int _eit_callback
epggrab_ota_mux_t *ota;
th_dvb_adapter_t *tda;
service_t *svc;
eit_status_list_t *stal;
eit_status_t *sta;
eit_table_status_t *tsta;
int resched = 0, save = 0;
uint16_t tsid, sid;
uint16_t sec, lst, seg, ver;
@ -655,12 +660,13 @@ static int _eit_callback
/* Get OTA */
ota = epggrab_ota_find((epggrab_module_ota_t*)mod, tdmi);
if (!ota || !ota->status) return -1;
stal = ota->status;
sta = ota->status;
/* Begin: reset sta->state to force revisiting of all tables */
if (epggrab_ota_begin(ota)) {
LIST_FOREACH(sta, stal, link) {
sta->state = EIT_STATUS_START;
sta->first = NULL;
LIST_FOREACH(tsta, &sta->tables, link) {
tsta->state = EIT_STATUS_START;
}
}
@ -673,12 +679,20 @@ static int _eit_callback
ver = (ptr[2] >> 1) & 0x1f;
#ifdef EPG_EIT_TRACE
tvhlog(LOG_DEBUG, mod->id,
"tid=%02X, tsid=%04X, sid=%04X, sec=%3d/%3d, seg=%3d, ver=%2d",
tableid, tsid, sid, sec, lst, seg, ver);
"tid=0x%02X, tsid=0x%04X, sid=0x%04X, sec=%3d/%3d, seg=%3d, ver=%2d, cur=%d",
tableid, tsid, sid, sec, lst, seg, ver, ptr[2] & 1);
#endif
/* Don't process */
if((ptr[2] & 1) == 0) goto done;
if((ptr[2] & 1) == 0) return 0;
/* Current status */
tsta = eit_status_find(sta, tableid, tsid, sid, sec, lst, seg, ver);
#ifdef EPG_EIT_TRACE
tvhlog(LOG_DEBUG, mod->id, tsta && tsta->state != EIT_STATUS_DONE ? "section process" : "section seen");
#endif
if (!tsta) return 0; // already seen, no state change
if (tsta->state == EIT_STATUS_DONE) goto done;
/* Get transport stream */
// Note: tableid=0x4f,0x60-0x6f is other TS
@ -705,13 +719,6 @@ static int _eit_callback
/* Ignore (not primary EPG service) */
if (!service_is_primary_epg(svc)) goto done;
/* Current status */
sta = eit_status_find(stal, tableid, tsid, sid, sec, lst, seg, ver);
#ifdef EPG_EIT_TRACE
tvhlog(LOG_DEBUG, mod->id, sta ? "section process" : "section seen");
#endif
if (!sta) goto done;
/* Register as interesting */
if (tableid < 0x50)
epggrab_ota_register(ota, 20, 300); // 20s grab, 5min interval
@ -735,28 +742,37 @@ static int _eit_callback
/* Complete */
done:
if (!sta || sta->state == EIT_STATUS_DONE) {
LIST_FOREACH(sta, stal, link)
if (sta->state != EIT_STATUS_DONE) break;
if (!sta)
epggrab_ota_complete(ota);
#ifdef EPG_EIT_TRACE
else {
int total = 0;
int finished = 0;
LIST_FOREACH(sta, stal, link) {
total++;
tvhlog(LOG_DEBUG, mod->id,
"scan status: table=0x%02x, tsid=0x%04x, sid=0x%04x, ver=0x%02d, done=%u, mask=%8x|%8x|%8x|%8x|%8x|%8x|%8x|%8x",
sta->tid, sta->tsid, sta->sid, sta->ver, sta->state,
sta->sec[7], sta->sec[6], sta->sec[5], sta->sec[4], sta->sec[3], sta->sec[2], sta->sec[1], sta->sec[0]);
if (sta->state == EIT_STATUS_DONE) finished++;
}
tvhlog(LOG_DEBUG, mod->id, "scan status: completed %d of %d",
finished, total);
if (tsta->state == EIT_STATUS_LAST)
tsta->state = EIT_STATUS_DONE;
if (tsta->state == EIT_STATUS_DONE) {
if (!sta->first)
sta->first = tsta;
else if (sta->first == tsta) {
LIST_FOREACH(tsta, &sta->tables, link)
if (tsta->state != EIT_STATUS_DONE) break;
if (!tsta) epggrab_ota_complete(ota);
}
#endif
}
#ifdef EPG_EIT_TRACE
if (ota->state != EPGGRAB_OTA_MUX_COMPLETE)
{
int total = 0;
int finished = 0;
tvhlog(LOG_DEBUG, mod->id, "scan status");
LIST_FOREACH(tsta, &sta->tables, link) {
total++;
tvhlog(LOG_DEBUG, mod->id,
" tid=0x%02X, tsid=0x%04X, sid=0x%04X, ver=%02d, done=%d, "
"mask=%08X|%08X|%08X|%08X|%08X|%08X|%08X|%08X",
tsta->tid, tsta->tsid, tsta->sid, tsta->ver,
tsta->state == EIT_STATUS_DONE,
tsta->sec[7], tsta->sec[6], tsta->sec[5], tsta->sec[4],
tsta->sec[3], tsta->sec[2], tsta->sec[1], tsta->sec[0]);
if (tsta->state == EIT_STATUS_DONE) finished++;
}
tvhlog(LOG_DEBUG, mod->id, " completed %d of %d", finished, total);
}
#endif
/* Update EPG */
if (resched) epggrab_resched();
@ -771,16 +787,16 @@ done:
static void _eit_ota_destroy ( epggrab_ota_mux_t *ota )
{
eit_status_t *sta;
eit_status_list_t *stal = ota->status;
eit_status_t *sta = ota->status;
eit_table_status_t *tsta;
/* Remove all entries */
while ((sta = LIST_FIRST(stal))) {
LIST_REMOVE(sta, link);
free(sta);
while ((tsta = LIST_FIRST(&sta->tables))) {
LIST_REMOVE(tsta, link);
free(tsta);
}
free(stal);
free(sta);
free(ota);
}
@ -801,7 +817,7 @@ static void _eit_start
/* Register */
if (!(ota = epggrab_ota_create(m, tdmi))) return;
if (!ota->status) {
ota->status = calloc(1, sizeof(eit_status_list_t));
ota->status = calloc(1, sizeof(eit_status_t));
ota->destroy = _eit_ota_destroy;
}