From: Felix Domke Date: Tue, 16 Aug 2005 01:02:55 +0000 (+0000) Subject: - add getLength() call to iStaticServiceInformation X-Git-Tag: 2.6.0~5750 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/fe813cde98c0c550137b47dd7a75ec2d4d9e6f34 - add getLength() call to iStaticServiceInformation - implementation for dvb pvr streams using tstools - start of implementing status information for PVR --- diff --git a/lib/dvb/Makefile.am b/lib/dvb/Makefile.am index 797e54d4..930a32e6 100644 --- a/lib/dvb/Makefile.am +++ b/lib/dvb/Makefile.am @@ -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 diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 92293b7e..067b0032 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -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; diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 5f528b82..b9cfcded 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -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) diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 4f5ecf2e..cfb32d09 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -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; +} diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index d9f049eb..d4c8eea0 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -4,6 +4,7 @@ #include #include #include +#include #include 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 &stateChange, ePtr &connection); + RESULT getState(int &state); + + RESULT setCIRouting(const eDVBCIRouting &routing); + RESULT getDemux(ePtr &demux); + RESULT getFrontend(ePtr &frontend); + + /* iDVBPVRChannel */ + RESULT playFile(const char *file); + RESULT getLength(pts_t &len); + RESULT getCurrentPosition(pts_t &pos); + private: ePtr m_frontend; ePtr 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; /* 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 &stateChange, ePtr &connection); - RESULT getState(int &state); - - RESULT setCIRouting(const eDVBCIRouting &routing); - RESULT getDemux(ePtr &demux); - RESULT getFrontend(ePtr &frontend); - - /* iDVBPVRChannel */ - RESULT playFile(const char *file); }; #endif diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 1e6c61f5..518525f9 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -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; diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp index 5d1c7e35..8e74b4c7 100644 --- a/lib/dvb/tstools.cpp +++ b/lib/dvb/tstools.cpp @@ -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; diff --git a/lib/dvb/tstools.h b/lib/dvb/tstools.h index c6f2cbbc..a50ab441 100644 --- a/lib/dvb/tstools.h +++ b/lib/dvb/tstools.h @@ -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 diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index 4144353e..003302b3 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -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 diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 7e24f9c1..61695a91 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -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; } diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 5618477c..955ceb0a 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -11,6 +11,7 @@ #include #include +#include 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 &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 diff --git a/lib/service/servicedvb.h b/lib/service/servicedvb.h index 5c750430..78444158 100644 --- a/lib/service/servicedvb.h +++ b/lib/service/servicedvb.h @@ -57,6 +57,8 @@ private: void serviceEvent(int event); Signal2 m_event; + + int m_is_pvr; public: virtual ~eDVBServicePlay(); diff --git a/lib/service/servicefs.cpp b/lib/service/servicefs.cpp index b0d53922..67b99c08 100644 --- a/lib/service/servicefs.cpp +++ b/lib/service/servicefs.cpp @@ -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); diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 21c6cba0..f550afc0 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -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() diff --git a/lib/service/servicemp3.h b/lib/service/servicemp3.h index 12ad7706..d46f6bd7 100644 --- a/lib/service/servicemp3.h +++ b/lib/service/servicemp3.h @@ -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