add PES reader
authorFelix Domke <tmbinc@elitedvb.net>
Fri, 12 May 2006 15:37:35 +0000 (15:37 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Fri, 12 May 2006 15:37:35 +0000 (15:37 +0000)
lib/dvb/demux.cpp
lib/dvb/demux.h
lib/dvb/idemux.h
lib/dvb/idvb.h

index f277468..ca9736c 100644 (file)
@@ -108,6 +108,15 @@ RESULT eDVBDemux::createSectionReader(eMainloop *context, ePtr<iDVBSectionReader
        return res;
 }
 
+RESULT eDVBDemux::createPESReader(eMainloop *context, ePtr<iDVBPESReader> &reader)
+{
+       RESULT res;
+       reader = new eDVBPESReader(this, context, res);
+       if (res)
+               reader = 0;
+       return res;
+}
+
 RESULT eDVBDemux::createTSRecorder(ePtr<iDVBTSRecorder> &recorder)
 {
        if (m_dvr_busy)
@@ -282,6 +291,100 @@ RESULT eDVBSectionReader::connectRead(const Slot1<void,const __u8*> &r, ePtr<eCo
        return 0;
 }
 
+void eDVBPESReader::data(int)
+{
+       while (1)
+       {
+               __u8 data[4096];
+               int r;
+               r = ::read(m_fd, data, 4096);
+               if (!r)
+                       break;
+               if(r < 0)
+               {
+                       eWarning("ERROR reading section - %m\n");
+                       return;
+               }
+               if (m_active)
+                       m_read(data, r);
+       }
+}
+
+eDVBPESReader::eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res): m_demux(demux)
+{
+       char filename[128];
+       m_fd = m_demux->openDemux();
+       
+       if (m_fd >= 0)
+       {
+               m_notifier = new eSocketNotifier(context, m_fd, eSocketNotifier::Read, false);
+               CONNECT(m_notifier->activated, eDVBPESReader::data);
+               res = 0;
+       } else
+       {
+               perror(filename);
+               res = errno;
+       }
+}
+
+DEFINE_REF(eDVBPESReader)
+
+eDVBPESReader::~eDVBPESReader()
+{
+       if (m_notifier)
+               delete m_notifier;
+       if (m_fd >= 0)
+               ::close(m_fd);
+}
+
+RESULT eDVBPESReader::start(int pid)
+{
+       RESULT res;
+       if (m_fd < 0)
+               return -ENODEV;
+
+       m_notifier->start();
+
+#if HAVE_DVB_API_VERSION < 3
+       dmxPesFilterParams flt;
+       
+       flt.pesType = DMX_PES_OTHER;
+#else
+       dmx_pes_filter_params flt;
+       
+       flt.pes_type = DMX_PES_OTHER;
+#endif
+
+       flt.pid     = pid;
+       flt.input   = DMX_IN_FRONTEND;
+       flt.output  = DMX_OUT_TAP;
+       
+       flt.flags   = DMX_IMMEDIATE_START;
+
+       res = ::ioctl(m_fd, DMX_SET_PES_FILTER, &flt);
+       if (!res)
+               m_active = 1;
+       return res;
+}
+
+RESULT eDVBPESReader::stop()
+{
+       if (!m_active)
+               return -1;
+
+       m_active=0;
+       ::ioctl(m_fd, DMX_STOP);
+       m_notifier->stop();
+
+       return 0;
+}
+
+RESULT eDVBPESReader::connectRead(const Slot2<void,const __u8*,int> &r, ePtr<eConnection> &conn)
+{
+       conn = new eConnection(this, m_read.connect(r));
+       return 0;
+}
+
 class eDVBRecordFileThread: public eFilePushThread
 {
 public:
index b14dfd2..ee731ef 100644 (file)
@@ -18,6 +18,7 @@ public:
        RESULT setSourcePVR(int pvrnum);
        
        RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader);
+       RESULT createPESReader(eMainloop *context, ePtr<iDVBPESReader> &reader);
        RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder);
        RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader, int primary);
        RESULT getSTC(pts_t &pts, int num);
@@ -31,6 +32,7 @@ private:
        
        int m_dvr_busy;
        friend class eDVBSectionReader;
+       friend class eDVBPESReader;
        friend class eDVBAudio;
        friend class eDVBVideo;
        friend class eDVBPCR;
@@ -62,6 +64,24 @@ public:
        RESULT connectRead(const Slot1<void,const __u8*> &read, ePtr<eConnection> &conn);
 };
 
+class eDVBPESReader: public iDVBPESReader, public Object
+{
+       DECLARE_REF(eDVBPESReader);
+private:
+       int m_fd;
+       Signal2<void, const __u8*, int> m_read;
+       ePtr<eDVBDemux> m_demux;
+       int m_active;
+       void data(int);
+       eSocketNotifier *m_notifier;
+public:
+       eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res);
+       virtual ~eDVBPESReader();
+       RESULT start(int pid);
+       RESULT stop();
+       RESULT connectRead(const Slot2<void,const __u8*, int> &read, ePtr<eConnection> &conn);
+};
+
 class eDVBRecordFileThread;
 
 class eDVBTSRecorder: public iDVBTSRecorder, public Object
index 8511992..b04ad00 100644 (file)
@@ -53,6 +53,15 @@ public:
        virtual ~iDVBSectionReader() { };
 };
 
+class iDVBPESReader: public iObject
+{
+public:
+       virtual RESULT start(int pid)=0;
+       virtual RESULT stop()=0;
+       virtual RESULT connectRead(const Slot2<void,const __u8*, int> &read, ePtr<eConnection> &conn)=0;
+       virtual ~iDVBPESReader() { };
+};
+
        /* records a given set of pids into a file descriptor. */
        /* the FD must not be modified between start() and stop() ! */
 class iDVBTSRecorder: public iObject
index 0326c60..0608042 100644 (file)
@@ -552,6 +552,7 @@ public:
 };
 
 class iDVBSectionReader;
+class iDVBPESReader;
 class iDVBTSRecorder;
 class iTSMPEGDecoder;
 
@@ -559,6 +560,7 @@ class iDVBDemux: public iObject
 {
 public:
        virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
+       virtual RESULT createPESReader(eMainloop *context, ePtr<iDVBPESReader> &reader)=0;
        virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
        virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader, int primary=1)=0;
        virtual RESULT getSTC(pts_t &pts, int num=0)=0;