aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/dvb/Makefile.am2
-rw-r--r--lib/dvb/db.cpp5
-rw-r--r--lib/dvb/decoder.cpp13
-rw-r--r--lib/dvb/dvb.cpp24
-rw-r--r--lib/dvb/dvb.h41
-rw-r--r--lib/dvb/idvb.h8
-rw-r--r--lib/dvb/tstools.cpp7
-rw-r--r--lib/dvb/tstools.h4
-rw-r--r--lib/python/Components/MovieList.py8
-rw-r--r--lib/service/iservice.h5
-rw-r--r--lib/service/servicedvb.cpp25
-rw-r--r--lib/service/servicedvb.h2
-rw-r--r--lib/service/servicefs.cpp1
-rw-r--r--lib/service/servicemp3.cpp5
-rw-r--r--lib/service/servicemp3.h1
15 files changed, 117 insertions, 34 deletions
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 <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
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 <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
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<void,iPlayableService*,int> 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