diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index a5f4a02d..04f437de 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -166,6 +166,8 @@ int dvb_table_begin (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid, uint64_t extraid, int minlen, struct mpegts_table_state **st, int *sect, int *last, int *ver); +void dvb_table_reset + (struct mpegts_table *mt ); int dvb_pat_callback (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 1819c4da..05d2bc17 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -391,6 +391,7 @@ mpegts_table_state_reset } mt->mt_finished = 0; st->complete = 0; + st->version = 0xff; /* invalid */ memset(st->sections, 0, sizeof(st->sections)); for (i = 0; i < last / 32; i++) st->sections[i] = 0xFFFFFFFF; @@ -531,6 +532,18 @@ dvb_table_begin return 1; } +void +dvb_table_reset(mpegts_table_t *mt) +{ + mpegts_table_state_t *st; + + tvhtrace(mt->mt_name, "pid %02X complete reset", mt->mt_pid); + while ((st = RB_FIRST(&mt->mt_state)) != NULL) { + RB_REMOVE(&mt->mt_state, st, link); + free(st); + } +} + /* * PAT processing */ diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index 71d945a7..7cee71c6 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -52,17 +52,24 @@ mpegts_table_dispatch if(mt->mt_destroyed) return; - /* It seems some hardware (or is it the dvb API?) does not - honour the DMX_CHECK_CRC flag, so we check it again */ - if(chkcrc && tvh_crc32(sec, r, 0xffffffff)) { - tvhwarn(mt->mt_name, "invalid checksum"); - return; - } - /* Table info */ tid = sec[0]; len = ((sec[1] & 0x0f) << 8) | sec[2]; - + + if (r > 2 && tid == 0x72) { /* stuffing section */ + if (len != r - 3) + tvhwarn(mt->mt_name, "stuffing found with trailing data (len %i, total %zi)", len, r); + dvb_table_reset(mt); + return; + } + + /* It seems some hardware (or is it the dvb API?) does not + honour the DMX_CHECK_CRC flag, so we check it again */ + if(chkcrc && tvh_crc32(sec, r, 0xffffffff)) { + tvhwarn(mt->mt_name, "invalid checksum (len %zi)", r); + return; + } + /* Not enough data */ if(len < r - 3) { tvhtrace(mt->mt_name, "not enough data, %d < %d", (int)r, len);