- add iSeekableService, implement it for serviceDvb
authorFelix Domke <tmbinc@elitedvb.net>
Wed, 17 Aug 2005 02:16:32 +0000 (02:16 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Wed, 17 Aug 2005 02:16:32 +0000 (02:16 +0000)
12 files changed:
lib/dvb/demux.cpp
lib/dvb/demux.h
lib/dvb/dvb.cpp
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/dvb/tstools.h
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.cpp
lib/service/servicemp3.h

index bdd8e67df329f1a09625b32de93302f7abbaa0e3..3e05065be6565d8de2c76ffa2314f66a1074f14b 100644 (file)
@@ -59,6 +59,38 @@ RESULT eDVBDemux::getMPEGDecoder(ePtr<iTSMPEGDecoder> &decoder)
        return 0;
 }
 
+RESULT eDVBDemux::getSTC(pts_t &pts)
+{
+       char filename[128];
+#if HAVE_DVB_API_VERSION < 3
+       sprintf(filename, "/dev/dvb/card%d/demux%d", adapter, demux);
+#else
+       sprintf(filename, "/dev/dvb/adapter%d/demux%d", adapter, demux);
+#endif
+       int fd = ::open(filename, O_RDWR);
+       
+       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;
+       eDebug("got demux stc: %08llx", pts);
+       
+       ::close(fd);
+       
+       return 0;
+}
+
+
 void eDVBSectionReader::data(int)
 {
        __u8 data[4096]; // max. section size
index fdec41771bfb9c396ae5a779eaf455c64d57df50..23aef0f35b93bc52e9ef1e4080976ec0eec8767a 100644 (file)
@@ -21,6 +21,7 @@ public:
        RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader);
        RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder);
        RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader);
+       RESULT getSTC(pts_t &pts);
 };
 
 class eDVBSectionReader: public iDVBSectionReader, public Object
index cfb32d09e7f771a2cf57bc81d25f53c439924237..3e4c7bdc8ea4fc53c47e8ff020d0baac7fd3c4fc 100644 (file)
@@ -552,14 +552,39 @@ RESULT eDVBChannel::getLength(pts_t &len)
 
 RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
 {
-#if 0
        off_t begin = 0;
                /* getPTS for offset 0 is cached, so it doesn't harm. */
        int r = m_tstools.getPTS(begin, pos);
        if (r)
+       {
+               eDebug("tstools getpts(0) failed!");
                return r;
+       }
+       
+       pts_t now;
+       
+       r = m_demux->get().getSTC(now);
+
+       if (r)
+       {
+               eDebug("demux getSTC failed");
+               return -1;
+       }
+       
+       eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
+       
+               /* when we are less than 10 seconds before the start, return 0. */
+               /* (we're just waiting for the timespam to start) */
+       if ((now < pos) && ((pos - now) < 90000 * 10))
+       {
+               pos = 0;
+               return 0;
+       }
+       
+       if (now < pos) /* wrap around */
+               pos = now + ((pts_t)1)<<33 - pos;
+       else
+               pos = now - pos;
        
-       // DMX_GET_STC 
-#endif
        return 0;
 }
index 518525f9e09c253755eb65594c1fcf12b1255dcb..683a7b714b049a860b1008708a4ded949e1b8184 100644 (file)
@@ -459,7 +459,7 @@ public:
                /* so this is VERY UGLY. */
        virtual RESULT playFile(const char *file) = 0;
        
-       virtual RESULT getLength(pts_t &len) = 0;
+       virtual RESULT getLength(pts_t &pts) = 0;
        virtual RESULT getCurrentPosition(pts_t &pos) = 0;
        
        // seekTo ...
@@ -475,6 +475,7 @@ public:
        virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
        virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
        virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader)=0;
+       virtual RESULT getSTC(pts_t &pts)=0;
 };
 
 class iTSMPEGDecoder: public iObject
index 541a248c2e2feee0bcd6f30a538c7071ea1121d4..e62de9b8a8d16c7b70c8f39e8b137eeacea71324 100644 (file)
@@ -168,6 +168,15 @@ int eDVBServicePMTHandler::getDemux(ePtr<iDVBDemux> &demux)
                return -1;
 }
 
+int eDVBServicePMTHandler::getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel)
+{
+       pvr_channel = m_pvr_channel;
+       if (pvr_channel)
+               return 0;
+       else
+               return -1;
+}
+
 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
 {
        RESULT res;
index 9d35aa4c849d912f1fc9d27e387d207924ba6a80..efe54ee78b27a970c429610306ad3f65771b25ac 100644 (file)
@@ -66,6 +66,7 @@ public:
        
        int getProgramInfo(struct program &program);
        int getDemux(ePtr<iDVBDemux> &demux);
+       int getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel);
        
        int tune(eServiceReferenceDVB &ref);    
 };
index a50ab4419a05c3b040a3cb96ebb794c4dbf819f0..4ec4b66aa9902dfbac9e09d9e759e858f5349e0c 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __lib_dvb_tstools_h
 #define __lib_dvb_tstools_h
 
+#include <config.h>
 #include <sys/types.h>
 
 /*
index 61695a91e61a25eb43855a82fd25cdfda2cc788c..4a19378c5dba74fe9d82d39b73f15f563bac22f6 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __lib_dvb_iservice_h
 #define __lib_dvb_iservice_h
 
+#include <lib/python/swig.h>
 #include <lib/base/object.h>
 #include <string>
 #include <connection.h>
@@ -177,6 +178,16 @@ public:
 
 TEMPLATE_TYPEDEF(ePtr<iPauseableService>, iPauseableServicePtr);
 
+class iSeekableService: public iObject
+{
+public:
+       virtual RESULT getLength(pts_t &SWIG_OUTPUT)=0;
+       virtual RESULT seekTo(pts_t to)=0;
+       virtual RESULT getPlayPosition(pts_t &SWIG_OUTPUT)=0;
+};
+
+TEMPLATE_TYPEDEF(ePtr<iSeekableService>, iSeekableServicePtr);
+
 class iPlayableService: public iObject
 {
        friend class iServiceHandler;
@@ -192,6 +203,7 @@ public:
        virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
        virtual RESULT start()=0;
        virtual RESULT stop()=0;
+       virtual RESULT seek(ePtr<iSeekableService> &ptr)=0;
        virtual RESULT pause(ePtr<iPauseableService> &ptr)=0;
        virtual RESULT info(ePtr<iServiceInformation> &ptr)=0;
 };
index 955ceb0a9a20f5e7a6b6df72a2e5496b5c95eec3..ac22456229126dde7fd208effbdd834217adb048 100644 (file)
@@ -313,9 +313,14 @@ void eDVBServicePlay::serviceEvent(int event)
 // how we can do this better?
 // update cache pid when the user changed the audio track or video track
 // TODO handling of difference audio types.. default audio types..
-                       m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
-                       m_dvb_service->setCachePID(eDVBService::cAPID, apid);
-                       m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
+                               
+                               /* don't worry about non-existing services, nor pvr services */
+                       if (m_dvb_service && !m_is_pvr)
+                       {
+                               m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
+                               m_dvb_service->setCachePID(eDVBService::cAPID, apid);
+                               m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
+                       }
                }
                
                break;
@@ -325,9 +330,10 @@ void eDVBServicePlay::serviceEvent(int event)
 
 RESULT eDVBServicePlay::start()
 {
+       int r;
        eDebug("starting DVB service");
+       r = m_service_handler.tune((eServiceReferenceDVB&)m_reference);
        m_event(this, evStart);
-       return m_service_handler.tune((eServiceReferenceDVB&)m_reference);
 }
 
 RESULT eDVBServicePlay::stop()
@@ -349,6 +355,46 @@ RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
        return -1;
 }
 
+RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
+{
+       if (m_is_pvr)
+       {
+               ptr = this;
+               return 0;
+       }
+       
+       ptr = 0;
+       return -1;
+}
+
+RESULT eDVBServicePlay::getLength(pts_t &len)
+{
+       ePtr<iDVBPVRChannel> pvr_channel;
+       
+       if (m_service_handler.getPVRChannel(pvr_channel))
+       {
+               eDebug("getPVRChannel failed!");
+               return -1;
+       }
+       
+       return pvr_channel->getLength(len);
+}
+
+RESULT eDVBServicePlay::seekTo(pts_t to)
+{
+       return -1;
+}
+
+RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
+{
+       ePtr<iDVBPVRChannel> pvr_channel;
+       
+       if (m_service_handler.getPVRChannel(pvr_channel))
+               return -1;
+       
+       return pvr_channel->getCurrentPosition(pos);
+}
+
 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
 {
        ptr = this;
index 78444158d94a6c688db9557fd8668d1dbf804b05..1dd66e4046a3e5989baf0bc8e78dbfbfc260a3c6 100644 (file)
@@ -37,7 +37,7 @@ public:
        RESULT getNext(eServiceReference &ptr);
 };
 
-class eDVBServicePlay: public iPlayableService, public Object, public iServiceInformation
+class eDVBServicePlay: public iPlayableService, iSeekableService, public Object, public iServiceInformation
 {
 DECLARE_REF(eDVBServicePlay);
 private:
@@ -66,9 +66,15 @@ public:
        RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection);
        RESULT start();
        RESULT stop();
+       RESULT seek(ePtr<iSeekableService> &ptr);
        RESULT pause(ePtr<iPauseableService> &ptr);
        RESULT info(ePtr<iServiceInformation> &ptr);
        
+               // iSeekableService
+       RESULT getLength(pts_t &len);
+       RESULT seekTo(pts_t to);
+       RESULT getPlayPosition(pts_t &pos);
+
                // iServiceInformation
        RESULT getName(std::string &name);
        RESULT getEvent(ePtr<eServiceEvent> &evt, int nownext);
index f550afc0a0072e7359e338e70a34872445c1e146..549a288ad3dc378b6d31e9a6b8dfb7c09ec2e6c6 100644 (file)
@@ -140,6 +140,7 @@ RESULT eServiceMP3::stop()
 }
 
 RESULT eServiceMP3::pause(ePtr<iPauseableService> &ptr) { ptr=this; return 0; }
+RESULT eServiceMP3::seek(ePtr<iSeekableService> &ptr) { ptr = 0; return -1; }
 
                // iPausableService
 RESULT eServiceMP3::pause() { printf("mp3 pauses!\n"); return 0; }
index d46f6bd7f99757c9ff29c3549ee65d383305f410..92117857815b9b5be8c02322d5f6d998dcd89252 100644 (file)
@@ -55,6 +55,7 @@ public:
        RESULT start();
        RESULT stop();
        RESULT pause(ePtr<iPauseableService> &ptr);
+       RESULT seek(ePtr<iSeekableService> &ptr);
 
                // iPausableService
        RESULT pause();