X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=lib%2Fdvb%2Fesection.h;h=3e097ccc142c5e12338559760a454f540aebda9c;hb=4712fa7b44263f0e9517bb5a4b1729d922994572;hp=5dc84ec6019dba8c823087677d65ce29e1396870;hpb=2e0270746af934180499931f95ed91c444c8233e;p=vuplus_dvbapp diff --git a/lib/dvb/esection.h b/lib/dvb/esection.h index 5dc84ec..3e097cc 100644 --- a/lib/dvb/esection.h +++ b/lib/dvb/esection.h @@ -4,6 +4,9 @@ #include #include +#define TABLE_eDebug(x...) do { if (m_debug) eDebug(x); } while(0) +#define TABLE_eDebugNoNewLine(x...) do { if (m_debug) eDebugNoNewLine(x); } while(0) + class eGTable: public iObject, public Object { DECLARE_REF(eGTable); @@ -12,16 +15,17 @@ class eGTable: public iObject, public Object unsigned int m_tries; - eTimer *m_timeout; + ePtr m_timeout; void sectionRead(const __u8 *data); void timeout(); ePtr m_sectionRead_conn; protected: + bool m_debug; virtual int createTable(unsigned int nr, const __u8 *data, unsigned int max)=0; public: Signal1 tableReady; - eGTable(); + eGTable(bool debug=true); RESULT start(iDVBSectionReader *reader, const eDVBTableSpec &table); RESULT start(iDVBDemux *reader, const eDVBTableSpec &table); RESULT getSpec(eDVBTableSpec &spec) { spec = m_table; return 0; } @@ -42,7 +46,7 @@ protected: unsigned int ssize = sections.size(); if (max < ssize || nr >= max) { - eDebug("kaputt max(%d) < ssize(%d) || nr(%d) >= max(%d)", + TABLE_eDebug("kaputt max(%d) < ssize(%d) || nr(%d) >= max(%d)", max, ssize, nr, max); return 0; } @@ -55,22 +59,22 @@ protected: for (unsigned int i = 0; i < max; ++i) if (avail.find(i) != avail.end()) - eDebugNoNewLine("+"); + TABLE_eDebugNoNewLine("+"); else - eDebugNoNewLine("-"); + TABLE_eDebugNoNewLine("-"); - eDebug(" %d/%d TID %02x", avail.size(), max, data[0]); + TABLE_eDebug(" %zd/%d TID %02x", avail.size(), max, data[0]); if (avail.size() == max) { - eDebug("done!"); + TABLE_eDebug("done!"); return 1; } else return 0; } public: std::vector &getSections() { return sections; } - eTable(): eGTable() + eTable(bool debug=true): eGTable(debug) { } ~eTable() @@ -96,6 +100,10 @@ class eAUTable: public eAUGTable int first; ePtr m_demux; eMainloop *ml; + + /* needed to detect broken table version handling (seen on some m2ts files) */ + struct timespec m_prev_table_update; + int m_table_cnt; public: eAUTable() @@ -115,6 +123,7 @@ public: int begin(eMainloop *m, const eDVBTableSpec &spec, ePtr demux) { + m_table_cnt = 0; ml = m; m_demux = demux; first= 1; @@ -185,7 +194,7 @@ public: next=0; first=0; - assert(current->ready); + ASSERT(current->ready); /*emit*/ tableReady(0); @@ -193,6 +202,24 @@ public: if (current && (!current->getSpec(spec))) { + /* detect broken table version handling (seen on some m2ts files) */ + if (m_table_cnt) + { + if (abs(timeout_usec(m_prev_table_update)) > 500000) + m_table_cnt = -1; + else if (m_table_cnt > 1) // two pmt update within one second + { + eDebug("Seen two consecutive table version changes within 500ms. " + "This seems broken, so auto update for pid %04x, table %02x is now disabled!!", + spec.pid, spec.tid); + m_table_cnt = 0; + return; + } + } + + ++m_table_cnt; + clock_gettime(CLOCK_MONOTONIC, &m_prev_table_update); + next = new Table(); CONNECT(next->tableReady, eAUTable::slotTableReady); spec.flags &= ~(eDVBTableSpec::tfAnyVersion|eDVBTableSpec::tfThisVersion|eDVBTableSpec::tfHaveTimeout);