aboutsummaryrefslogtreecommitdiff
path: root/lib/dvb/tstools.cpp
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2005-08-14 16:25:44 +0000
committerFelix Domke <tmbinc@elitedvb.net>2005-08-14 16:25:44 +0000
commitd375f3ea3ead88dcc4f41c6e5c551370cd305755 (patch)
tree9d14d5678b8dd9e245d5b9a78f940554476a31c8 /lib/dvb/tstools.cpp
parent9c2983bcc72ab3e24999c4d7a4b2ac9b2cd5597a (diff)
downloadenigma2-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.cpp151
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;
+}
+