diff --git a/src/input/mpegts.h b/src/input/mpegts.h index ddbcff57..cb71fb66 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -78,11 +78,11 @@ struct mpegts_psi_section typedef struct mpegts_table_state { int tableid; - int extraid; + uint64_t extraid; int version; int complete; uint32_t sections[8]; - RB_ENTRY(mpegts_table_state) link; + RB_ENTRY(mpegts_table_state) link; } mpegts_table_state_t; struct mpegts_table @@ -119,6 +119,8 @@ struct mpegts_table mpegts_table_callback_t mt_callback; RB_HEAD(,mpegts_table_state) mt_state; + int mt_complete; + int mt_incomplete; int mt_count; @@ -137,6 +139,10 @@ struct mpegts_table mpegts_psi_section_t mt_sect; struct mpegts_table_mux_cb *mt_mux_cb; + + void (*mt_destroy) (mpegts_table_t *mt); // Allow customisable destroy hook + // useful for dynamic allocation of + // the opaque field }; /** diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index 78d70137..721f1b62 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -160,7 +160,7 @@ int dvb_table_end (struct mpegts_table *mt, struct mpegts_table_state *st, int sect ); int dvb_table_begin (struct mpegts_table *mt, const uint8_t *ptr, int len, - int tableid, int extraid, int minlen, + int tableid, uint64_t extraid, int minlen, struct mpegts_table_state **st, int *sect, int *last, int *ver); int dvb_pat_callback diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 3c93e62d..44c2a680 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -389,16 +389,24 @@ dvb_desc_local_channel static int sect_cmp ( struct mpegts_table_state *a, struct mpegts_table_state *b ) { - if (b->tableid != a->tableid) + if (a->tableid != b->tableid) return a->tableid - b->tableid; - return a->extraid - b->extraid; + if (a->extraid < b->extraid) + return -1; + if (a->extraid > b->extraid) + return 1; + return 0; } static void mpegts_table_state_reset - ( mpegts_table_state_t *st, int last ) + ( mpegts_table_t *mt, mpegts_table_state_t *st, int last ) { int i; + if (st->complete == 2) { + mt->mt_complete--; + mt->mt_incomplete++; + } st->complete = 0; memset(st->sections, 0, sizeof(st->sections)); for (i = 0; i < last / 32; i++) @@ -408,7 +416,7 @@ mpegts_table_state_reset static struct mpegts_table_state * mpegts_table_state_find - ( mpegts_table_t *mt, int tableid, int extraid, int last ) + ( mpegts_table_t *mt, int tableid, uint64_t extraid, int last ) { static struct mpegts_table_state *st, *skel = NULL; @@ -421,7 +429,8 @@ mpegts_table_state_find if (!st) { st = skel; skel = NULL; - mpegts_table_state_reset(st, last); + mt->mt_incomplete++; + mpegts_table_state_reset(mt, st, last); } return st; } @@ -433,19 +442,16 @@ static int dvb_table_complete (mpegts_table_t *mt) { - int c = 0, p = 0; - struct mpegts_table_state *st; - tvhtrace(mt->mt_name, "status: "); - RB_FOREACH(st, &mt->mt_state, link) { - tvhtrace(mt->mt_name, " tableid %02X extraid %08X ver %2d complete %d", - st->tableid, st->extraid, st->version, st->complete); - if (!st->complete) - p = 1; - else - c = MAX(c, st->complete); + if (mt->mt_incomplete || !mt->mt_complete) { + int total = 0; + mpegts_table_state_t *st; + RB_FOREACH(st, &mt->mt_state, link) + total++; + tvhtrace(mt->mt_name, "incomplete %d complete %d total %d", + mt->mt_incomplete, mt->mt_complete, total); + return -1; } - if (p || c != 2) return -1; - tvhdebug(mt->mt_name, "completed"); + tvhdebug(mt->mt_name, "subtable completed"); return 0; } @@ -456,6 +462,7 @@ dvb_table_end int sa, sb; uint32_t rem; if (st) { + assert(sect >= 0 && sect <= 255); sa = sect / 32; sb = sect % 32; st->sections[sa] &= ~(0x1 << (31 - sb)); @@ -464,9 +471,10 @@ dvb_table_end for (sa = 0; sa < 8; sa++) rem |= st->sections[sa]; if (rem) return -1; - tvhtrace(mt->mt_name, " tableid %02X extraid %08X completed", + tvhtrace(mt->mt_name, " tableid %02X extraid %016lX completed", st->tableid, st->extraid); st->complete = 1; + mt->mt_incomplete--; return dvb_table_complete(mt); } } @@ -479,7 +487,7 @@ dvb_table_end int dvb_table_begin (mpegts_table_t *mt, const uint8_t *ptr, int len, - int tableid, int extraid, int minlen, + int tableid, uint64_t extraid, int minlen, mpegts_table_state_t **ret, int *sect, int *last, int *ver) { mpegts_table_state_t *st; @@ -495,8 +503,8 @@ dvb_table_begin if((ptr[2] & 1) == 0) return -1; - tvhtrace(mt->mt_name, "tableid %02X extraid %08X len %d", - tableid, extraid, len); + tvhtrace(mt->mt_name, "pid %02X tableid %02X extraid %016lX len %d", + mt->mt_pid, tableid, extraid, len); /* Section info */ if (sect && ret) { @@ -510,7 +518,7 @@ dvb_table_begin if (st->complete && st->version != *ver) { tvhtrace(mt->mt_name, " new version, restart"); - mpegts_table_state_reset(st, *last); + mpegts_table_state_reset(mt, st, *last); } st->version = *ver; @@ -519,6 +527,7 @@ dvb_table_begin tvhtrace(mt->mt_name, " skip, already complete"); if (st->complete == 1) { st->complete = 2; + mt->mt_complete++; return dvb_table_complete(mt); } return -1; @@ -735,7 +744,7 @@ dvb_nit_callback /* Network Descriptors */ *name = 0; DVB_DESC_FOREACH(ptr, len, 5, lptr, llen, dtag, dlen, dptr) { - tvhdebug(mt->mt_name, " dtag %02X dlen %d", dtag, dlen); + tvhtrace(mt->mt_name, " dtag %02X dlen %d", dtag, dlen); switch (dtag) { case DVB_DESC_BOUQUET_NAME: @@ -773,7 +782,7 @@ dvb_nit_callback break; DVB_DESC_FOREACH(lptr, llen, 4, dlptr, dllen, dtag, dlen, dptr) { - tvhdebug(mt->mt_name, " dtag %02X dlen %d", dtag, dlen); + tvhtrace(mt->mt_name, " dtag %02X dlen %d", dtag, dlen); /* User-defined */ if (mt->mt_mux_cb) { @@ -882,9 +891,7 @@ dvb_sdt_callback int free_ca_mode = (ptr[3] >> 4) & 0x1; int stype = 0; char sprov[256], sname[256], sauth[256]; -#if ENABLE_TRACE int running_status = (ptr[3] >> 5) & 0x7; -#endif *sprov = *sname = *sauth = 0; tvhdebug("sdt", " sid %04X (%d) running %d free_ca %d", service_id, service_id, running_status, free_ca_mode); @@ -897,7 +904,7 @@ dvb_sdt_callback /* Descriptor loop */ DVB_DESC_EACH(lptr, llen, dtag, dlen, dptr) { - tvhdebug("sdt", " dtag %02X dlen %d", dtag, dlen); + tvhtrace("sdt", " dtag %02X dlen %d", dtag, dlen); switch (dtag) { case DVB_DESC_SERVICE: if (dvb_desc_service(dptr, dlen, &stype, sprov, @@ -911,7 +918,7 @@ dvb_sdt_callback } } - tvhdebug("sdt", " type %d name [%s] provider [%s] def_auth [%s]", + tvhtrace("sdt", " type %d name [%s] provider [%s] def_auth [%s]", stype, sname, sprov, sauth); if (!s) continue; diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index 93dd874a..dbb1baa8 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -371,8 +371,6 @@ mpegts_mux_start return SM_CODE_NO_FREE_ADAPTER; } - mpegts_fire_event(mm, ml_mux_start); - return 0; } diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index 3a46b011..74b7966c 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -115,6 +115,8 @@ mpegts_table_destroy ( mpegts_table_t *mt ) RB_REMOVE(&mt->mt_state, st, link); free(st); } + if (mt->mt_destroy) + mt->mt_destroy(mt); mpegts_table_release(mt); }