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
return 0;
}
+int eDVBService::getLength(const eServiceReference &ref)
+{
+ return -1;
+}
+
int eDVBService::checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query)
{
int res = 0;
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;
}
m_changed |= changePCR;
m_pcrpid = pcrpid;
}
- return -1;
+ return 0;
}
RESULT eTSMPEGDecoder::setSyncMaster(int who)
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)
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;
+}
#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;
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;
/* 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
// iStaticServiceInformation
RESULT getName(const eServiceReference &ref, std::string &name);
+ int getLength(const eServiceReference &ref);
// for filtering:
int checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query);
virtual void ReleaseUse() = 0;
};
+typedef unsigned long long pts_t;
+
class iDVBPVRChannel: public iDVBChannel
{
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;
{
if (m_fd < 0)
return -1;
- if (m_pid < 0)
- return -1;
offset -= offset % 188;
// 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;
* 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();
off_t m_offset_begin, m_offset_end;
};
-
#endif
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
}
};
+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
{
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; }
#include <lib/service/servicedvbrecord.h>
#include <lib/dvb/metaparser.h>
+#include <lib/dvb/tstools.h>
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);
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()
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)");
{
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
void serviceEvent(int event);
Signal2<void,iPlayableService*,int> m_event;
+
+ int m_is_pvr;
public:
virtual ~eDVBServicePlay();
DECLARE_REF(eStaticServiceFSInformation);
public:
RESULT getName(const eServiceReference &ref, std::string &name);
+ int getLength(const eServiceReference &ref) { return -1; }
};
DEFINE_REF(eStaticServiceFSInformation);
return 0;
}
+int eStaticServiceMP3Info::getLength(const eServiceReference &ref)
+{
+ return -1;
+}
+
// eServiceMP3
void eServiceMP3::test_end()
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