- add prelim. pvr playback.
authorFelix Domke <tmbinc@elitedvb.net>
Thu, 28 Jul 2005 01:50:44 +0000 (01:50 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Thu, 28 Jul 2005 01:50:44 +0000 (01:50 +0000)
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h

index ea51d6a..d98aa2a 100644 (file)
@@ -1,12 +1,14 @@
-#include <lib/dvb/idvb.h>
 #include <lib/base/eerror.h>
+#include <lib/base/filepush.h>
+#include <lib/dvb/idvb.h>
 #include <lib/dvb/dvb.h>
 #include <lib/dvb/sec.h>
-#include <errno.h>
 
+#include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 DEFINE_REF(eDVBRegisteredFrontend);
 DEFINE_REF(eDVBRegisteredDemux);
@@ -214,9 +216,9 @@ RESULT eDVBResourceManager::allocateFrontend(const eDVBChannelID &chid, ePtr<eDV
 
 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux)
 {
-               /* find first unused demux which is on same adapter as frontend */
+               /* find first unused demux which is on same adapter as frontend (or any, if PVR) */
        for (eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin()); i != m_demux.end(); ++i)
-               if ((!i->m_inuse) && (i->m_adapter == fe->m_adapter))
+               if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
                {
                        demux = new eDVBAllocatedDemux(i);
                        return 0;
@@ -312,9 +314,19 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel)
        return 0;
 }
 
-RESULT eDVBResourceManager::allocatePVRChannel(int caps)
+
+RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
 {
-       return -1; // will nicht, mag nicht, und das interface ist auch kaputt
+       ePtr<eDVBAllocatedDemux> demux;
+       
+       if (allocateDemux(0, demux))
+               return errNoDemux;
+       
+       eDVBChannel *ch;
+       ch = new eDVBChannel(this, 0, demux);
+       
+       channel = ch;
+       return 0;
 }
 
 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
@@ -355,6 +367,8 @@ eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *fronte
 {
        m_frontend = frontend;
        m_demux = demux;
+
+       m_pvr_thread = 0;
        
        if (m_frontend)
                m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
@@ -364,6 +378,12 @@ eDVBChannel::~eDVBChannel()
 {
        if (m_channel_id)
                m_mgr->removeChannel(this);
+       
+       if (m_pvr_thread)
+       {
+               m_pvr_thread->stop();
+               delete m_pvr_thread;
+       }
 }
 
 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
@@ -484,3 +504,40 @@ RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
        else
                return -ENODEV;
 }
+
+RESULT eDVBChannel::playFile(const char *file)
+{
+       ASSERT(!m_frontend);
+       if (m_pvr_thread)
+       {
+               m_pvr_thread->stop();
+               delete m_pvr_thread;
+               m_pvr_thread = 0;
+       }
+       
+               /* 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.) */
+       int dest = open("/dev/misc/pvr", O_WRONLY);
+       if (dest < 0)
+       {
+               eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)");
+               return -ENODEV;
+       }
+       
+       int source = open(file, O_RDONLY);
+       if (source < 0)
+       {
+               eDebug("can't open PVR source file %s (%m)", file);
+               close(dest);
+               return -ENOENT;
+       }
+
+       m_state = state_ok;
+       m_stateChanged(this);
+       
+       m_pvr_thread = new eFilePushThread();
+       m_pvr_thread->start(source, dest);
+}
index d0deb2f..0e1c8af 100644 (file)
@@ -158,14 +158,17 @@ public:
                /* allocate channel... */
        RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel);
        RESULT allocateRawChannel(eUsePtr<iDVBChannel> &channel);
-       RESULT allocatePVRChannel(int caps);
+       RESULT allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel);
 
        RESULT connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection);
        RESULT connectChannelRemoved(const Slot1<void,eDVBChannel*> &channelRemoved, ePtr<eConnection> &connection);
        RESULT connectChannelRunning(const Slot1<void,iDVBChannel*> &channelRemoved, ePtr<eConnection> &connection);
 };
 
-class eDVBChannel: public iDVBChannel, public Object
+class eFilePushThread;
+
+       /* iDVBPVRChannel includes iDVBChannel. don't panic. */
+class eDVBChannel: public iDVBPVRChannel, public Object
 {
        DECLARE_REF(eDVBChannel);
 private:
@@ -182,6 +185,9 @@ private:
        
        void frontendStateChanged(iDVBFrontend*fe);
        ePtr<eConnection> m_conn_frontendStateChanged;
+       
+               /* for PVR playback */
+       eFilePushThread *m_pvr_thread;
 
        friend class eUsePtr<eDVBChannel>;
                /* use count */
@@ -193,6 +199,7 @@ public:
        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; }
 
@@ -202,6 +209,9 @@ public:
        RESULT setCIRouting(const eDVBCIRouting &routing);
        RESULT getDemux(ePtr<iDVBDemux> &demux);
        RESULT getFrontend(ePtr<iDVBFrontend> &frontend);
+       
+               /* iDVBPVRChannel */
+       RESULT playFile(const char *file);
 };
 
 #endif
index 882e9b1..d338f29 100644 (file)
@@ -435,6 +435,19 @@ public:
        virtual void ReleaseUse() = 0;
 };
 
+class iDVBPVRChannel: public iDVBChannel
+{
+public:
+       enum
+       {
+               state_eof = state_release + 1  /* end-of-file reached. */
+       };
+       
+               /* FIXME: there are some very ugly buffer-end and ... related problems */
+               /* so this is VERY UGLY. */
+       virtual RESULT playFile(const char *file) = 0;
+};
+
 class iDVBSectionReader;
 class iDVBTSRecorder;
 class iTSMPEGDecoder;
index c1ac5dd..7b24b43 100644 (file)
@@ -131,13 +131,26 @@ int eDVBServicePMTHandler::getDemux(ePtr<iDVBDemux> &demux)
 int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
 {
        RESULT res;
-       m_channel = 0;
-       m_channelStateChanged_connection = 0;
        m_reference = ref;
-       eDVBChannelID chid;
-       ref.getChannelID(chid);
-       res = m_resourceManager->allocateChannel(chid, m_channel);
-       eDebug("eDVBServicePMTHandler: tune %d", res);
+       
+//     ref.path = "/viva.ts"; // hrhr.
+       
+               /* is this a normal (non PVR) channel? */
+       if (ref.path.empty())
+       {
+               eDVBChannelID chid;
+               ref.getChannelID(chid);
+               res = m_resourceManager->allocateChannel(chid, m_channel);
+       } else
+       {
+               eDebug("alloc PVR");
+                       /* allocate PVR */
+               res = m_resourceManager->allocatePVRChannel(m_pvr_channel);
+               if (res)
+                       eDebug("allocatePVRChannel failed!\n");
+               m_channel = m_pvr_channel;
+       }
+       
        if (m_channel)
        {
                m_channel->connectStateChange(
@@ -146,5 +159,9 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
                m_last_channel_state = -1;
                channelStateChanged(m_channel);
        }
+       
+       if (m_pvr_channel)
+               m_pvr_channel->playFile(ref.path.c_str());
+       
        return res;
 }
index d86d1ac..d8ea062 100644 (file)
@@ -19,6 +19,7 @@ class eDVBServicePMTHandler: public Object
        eAUTable<eTable<ProgramAssociationTable> > m_PAT;
 
        eUsePtr<iDVBChannel> m_channel;
+       eUsePtr<iDVBPVRChannel> m_pvr_channel;
        ePtr<eDVBResourceManager> m_resourceManager;
        ePtr<iDVBDemux> m_demux;