X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/aa3fdc5321e50af5b79085a0942e9b5cf2d82e30..e38fa979923a2c3ce47822bce550ed2a5ed9364b:/lib/dvb/tstools.cpp diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index e440aeca..34edbc9e 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -7,7 +7,6 @@ eDVBTSTools::eDVBTSTools() { - m_fd = -1; m_pid = -1; m_maxrange = 256*1024; @@ -15,6 +14,7 @@ eDVBTSTools::eDVBTSTools() m_end_valid = 0; m_use_streaminfo = 0; + m_samples_taken = 0; } eDVBTSTools::~eDVBTSTools() @@ -35,17 +35,17 @@ int eDVBTSTools::openFile(const char *filename) eDebug("no recorded stream information available"); m_use_streaminfo = 0; } + + m_samples_taken = 0; - m_fd = ::open(filename, O_RDONLY); - if (m_fd < 0) + if (m_file.open(filename) < 0) return -1; return 0; } void eDVBTSTools::closeFile() { - if (m_fd >= 0) - ::close(m_fd); + m_file.close(); } void eDVBTSTools::setSyncPID(int pid) @@ -64,13 +64,12 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) if (m_use_streaminfo) return m_streaminfo.getPTS(offset, pts); - if (m_fd < 0) + if (!m_file.valid() < 0) return -1; offset -= offset % 188; - // TODO: multiple files! - if (lseek(m_fd, offset, SEEK_SET) < 0) + if (m_file.lseek(offset, SEEK_SET) < 0) return -1; int left = m_maxrange; @@ -78,7 +77,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) while (left >= 188) { unsigned char block[188]; - if (read(m_fd, block, 188) != 188) + if (m_file.read(block, 188) != 188) { eDebug("read error"); break; @@ -95,7 +94,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) break; ++i; } - offset = lseek(m_fd, i - 188, SEEK_CUR); + offset = m_file.lseek(i - 188, SEEK_CUR); continue; } @@ -132,6 +131,8 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed) pts |= ((unsigned long long)(pes[13]&0xFE)) >> 1; offset -= 188; +// eDebug("found pts %08llx at %08llx", pts, offset); + /* convert to zero-based */ if (fixed) fixupPTS(offset, pts); @@ -180,20 +181,63 @@ int eDVBTSTools::getOffset(off_t &offset, pts_t &pts) return 0; } else { - int bitrate = calcBitrate(); /* in bits/s */ - if (bitrate <= 0) - return -1; +// eDebug("get offset"); + if (!m_samples_taken) + takeSamples(); + + if (!m_samples.empty()) + { +// eDebug("ok, samples ok"); + /* search entry before and after */ + std::map::const_iterator l = m_samples.lower_bound(pts); + std::map::const_iterator u = l; + + if (l != m_samples.begin()) + --l; - offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL; + if ((u != m_samples.end()) && (l != m_samples.end())) + { + pts_t pts_diff = u->first - l->first; + off_t offset_diff = u->second - l->second; +// eDebug("using: %llx:%llx -> %llx:%llx", l->first, u->first, l->second, u->second); + + if (pts_diff) + { + int bitrate = offset_diff * 90000 * 8 / pts_diff; + if (bitrate > 0) + { + offset = l->second; + offset += ((pts - l->first) * (pts_t)bitrate) / 8ULL / 90000ULL; + offset -= offset % 188; + return 0; + } + } + } + } + + eDebug("falling back"); + int bitrate = calcBitrate(); + offset = pts * (pts_t)bitrate / 8ULL / 90000ULL; offset -= offset % 188; return 0; } } +int eDVBTSTools::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction) +{ + if (m_use_streaminfo) + return m_streaminfo.getNextAccessPoint(ts, start, direction); + else + { + eDebug("can't get next access point without streaminfo"); + return -1; + } +} + void eDVBTSTools::calcBegin() { - if (m_fd < 0) + if (!m_file.valid()) return; if (!m_begin_valid) @@ -206,10 +250,10 @@ void eDVBTSTools::calcBegin() void eDVBTSTools::calcEnd() { - if (m_fd < 0) + if (!m_file.valid()) return; - off_t end = lseek(m_fd, 0, SEEK_END); + off_t end = m_file.lseek(0, SEEK_END); if (abs(end - m_offset_end) > 1*1024*1024) { @@ -268,4 +312,35 @@ int eDVBTSTools::calcBitrate() return -1; return bitrate; +} + + /* pts, off */ +void eDVBTSTools::takeSamples() +{ + m_samples_taken = 1; + m_samples.clear(); + pts_t dummy; + if (calcLen(dummy) == -1) + return; + + int nr_samples = 30; + off_t bytes_per_sample = (m_offset_end - m_offset_begin) / (long long)nr_samples; + if (bytes_per_sample < 40*1024*1024) + 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) + { + off_t o = offset; + pts_t p; + if (!eDVBTSTools::getPTS(o, p, 1)) + { +// eDebug("sample: %llx, %llx", o, p); + m_samples[p] = o; + } + } + m_samples[m_pts_begin] = m_offset_begin; + m_samples[m_pts_end] = m_offset_end; +// eDebug("begin, end: %llx %llx", m_offset_begin, m_offset_end); }