add demux handling (for decoder and record)
authorFelix Domke <tmbinc@elitedvb.net>
Sat, 15 Oct 2005 20:33:40 +0000 (20:33 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Sat, 15 Oct 2005 20:33:40 +0000 (20:33 +0000)
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/dvbtime.cpp
lib/dvb/epgcache.cpp
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h

index 90df726..c8feccf 100644 (file)
@@ -214,15 +214,29 @@ RESULT eDVBResourceManager::allocateFrontend(const eDVBChannelID &chid, ePtr<eDV
        return -1;
 }
 
-RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux)
+RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
 {
-               /* 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)
+               /* find first unused demux which is on same adapter as frontend (or any, if PVR)
+                  never use the first one unless we need a decoding demux. */
+
+       eDebug("allocate demux");
+       eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
+       
+       if (i == m_demux.end())
+               return -1;
+               
+               /* FIXME: hardware demux policy */
+       if (!(cap & iDVBChannel::capDecode))
+               ++i;
+       
+       for (; i != m_demux.end(); ++i)
                if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
                {
                        demux = new eDVBAllocatedDemux(i);
+                       eDebug("demux found");
                        return 0;
                }
+       eDebug("demux not found");
        return -1;
 }
 
@@ -267,14 +281,15 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse
        if (allocateFrontend(channelid, fe))
                return errNoFrontend;
        
-       ePtr<eDVBAllocatedDemux> demux;
-       
-       if (allocateDemux(*fe, demux))
-               return errNoDemux;
+// will be allocated on demand:
+//     ePtr<eDVBAllocatedDemux> demux;
+//     
+//     if (allocateDemux(*fe, demux))
+//             return errNoDemux;
        
        RESULT res;
        eDVBChannel *ch;
-       ch = new eDVBChannel(this, fe, demux);
+       ch = new eDVBChannel(this, fe);
 
        ePtr<iDVBFrontend> myfe;
        if (!ch->getFrontend(myfe))
@@ -298,13 +313,13 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel)
        if (allocateFrontend(eDVBChannelID(), fe))
                return errNoFrontend;
        
-       ePtr<eDVBAllocatedDemux> demux;
-       
-       if (allocateDemux(*fe, demux))
-               return errNoDemux;
+//     ePtr<eDVBAllocatedDemux> demux;
+       //
+//     if (allocateDemux(*fe, demux))
+//             return errNoDemux;
        
        eDVBChannel *ch;
-       ch = new eDVBChannel(this, fe, demux);
+       ch = new eDVBChannel(this, fe);
 
        ePtr<iDVBFrontend> myfe;
        if (!ch->getFrontend(myfe))
@@ -319,11 +334,11 @@ RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
 {
        ePtr<eDVBAllocatedDemux> demux;
        
-       if (allocateDemux(0, demux))
-               return errNoDemux;
+//     if (allocateDemux(0, demux))
+//             return errNoDemux;
        
        eDVBChannel *ch;
-       ch = new eDVBChannel(this, 0, demux);
+       ch = new eDVBChannel(this, 0);
        
        channel = ch;
        return 0;
@@ -363,10 +378,9 @@ RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &
 
 DEFINE_REF(eDVBChannel);
 
-eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux): m_state(state_idle), m_mgr(mgr)
+eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
 {
        m_frontend = frontend;
-       m_demux = demux;
 
        m_pvr_thread = 0;
        
@@ -492,9 +506,19 @@ RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
        return -1;
 }
 
-RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux)
+RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
 {
-       demux = &m_demux->get();
+       ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
+       
+       if (!our_demux)
+       {
+               demux = 0;
+               
+               if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
+                       return 0;
+       }
+       
+       demux = *our_demux;
        return 0;
 }
 
@@ -543,6 +567,8 @@ RESULT eDVBChannel::playFile(const char *file)
        
        m_pvr_thread = new eFilePushThread();
        m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
+
+       return 0;
 }
 
 RESULT eDVBChannel::getLength(pts_t &len)
@@ -552,6 +578,9 @@ RESULT eDVBChannel::getLength(pts_t &len)
 
 RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
 {
+       if (!m_decoder_demux)
+               return -1;
+       
        off_t begin = 0;
                /* getPTS for offset 0 is cached, so it doesn't harm. */
        int r = m_tstools.getPTS(begin, pos);
@@ -563,7 +592,7 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
        
        pts_t now;
        
-       r = m_demux->get().getSTC(now);
+       r = m_decoder_demux->get().getSTC(now);
 
        if (r)
        {
index d4c8eea..9a85c22 100644 (file)
@@ -117,7 +117,7 @@ class eDVBResourceManager: public iObject
        RESULT allocateFrontend(const eDVBChannelID &chid, ePtr<eDVBAllocatedFrontend> &fe);
        
                        /* allocate a demux able to filter on the selected frontend. */
-       RESULT allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux);
+       RESULT allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap);
        
        struct active_channel
        {
@@ -173,7 +173,7 @@ class eDVBChannel: public iDVBPVRChannel, public Object
 {
        DECLARE_REF(eDVBChannel);
 public:
-       eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend, eDVBAllocatedDemux *demux);
+       eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend);
        virtual ~eDVBChannel();
 
                /* only for managed channels - effectively tunes to the channelid. should not be used... */
@@ -185,7 +185,7 @@ public:
        RESULT getState(int &state);
 
        RESULT setCIRouting(const eDVBCIRouting &routing);
-       RESULT getDemux(ePtr<iDVBDemux> &demux);
+       RESULT getDemux(ePtr<iDVBDemux> &demux, int cap);
        RESULT getFrontend(ePtr<iDVBFrontend> &frontend);
        
                /* iDVBPVRChannel */
@@ -195,7 +195,7 @@ public:
 
 private:
        ePtr<eDVBAllocatedFrontend> m_frontend;
-       ePtr<eDVBAllocatedDemux> m_demux;
+       ePtr<eDVBAllocatedDemux> m_demux, m_decoder_demux;
        
        ePtr<iDVBFrontendParameters> m_current_frontend_parameters;
        eDVBChannelID m_channel_id;
index 82ceffd..bfc2c87 100644 (file)
@@ -68,7 +68,7 @@ TDT::TDT(eDVBChannel *chan)
        CONNECT(tableReady, TDT::ready);
        CONNECT(m_interval_timer.timeout, TDT::start);
        if (chan)
-               chan->getDemux(demux);
+               chan->getDemux(demux, 0);
 }
 
 void TDT::ready(int error)
index c22bf89..1ec88a3 100644 (file)
@@ -231,7 +231,7 @@ void eEPGCache::DVBChannelRunning(iDVBChannel *chan)
                else
                {
                        ePtr<iDVBDemux> demux;
-                       if ( data.channel->getDemux(demux) )
+                       if ( data.channel->getDemux(demux, 0) )
                        {
                                eDebug("[eEPGCache] no demux!!");
                                return;
index d94bf5f..764c455 100644 (file)
@@ -434,13 +434,15 @@ public:
        };
        virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
        virtual RESULT getState(int &state)=0;
+       
+               /* demux capabilities */
        enum
        {
-               cap_decode,
-               cap_ci
+               capDecode = 1,
+               /* capCI = 2 */
        };
        virtual RESULT setCIRouting(const eDVBCIRouting &routing)=0;
-       virtual RESULT getDemux(ePtr<iDVBDemux> &demux)=0;
+       virtual RESULT getDemux(ePtr<iDVBDemux> &demux, int cap=0)=0;
        
                /* direct frontend access for raw channels and/or status inquiries. */
        virtual RESULT getFrontend(ePtr<iDVBFrontend> &frontend)=0;
index a5bd970..68b1f6c 100644 (file)
@@ -5,9 +5,10 @@
 #include <lib/dvb/metaparser.h>
 #include <dvbsi++/ca_program_map_section.h>
 
-eDVBServicePMTHandler::eDVBServicePMTHandler()
+eDVBServicePMTHandler::eDVBServicePMTHandler(int record)
        :m_pmt_pid(0xFFFF), m_ca_servicePtr(0)
 {
+       m_record = record;
        eDVBResourceManager::getInstance(m_resourceManager);
        CONNECT(m_PMT.tableReady, eDVBServicePMTHandler::PMTready);
        CONNECT(m_PAT.tableReady, eDVBServicePMTHandler::PATready);
@@ -27,8 +28,8 @@ void eDVBServicePMTHandler::channelStateChanged(iDVBChannel *channel)
                && (state == iDVBChannel::state_ok) && (!m_demux))
        {
                if (m_channel)
-                       if (m_channel->getDemux(m_demux))
-                               eDebug("shit it failed.. again.");
+                       if (m_channel->getDemux(m_demux, m_record ? 0 : iDVBChannel::capDecode))
+                               eDebug("Allocating a demux for now tuned-in channel failed.");
                
                serviceEvent(eventTuned);
                
@@ -198,8 +199,6 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref)
        RESULT res;
        m_reference = ref;
        
-//     ref.path = "/viva.ts"; // hrhr.
-       
                /* is this a normal (non PVR) channel? */
        if (ref.path.empty())
        {
index e260ddd..beafc5a 100644 (file)
@@ -66,8 +66,10 @@ class eDVBServicePMTHandler: public Object
 
        void PMTready(int error);
        void PATready(int error);
+       
+       int m_record;
 public:
-       eDVBServicePMTHandler();
+       eDVBServicePMTHandler(int record);
        ~eDVBServicePMTHandler();
        
        enum