Ensure that EIT scanning will not block after first pass, will only update as required and will continue to operate if someone stays tuned to the mux.

This commit is contained in:
Adam Sutton 2012-09-10 21:34:41 +01:00
parent 692349682d
commit 45ca377747

View file

@ -38,13 +38,14 @@ typedef struct eit_status
uint16_t tsid;
uint16_t sid;
uint32_t sec[8];
uint8_t ver;
int done;
} eit_status_t;
typedef LIST_HEAD(, eit_status) eit_status_list_t;
static eit_status_t *eit_status_find
( eit_status_list_t *el, int tableid, uint16_t tsid, uint16_t sid,
uint8_t sec, uint8_t lst, uint8_t seg )
uint8_t sec, uint8_t lst, uint8_t seg, uint8_t ver )
{
int i;
uint32_t msk;
@ -56,7 +57,7 @@ static eit_status_t *eit_status_find
break;
/* Already complete */
if (sta && sta->done) return NULL;
if (sta && sta->done && sta->ver == ver) return NULL;
/* Insert new entry */
if (!sta) {
@ -65,6 +66,12 @@ static eit_status_t *eit_status_find
sta->tid = tableid;
sta->tsid = tsid;
sta->sid = sid;
sta->ver = 255; // Note: force update below
}
/* Reset */
if (sta->ver != ver) {
sta->ver = ver;
for (i = 0; i < (lst / 32); i++)
sta->sec[i] = 0xFFFFFFFF;
if (lst % 32)
@ -577,6 +584,7 @@ static int _eit_callback
eit_status_t *sta;
int resched = 0, save = 0;
uint16_t tsid, sid;
uint16_t sec, lst, seg, ver;
/* Invalid */
if(tableid < 0x4e || tableid > 0x6f || len < 11) return -1;
@ -589,12 +597,25 @@ static int _eit_callback
if (!ota || !ota->status) return -1;
stal = ota->status;
/* Already complete */
if (epggrab_ota_is_complete(ota)) return 0;
/* Get tsid/sid */
/* Get table info */
sid = ptr[0] << 8 | ptr[1];
tsid = ptr[5] << 8 | ptr[6];
sec = ptr[3];
lst = ptr[4];
seg = ptr[9];
ver = (ptr[2] >> 1) & 0x1f;
#ifdef EPG_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);
#endif
/* Current status */
sta = eit_status_find(stal, tableid, tsid, sid, sec, lst, seg, ver);
#ifdef EPG_TRACE
tvhlog(LOG_DEBUG, mod->id, sta ? "section process" : "section seen");
#endif
if (!sta) return 0;
/* Get transport stream */
// Note: tableid=0x4f,0x60-0x6f is other TS
@ -604,6 +625,8 @@ static int _eit_callback
LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link)
if(tdmi->tdmi_transport_stream_id == tsid)
break;
} else {
if (tdmi->tdmi_transport_stream_id != tsid) return -1;
}
if(!tdmi) return 0;
@ -614,13 +637,9 @@ static int _eit_callback
/* Ignore (not primary EPG service) */
if (!service_is_primary_epg(svc)) return 0;
sta = eit_status_find(stal, tableid, tsid, sid, ptr[3], ptr[4],
ptr[9]);
if (!sta) return 0;
/* Started */
if (epggrab_ota_begin(ota)) {
// nothing/clear?
// Note: we don't clear, status is persistent to reduce overhead
/* Check end */
} else if (sta->done) {
@ -635,6 +654,7 @@ static int _eit_callback
epggrab_ota_register(ota, 600, 3600); // 10min grab, 1hour interval
// Note: this does mean you will get a slight oddity for muxes that
// carry both, since they will end up with setting of 600/300
// Note: could we be more dynamic for now/next interval?
/* Process events */
len -= 11;
@ -649,7 +669,7 @@ static int _eit_callback
}
/* Complete */
if (!sta) epggrab_ota_complete(ota);
if (!sta) epggrab_ota_complete(ota);
/* Update EPG */
if (resched) epggrab_resched();