add - untested - multituner support
[enigma2.git] / lib / dvb / demux.cpp
index c3383a7ebd4b3989597c2cb507a68b0d513745e7..d2a2a545dc27a9f34c6ca66284c9a76b756bd815 100644 (file)
@@ -34,8 +34,35 @@ eDVBDemux::~eDVBDemux()
 {
 }
 
+int eDVBDemux::openDemux(void)
+{
+       char filename[128];
+#if HAVE_DVB_API_VERSION < 3
+       snprintf(filename, 128, "/dev/dvb/card%d/demux%d", adapter, demux);
+#else
+       snprintf(filename, 128, "/dev/dvb/adapter%d/demux%d", adapter, demux);
+#endif
+       return ::open(filename, O_RDWR);
+}
+
 DEFINE_REF(eDVBDemux)
 
+RESULT eDVBDemux::setSourceFrontend(int fenum)
+{
+       int fd = openDemux();
+       int res = ::ioctl(fd, DMX_SET_SOURCE, DMX_SOURCE_FRONT0 + fenum);
+       ::close(fd);
+       return res;
+}
+
+RESULT eDVBDemux::setSourcePVR(int pvrnum)
+{
+       int fd = openDemux();
+       int res = ::ioctl(fd, DMX_SET_SOURCE, DMX_SOURCE_DVR0 + pvrnum);
+       ::close(fd);
+       return res;
+}
+
 RESULT eDVBDemux::createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)
 {
        RESULT res;
@@ -59,6 +86,43 @@ RESULT eDVBDemux::getMPEGDecoder(ePtr<iTSMPEGDecoder> &decoder)
        return 0;
 }
 
+RESULT eDVBDemux::getSTC(pts_t &pts)
+{
+       int fd = openDemux();
+       
+       if (fd < 0)
+               return -ENODEV;
+
+       struct dmx_stc stc;
+       stc.num = 0;
+       stc.base = 1;
+       
+       if (ioctl(fd, DMX_GET_STC, &stc) < 0)
+       {
+               ::close(fd);
+               return -1;
+       }
+       
+       pts = stc.stc;
+       
+       ::close(fd);
+       return 0;
+}
+
+RESULT eDVBDemux::flush()
+{
+       // FIXME: implement flushing the PVR queue here.
+       
+       m_event(evtFlush);
+       return 0;
+}
+
+RESULT eDVBDemux::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &conn)
+{
+       conn = new eConnection(this, m_event.connect(event));
+       return 0;
+}
+
 void eDVBSectionReader::data(int)
 {
        __u8 data[4096]; // max. section size
@@ -74,7 +138,10 @@ void eDVBSectionReader::data(int)
                        // this check should never happen unless the driver is crappy!
                unsigned int c;
                if ((c = crc32((unsigned)-1, data, r)))
-                       eFatal("crc32 failed! is %x\n", c);
+               {
+                       eDebug("crc32 failed! is %x\n", c);
+                       return;
+               }
        }
        if (active)
                read(data);
@@ -85,18 +152,11 @@ void eDVBSectionReader::data(int)
 eDVBSectionReader::eDVBSectionReader(eDVBDemux *demux, eMainloop *context, RESULT &res): demux(demux)
 {
        char filename[128];
-#if HAVE_DVB_API_VERSION < 3
-       sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
-#else
-       sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
-#endif
-       fd = ::open(filename, O_RDWR);
-       
-       eDebug("eDVBSectionReader has fd %d", fd);
+       fd = demux->openDemux();
        
        if (fd >= 0)
        {
-               notifier=new eSocketNotifier(context, fd, eSocketNotifier::Read);
+               notifier=new eSocketNotifier(context, fd, eSocketNotifier::Read, false);
                CONNECT(notifier->activated, eDVBSectionReader::data);
                res = 0;
        } else
@@ -122,6 +182,7 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask)
        if (fd < 0)
                return -ENODEV;
 
+       notifier->start();
 #if HAVE_DVB_API_VERSION < 3
        dmxSctFilterParams sct;
 #else
@@ -145,6 +206,8 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask)
        memcpy(sct.filter.mask, mask.mask, DMX_FILTER_SIZE);
 #if HAVE_DVB_API_VERSION >= 3
        memcpy(sct.filter.mode, mask.mode, DMX_FILTER_SIZE);
+       if (::ioctl(fd, DMX_SET_BUFFER_SIZE, 8192*8) < 0)
+               eDebug("DMX_SET_BUFFER_SIZE failed(%m)");
 #endif
        
        res = ::ioctl(fd, DMX_SET_FILTER, &sct);
@@ -172,7 +235,8 @@ RESULT eDVBSectionReader::stop()
 
        active=0;
        ::ioctl(fd, DMX_STOP);
-       
+       notifier->stop();
+
        return 0;
 }
 
@@ -295,16 +359,10 @@ RESULT eDVBTSRecorder::connectEvent(const Slot1<void,int> &event, ePtr<eConnecti
 
 RESULT eDVBTSRecorder::startPID(int pid)
 {
-       char filename[128];
-#if HAVE_DVB_API_VERSION < 3
-       snprintf(filename, 128, "/dev/dvb/card%d/demux%d", m_demux->adapter, m_demux->demux);
-#else
-       snprintf(filename, 128, "/dev/dvb/adapter%d/demux%d", m_demux->adapter, m_demux->demux);
-#endif
-       int fd = ::open(filename, O_RDWR);
+       int fd = m_demux->openDemux();
        if (fd < 0)
        {
-               eDebug("FAILED to open demux (%s) in ts recoder (%m)", filename);
+               eDebug("FAILED to open demux in ts recoder (%m)");
                return -1;
        }