X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/bce2ef4220fecb2c2e296c85ec2fbef5794f4492..e03708b0a361c236d7034f35e4585edd4a91bb34:/lib/dvb/tstools.cpp diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index dafd70fe..d5ad2494 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -138,7 +138,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) pts |= ((unsigned long long)(packet[ 9]&0xFF)) << 1; pts |= ((unsigned long long)(packet[10]&0x80)) >> 7; offset -= 188; - eDebug("PCR found at %llx: %16llx", offset, pts); + eDebug("PCR %16llx found at %lld pid %02x (%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)", pts, offset, pid, packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9], packet[10]); if (fixed && fixupPTS(offset, pts)) return -1; return 0; @@ -148,24 +148,83 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) } else payload = packet + 4; - /* if (m_pid >= 0) if (pid != m_pid) continue; */ if (!pusi) continue; - - + /* somehow not a startcode. (this is invalid, since pusi was set.) ignore it. */ if (payload[0] || payload[1] || (payload[2] != 1)) continue; - + + if (payload[3] == 0xFD) + { // stream use extension mechanism defined in ISO 13818-1 Amendment 2 + if (payload[7] & 1) // PES extension flag + { + int offs = 0; + if (payload[7] & 0x80) // pts avail + offs += 5; + if (payload[7] & 0x40) // dts avail + offs += 5; + if (payload[7] & 0x20) // escr avail + offs += 6; + if (payload[7] & 0x10) // es rate + offs += 3; + if (payload[7] & 0x8) // dsm trickmode + offs += 1; + if (payload[7] & 0x4) // additional copy info + offs += 1; + if (payload[7] & 0x2) // crc + offs += 2; + if (payload[8] < offs) + continue; + uint8_t pef = payload[9+offs++]; // pes extension field + if (pef & 1) // pes extension flag 2 + { + if (pef & 0x80) // private data flag + offs += 16; + if (pef & 0x40) // pack header field flag + offs += 1; + if (pef & 0x20) // program packet sequence counter flag + offs += 2; + if (pef & 0x10) // P-STD buffer flag + offs += 2; + if (payload[8] < offs) + continue; + uint8_t stream_id_extension_len = payload[9+offs++] & 0x7F; + if (stream_id_extension_len >= 1) + { + if (payload[8] < (offs + stream_id_extension_len) ) + continue; + if (payload[9+offs] & 0x80) // stream_id_extension_bit (should not set) + continue; + switch (payload[9+offs]) + { + case 0x55 ... 0x5f: // VC-1 + break; + case 0x71: // AC3 / DTS + break; + default: + eDebug("skip unknwn stream_id_extension %02x\n", payload[9+offs]); + continue; + } + } + else + continue; + } + else + continue; + } + else + continue; + } /* drop non-audio, non-video packets because other streams can be non-compliant.*/ - if (((payload[3] & 0xE0) != 0xC0) && // audio - ((payload[3] & 0xF0) != 0xE0)) // video + else if (((payload[3] & 0xE0) != 0xC0) && // audio + ((payload[3] & 0xF0) != 0xE0)) // video continue; - + if (payload[7] & 0x80) /* PTS */ { pts = ((unsigned long long)(payload[ 9]&0xE)) << 29; @@ -175,11 +234,11 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) pts |= ((unsigned long long)(payload[13]&0xFE)) >> 1; offset -= 188; -// eDebug("found pts %08llx at %08llx pid %02x stream: %02x", pts, offset, pid, payload[3]); - + eDebug("PTS %16llx found at %lld pid %02x stream: %02x", pts, offset, pid, payload[3]); + /* convert to zero-based */ if (fixed && fixupPTS(offset, pts)) - return -1; + return -1; return 0; } } @@ -216,10 +275,13 @@ int eDVBTSTools::fixupPTS(const off_t &offset, pts_t &now) now -= pos; return 0; } + eDebug("eDVBTSTools::fixupPTS failed!"); + return -1; } int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg) { + eDebug("getOffset for pts 0x%llx", pts); if (m_use_streaminfo) { if (pts >= m_pts_end && marg > 0 && m_end_valid) @@ -445,6 +507,8 @@ void eDVBTSTools::takeSamples() m_samples_taken = 1; m_samples.clear(); pts_t dummy; + int retries=2; + if (calcLen(dummy) == -1) return; @@ -454,21 +518,27 @@ void eDVBTSTools::takeSamples() bytes_per_sample = 40*1024*1024; bytes_per_sample -= bytes_per_sample % 188; - - for (off_t offset = m_offset_begin; offset < m_offset_end; offset += bytes_per_sample) + + eDebug("samples step %lld, pts begin %llx, pts end %llx, offs begin %lld, offs end %lld:", + bytes_per_sample, m_pts_begin, m_pts_end, m_offset_begin, m_offset_end); + + for (off_t offset = m_offset_begin; offset < m_offset_end;) { pts_t p; - takeSample(offset, p); + if (takeSample(offset, p) && retries--) + continue; + retries = 2; + offset += bytes_per_sample; } m_samples[0] = m_offset_begin; m_samples[m_pts_end - m_pts_begin] = m_offset_end; - -// eDebug("begin, end: %llx %llx", m_offset_begin, m_offset_end); } /* returns 0 when a sample was taken. */ int eDVBTSTools::takeSample(off_t off, pts_t &p) { + off_t offset_org = off; + if (!eDVBTSTools::getPTS(off, p, 1)) { /* as we are happily mixing PTS and PCR values (no comment, please), we might @@ -486,18 +556,18 @@ int eDVBTSTools::takeSample(off_t off, pts_t &p) { if ((l->second > off) || (u->second < off)) { - eDebug("ignoring sample %llx %llx %llx (%lld %lld %lld)", + eDebug("ignoring sample %lld %lld %lld (%llx %llx %llx)", l->second, off, u->second, l->first, p, u->first); return 1; } } } - + eDebug("adding sample %lld: pts 0x%llx -> pos %lld (diff %lld bytes)", offset_org, p, off, off-offset_org); m_samples[p] = off; return 0; } - return 1; + return -1; } int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)