diff options
| author | Felix Domke <tmbinc@elitedvb.net> | 2005-08-14 16:25:44 +0000 |
|---|---|---|
| committer | Felix Domke <tmbinc@elitedvb.net> | 2005-08-14 16:25:44 +0000 |
| commit | d375f3ea3ead88dcc4f41c6e5c551370cd305755 (patch) | |
| tree | 9d14d5678b8dd9e245d5b9a78f940554476a31c8 /lib/dvb/tstools.cpp | |
| parent | 9c2983bcc72ab3e24999c4d7a4b2ac9b2cd5597a (diff) | |
| download | enigma2-d375f3ea3ead88dcc4f41c6e5c551370cd305755.tar.gz enigma2-d375f3ea3ead88dcc4f41c6e5c551370cd305755.zip | |
- add tstools to evaluate PTS values from TS files for playback
Diffstat (limited to 'lib/dvb/tstools.cpp')
| -rw-r--r-- | lib/dvb/tstools.cpp | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp new file mode 100644 index 00000000..5d1c7e35 --- /dev/null +++ b/lib/dvb/tstools.cpp @@ -0,0 +1,151 @@ +#include <lib/dvb/tstools.h> +#include <unistd.h> +#include <fcntl.h> + +#include <stdio.h> + +eDVBTSTools::eDVBTSTools() +{ + m_fd = -1; + m_pid = -1; + m_maxrange = 1*1024*1024; + + m_begin_valid = 0; + m_end_valid = 0; +} + +eDVBTSTools::~eDVBTSTools() +{ + closeFile(); +} + +int eDVBTSTools::openFile(const char *filename) +{ + closeFile(); + m_fd = ::open(filename, O_RDONLY); + if (m_fd < 0) + return -1; + return 0; +} + +void eDVBTSTools::closeFile() +{ + if (m_fd >= 0) + ::close(m_fd); +} + +void eDVBTSTools::setSyncPID(int pid) +{ + m_pid = pid; +} + +void eDVBTSTools::setSearchRange(int maxrange) +{ + m_maxrange = maxrange; +} + +int eDVBTSTools::getPTS(off_t &offset, pts_t &pts) +{ + if (m_fd < 0) + return -1; + if (m_pid < 0) + return -1; + + offset -= offset % 188; + + // TODO: multiple files! + if (lseek(m_fd, offset, SEEK_SET) < 0) + return -1; + + int left = m_maxrange; + + while (left >= 188) + { + unsigned char block[188]; + if (read(m_fd, block, 188) != 188) + break; + left -= 188; + offset += 188; + + if (block[0] != 0x47) + { + int i = 0; + while (i < 188) + if (block[i] == 0x47) + break; + offset = lseek(m_fd, i - 188, SEEK_CUR); + continue; + } + + int pid = ((block[1] << 8) | block[2]) & 0x1FFF; + int pusi = !!(block[1] & 0x40); + +// printf("PID %04x, PUSI %d\n", pid, pusi); + + if (pid != m_pid) + continue; + if (!pusi) + continue; + + /* ok, now we have a PES header */ + unsigned char *pes; + + /* check for adaption field */ + if (block[3] & 0x10) + pes = block + block[4] + 4 + 1; + else + pes = block + 4; + + /* somehow not a startcode. (this is invalid, since pusi was set.) ignore it. */ + if (pes[0] || pes[1] || (pes[2] != 1)) + continue; + + if (pes[7] & 0x80) /* PTS */ + { + pts = ((unsigned long long)(pes[ 9]&0xE)) << 29; + pts |= ((unsigned long long)(pes[10]&0xFF)) << 22; + pts |= ((unsigned long long)(pes[11]&0xFE)) << 14; + pts |= ((unsigned long long)(pes[12]&0xFF)) << 7; + pts |= ((unsigned long long)(pes[13]&0xFE)) >> 1; + offset -= 188; + return 0; + } + } + + return -1; +} + +void eDVBTSTools::calcBegin() +{ + if (m_fd < 0) + return; + if (!m_begin_valid) + { + m_offset_begin = 0; + if (!getPTS(m_offset_begin, m_pts_begin)) + m_begin_valid = 1; + } +} + +void eDVBTSTools::calcEnd() +{ + if (m_fd < 0) + return; + + if (!m_end_valid) + { + m_offset_end = lseek(m_fd, 0, SEEK_END) - m_maxrange; + if (!getPTS(m_offset_end, m_pts_end)) + m_end_valid = 1; + } +} + +int eDVBTSTools::calcLen(pts_t &len) +{ + calcBegin(); calcEnd(); + if (!(m_begin_valid && m_end_valid)) + return -1; + len = m_pts_end - m_pts_begin; + return 0; +} + |
