- add getLength() call to iStaticServiceInformation
authorFelix Domke <tmbinc@elitedvb.net>
Tue, 16 Aug 2005 01:02:55 +0000 (01:02 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Tue, 16 Aug 2005 01:02:55 +0000 (01:02 +0000)
 - implementation for dvb pvr streams using tstools
 - start of implementing status information for PVR

15 files changed:
lib/dvb/Makefile.am
lib/dvb/db.cpp
lib/dvb/decoder.cpp
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/idvb.h
lib/dvb/tstools.cpp
lib/dvb/tstools.h
lib/python/Components/MovieList.py
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicefs.cpp
lib/service/servicemp3.cpp
lib/service/servicemp3.h

index 797e54d..930a32e 100644 (file)
@@ -5,4 +5,4 @@ noinst_LIBRARIES = libenigma_dvb.a
 
 libenigma_dvb_a_SOURCES = dvb.cpp demux.cpp frontend.cpp esection.cpp db.cpp \
        sec.cpp scan.cpp crc32.cpp pmt.cpp decoder.cpp eit.cpp rotor_calc.cpp \
-       epgcache.cpp dvbtime.cpp metaparser.cpp volume.cpp
+       epgcache.cpp dvbtime.cpp metaparser.cpp volume.cpp tstools.cpp
index 92293b7..067b003 100644 (file)
@@ -33,6 +33,11 @@ RESULT eDVBService::getName(const eServiceReference &ref, std::string &name)
        return 0;
 }
 
+int eDVBService::getLength(const eServiceReference &ref)
+{
+       return -1;
+}
+
 int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query)
 {
        int res = 0;
index 5f528b8..b9cfcde 100644 (file)
@@ -293,11 +293,14 @@ int eTSMPEGDecoder::setState()
                if (m_pcr)
                        m_pcr->stop();
                m_pcr = 0;
-               m_pcr = new eDVBPCR(m_demux);
-               if (m_pcr->startPid(m_pcrpid))
+               if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
                {
-                       eWarning("video: startpid failed!");
-                       res = -1;
+                       m_pcr = new eDVBPCR(m_demux);
+                       if (m_pcr->startPid(m_pcrpid))
+                       {
+                               eWarning("video: startpid failed!");
+                               res = -1;
+                       }
                }
                m_changed &= ~changePCR;
        }
@@ -370,7 +373,7 @@ RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
                m_changed |= changePCR;
                m_pcrpid = pcrpid;
        }
-       return -1;
+       return 0;
 }
 
 RESULT eTSMPEGDecoder::setSyncMaster(int who)
index 4f5ecf2..cfb32d0 100644 (file)
@@ -517,10 +517,11 @@ RESULT eDVBChannel::playFile(const char *file)
                m_pvr_thread = 0;
        }
        
+       m_tstools.openFile(file);
+       
                /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
                   THEN DO A REAL FIX HERE! */
        
-       
                /* (this codepath needs to be improved anyway.) */
        m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
        if (m_pvr_fd_dst < 0)
@@ -536,10 +537,29 @@ RESULT eDVBChannel::playFile(const char *file)
                close(m_pvr_fd_dst);
                return -ENOENT;
        }
-
+       
        m_state = state_ok;
        m_stateChanged(this);
        
        m_pvr_thread = new eFilePushThread();
        m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
 }
+
+RESULT eDVBChannel::getLength(pts_t &len)
+{
+       return m_tstools.calcLen(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)
+               return r;
+       
+       // DMX_GET_STC 
+#endif
+       return 0;
+}
index d9f049e..d4c8eea 100644 (file)
@@ -4,6 +4,7 @@
 #include <lib/dvb/idvb.h>
 #include <lib/dvb/demux.h>
 #include <lib/dvb/frontend.h>
+#include <lib/dvb/tstools.h>
 #include <connection.h>
 
 class eDVBChannel;
@@ -171,6 +172,27 @@ class eFilePushThread;
 class eDVBChannel: public iDVBPVRChannel, public Object
 {
        DECLARE_REF(eDVBChannel);
+public:
+       eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux);
+       virtual ~eDVBChannel();
+
+               /* only for managed channels - effectively tunes to the channelid. should not be used... */
+               /* cannot be used for PVR channels. */
+       RESULT setChannel(const eDVBChannelID &id);
+       eDVBChannelID getChannelID() { return m_channel_id; }
+
+       RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection);
+       RESULT getState(int &state);
+
+       RESULT setCIRouting(const eDVBCIRouting &routing);
+       RESULT getDemux(ePtr<iDVBDemux> &demux);
+       RESULT getFrontend(ePtr<iDVBFrontend> &frontend);
+       
+               /* iDVBPVRChannel */
+       RESULT playFile(const char *file);
+       RESULT getLength(pts_t &len);
+       RESULT getCurrentPosition(pts_t &pos);
+
 private:
        ePtr<eDVBAllocatedFrontend> m_frontend;
        ePtr<eDVBAllocatedDemux> m_demux;
@@ -189,30 +211,13 @@ private:
                /* for PVR playback */
        eFilePushThread *m_pvr_thread;
        int m_pvr_fd_src, m_pvr_fd_dst;
+       eDVBTSTools m_tstools;
 
        friend class eUsePtr<eDVBChannel>;
                /* use count */
        oRefCount m_use_count;
        void AddUse();
        void ReleaseUse();
-public:
-       eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux);
-       virtual ~eDVBChannel();
-
-               /* only for managed channels - effectively tunes to the channelid. should not be used... */
-               /* cannot be used for PVR channels. */
-       RESULT setChannel(const eDVBChannelID &id);
-       eDVBChannelID getChannelID() { return m_channel_id; }
-
-       RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection);
-       RESULT getState(int &state);
-
-       RESULT setCIRouting(const eDVBCIRouting &routing);
-       RESULT getDemux(ePtr<iDVBDemux> &demux);
-       RESULT getFrontend(ePtr<iDVBFrontend> &frontend);
-       
-               /* iDVBPVRChannel */
-       RESULT playFile(const char *file);
 };
 
 #endif
index 1e6c61f..518525f 100644 (file)
@@ -192,6 +192,7 @@ public:
        
        // iStaticServiceInformation
        RESULT getName(const eServiceReference &ref, std::string &name);
+       int getLength(const eServiceReference &ref);
        
        // for filtering:
        int checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query);
@@ -444,6 +445,8 @@ public:
        virtual void ReleaseUse() = 0;
 };
 
+typedef unsigned long long pts_t;
+
 class iDVBPVRChannel: public iDVBChannel
 {
 public:
@@ -455,6 +458,11 @@ public:
                /* FIXME: there are some very ugly buffer-end and ... related problems */
                /* so this is VERY UGLY. */
        virtual RESULT playFile(const char *file) = 0;
+       
+       virtual RESULT getLength(pts_t &len) = 0;
+       virtual RESULT getCurrentPosition(pts_t &pos) = 0;
+       
+       // seekTo ...
 };
 
 class iDVBSectionReader;
index 5d1c7e3..8e74b4c 100644 (file)
@@ -48,8 +48,6 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts)
 {
        if (m_fd < 0)
                return -1;
-       if (m_pid < 0)
-               return -1;
 
        offset -= offset % 188;
        
@@ -82,8 +80,9 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts)
                
 //             printf("PID %04x, PUSI %d\n", pid, pusi);
                
-               if (pid != m_pid)
-                       continue;
+               if (m_pid >= 0)
+                       if (pid != m_pid)
+                               continue;
                if (!pusi)
                        continue;
                
index c6f2cbb..a50ab44 100644 (file)
@@ -8,10 +8,11 @@
  * thus we're not evaluating PES headers, not adaption fields.
  */
 
+typedef unsigned long long pts_t;
+
 class eDVBTSTools
 {
 public:
-       typedef unsigned long long pts_t;
        eDVBTSTools();
        ~eDVBTSTools();
 
@@ -38,5 +39,4 @@ private:
        off_t m_offset_begin, m_offset_end;
 };
 
-
 #endif
index 4144353..003302b 100644 (file)
@@ -34,10 +34,16 @@ def MovieListEntry(serviceref, serviceHandler):
                del info
                return
        
+       len = info.getLength(serviceref)
+       if len:
+               len = "%d:%02d" % (len / 60, len % 60)
+       else:
+               len = "?:??"
+       
        res.append((0, 0, 400, 30, 0, RT_HALIGN_LEFT, info.getName(serviceref)))
        res.append((0, 30, 200, 20, 1, RT_HALIGN_LEFT, "Toller Film"))
        res.append((0, 50, 200, 20, 1, RT_HALIGN_LEFT, "Aufgenommen: irgendwann"))
-       res.append((200, 50, 200, 20, 1, RT_HALIGN_RIGHT, "1232MB"))
+       res.append((200, 50, 200, 20, 1, RT_HALIGN_RIGHT, len))
        
        return res
 
index 7e24f9c..61695a9 100644 (file)
@@ -134,6 +134,8 @@ public:
        }
 };
 
+typedef unsigned long long pts_t;
+
        /* the reason we have the servicereference as additional argument is
           that we don't have to create one object for every entry in a possibly
           large list, provided that no state information is nessesary to deliver
@@ -143,6 +145,9 @@ class iStaticServiceInformation: public iObject
 {
 public:
        virtual RESULT getName(const eServiceReference &ref, std::string &name)=0;
+       
+               // doesn't need to be implemented, should return -1 then.
+       virtual int getLength(const eServiceReference &ref)=0;
 
                // FOR SWIG
        std::string getName(const eServiceReference &ref) { std::string temp; getName(ref, temp); return temp; }
index 5618477..955ceb0 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <lib/service/servicedvbrecord.h>
 #include <lib/dvb/metaparser.h>
+#include <lib/dvb/tstools.h>
 
 class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
 {
@@ -20,6 +21,7 @@ class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
 public:
        eStaticServiceDVBPVRInformation(const eServiceReference &ref);
        RESULT getName(const eServiceReference &ref, std::string &name);
+       int getLength(const eServiceReference &ref);
 };
 
 DEFINE_REF(eStaticServiceDVBPVRInformation);
@@ -36,6 +38,22 @@ RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, st
        name = m_parser.m_name.size() ? m_parser.m_name : ref.path;
 }
 
+int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
+{
+       ASSERT(ref == m_ref);
+       
+       eDVBTSTools tstools;
+       
+       if (tstools.openFile(ref.path.c_str()))
+               return 0;
+
+       pts_t len;
+       if (tstools.calcLen(len))
+               return 0;
+
+       return len / 90000;
+}
+
 DEFINE_REF(eServiceFactoryDVB)
 
 eServiceFactoryDVB::eServiceFactoryDVB()
@@ -185,6 +203,8 @@ RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServ
 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service): 
        m_reference(ref), m_dvb_service(service)
 {
+       m_is_pvr = !ref.path.empty();
+       
        CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
        CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
        eDebug("DVB start (play)");
@@ -285,7 +305,10 @@ void eDVBServicePlay::serviceEvent(int event)
                {
                        m_decoder->setVideoPID(vpid);
                        m_decoder->setAudioPID(apid, 0);
-                       m_decoder->setSyncPCR(pcrpid);
+                       if (m_is_pvr)
+                               m_decoder->setSyncPCR(pcrpid);
+                       else
+                               m_decoder->setSyncPCR(-1);
                        m_decoder->start();
 // how we can do this better?
 // update cache pid when the user changed the audio track or video track
index 5c75043..7844415 100644 (file)
@@ -57,6 +57,8 @@ private:
        
        void serviceEvent(int event);
        Signal2<void,iPlayableService*,int> m_event;
+       
+       int m_is_pvr;
 public:
        virtual ~eDVBServicePlay();
 
index b0d5392..67b99c0 100644 (file)
@@ -18,6 +18,7 @@ class eStaticServiceFSInformation: public iStaticServiceInformation
        DECLARE_REF(eStaticServiceFSInformation);
 public:
        RESULT getName(const eServiceReference &ref, std::string &name);
+       int getLength(const eServiceReference &ref) { return -1; }
 };
 
 DEFINE_REF(eStaticServiceFSInformation);
index 21c6cba..f550afc 100644 (file)
@@ -79,6 +79,11 @@ RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string
        return 0;
 }
 
+int eStaticServiceMP3Info::getLength(const eServiceReference &ref)
+{
+       return -1;
+}
+
 // eServiceMP3
 
 void eServiceMP3::test_end()
index 12ad770..d46f6bd 100644 (file)
@@ -29,6 +29,7 @@ class eStaticServiceMP3Info: public iStaticServiceInformation
        eStaticServiceMP3Info();
 public:
        RESULT getName(const eServiceReference &ref, std::string &name);
+       int getLength(const eServiceReference &ref);
 };
 
 class eServiceMP3: public iPlayableService, public iPauseableService, public iServiceInformation, public Object