change timing pid even when recording thread is already running
[enigma2.git] / lib / dvb / demux.cpp
index 918ecec6bf6dca4c0a1b9ef33541e7ff97d437eb..4fba8fa85b8359b1c2ac0f2d7fd28e8bf072c2c2 100644 (file)
@@ -5,6 +5,13 @@
 #include <unistd.h>
 #include <signal.h>
 
+// #define FUZZING 1
+
+#if FUZZING
+               /* change every 1:FUZZING_PROPABILITY byte */
+#define FUZZING_PROPABILITY 100
+#endif
+
 #if HAVE_DVB_API_VERSION < 3
 #include <ost/dmx.h>
 
 #define HAVE_ADD_PID
 
 #ifdef HAVE_ADD_PID
+
+#if HAVE_DVB_API_VERSION > 3
+#ifndef DMX_ADD_PID
+#define DMX_ADD_PID            _IOW('o', 51, __u16)
+#define DMX_REMOVE_PID         _IOW('o', 52, __u16)
+#endif
+#else
 #define DMX_ADD_PID              _IO('o', 51)
 #define DMX_REMOVE_PID           _IO('o', 52)
 
@@ -35,6 +49,7 @@ typedef enum {
        DMX_TAP_TS = 0,
        DMX_TAP_PES = DMX_PES_OTHER, /* for backward binary compat. */
 } dmx_tap_type_t;
+#endif
 
 #endif
 
@@ -178,6 +193,14 @@ void eDVBSectionReader::data(int)
        __u8 data[4096]; // max. section size
        int r;
        r = ::read(fd, data, 4096);
+#if FUZZING
+       int j;
+       for (j = 0; j < r; ++j)
+       {
+               if (!(rand()%FUZZING_PROPABILITY))
+                       data[j] ^= rand();
+       }
+#endif 
        if(r < 0)
        {
                eWarning("ERROR reading section - %m\n");
@@ -243,11 +266,13 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask)
 #else
        sct.flags   = DMX_IMMEDIATE_START;
 #endif
+#if !FUZZING
        if (mask.flags & eDVBSectionFilterMask::rfCRC)
        {
                sct.flags |= DMX_CHECK_CRC;
                checkcrc = 1;
        } else
+#endif
                checkcrc = 0;
        
        memcpy(sct.filter.filter, mask.data, DMX_FILTER_SIZE);
@@ -476,12 +501,17 @@ eDVBTSRecorder::~eDVBTSRecorder()
 
 RESULT eDVBTSRecorder::start()
 {
+       std::map<int,int>::iterator i(m_pids.begin());
+
        if (m_running)
                return -1;
        
        if (m_target_fd == -1)
                return -2;
 
+       if (i == m_pids.end())
+               return -3;
+
        char filename[128];
 #ifndef HAVE_ADD_PID
 #if HAVE_DVB_API_VERSION < 3
@@ -510,10 +540,16 @@ RESULT eDVBTSRecorder::start()
        ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, 1024*1024);
 
        dmx_pes_filter_params flt;
+#if HAVE_DVB_API_VERSION > 3
+       flt.pes_type = DMX_PES_OTHER;
+       flt.output  = DMX_OUT_TSDEMUX_TAP;
+#else
        flt.pes_type = (dmx_pes_type_t)DMX_TAP_TS;
-       flt.pid     = (__u16)-1;
-       flt.input   = DMX_IN_FRONTEND;
        flt.output  = DMX_OUT_TAP;
+#endif
+       flt.pid     = i->first;
+       ++i;
+       flt.input   = DMX_IN_FRONTEND;
        flt.flags   = 0;
        int res = ::ioctl(m_source_fd, DMX_SET_PES_FILTER, &flt);
        if (res)
@@ -532,10 +568,12 @@ RESULT eDVBTSRecorder::start()
        
        m_thread->start(m_source_fd, m_target_fd);
        m_running = 1;
-       
-       for (std::map<int,int>::iterator i(m_pids.begin()); i != m_pids.end(); ++i)
+
+       while (i != m_pids.end()) {
                startPID(i->first);
-       
+               ++i;
+       }
+
        return 0;
 }
 
@@ -564,8 +602,6 @@ RESULT eDVBTSRecorder::removePID(int pid)
 
 RESULT eDVBTSRecorder::setTimingPID(int pid, int type)
 {
-       if (m_running)
-               return -1;
        m_thread->setTimingPID(pid, type);
        return 0;
 }
@@ -658,7 +694,12 @@ RESULT eDVBTSRecorder::startPID(int pid)
        m_pids[pid] = fd;
 #else
        while(true) {
+#if HAVE_DVB_API_VERSION > 3
+               __u16 p = pid;
+               if (::ioctl(m_source_fd, DMX_ADD_PID, &p) < 0) {
+#else
                if (::ioctl(m_source_fd, DMX_ADD_PID, pid) < 0) {
+#endif
                        perror("DMX_ADD_PID");
                        if (errno == EAGAIN || errno == EINTR) {
                                eDebug("retry!");
@@ -681,7 +722,12 @@ void eDVBTSRecorder::stopPID(int pid)
        if (m_pids[pid] != -1)
        {
                while(true) {
+#if HAVE_DVB_API_VERSION > 3
+                       __u16 p = pid;
+                       if (::ioctl(m_source_fd, DMX_REMOVE_PID, &p) < 0) {
+#else
                        if (::ioctl(m_source_fd, DMX_REMOVE_PID, pid) < 0) {
+#endif
                                perror("DMX_REMOVE_PID");
                                if (errno == EAGAIN || errno == EINTR) {
                                        eDebug("retry!");