From b6592b47fa1932132a67a3beabcce7c96856d211 Mon Sep 17 00:00:00 2001 From: Felix Domke Date: Sat, 15 Oct 2005 20:33:40 +0000 Subject: [PATCH] add demux handling (for decoder and record) --- lib/dvb/dvb.cpp | 71 +++++++++++++++++++++++++++++++------------- lib/dvb/dvb.h | 8 ++--- lib/dvb/dvbtime.cpp | 2 +- lib/dvb/epgcache.cpp | 2 +- lib/dvb/idvb.h | 8 +++-- lib/dvb/pmt.cpp | 9 +++--- lib/dvb/pmt.h | 4 ++- 7 files changed, 68 insertions(+), 36 deletions(-) diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 90df7267..c8feccfd 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -214,15 +214,29 @@ RESULT eDVBResourceManager::allocateFrontend(const eDVBChannelID &chid, ePtr &demux) +RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr &demux, int cap) { - /* find first unused demux which is on same adapter as frontend (or any, if PVR) */ - for (eSmartPtrList::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::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 demux; - - if (allocateDemux(*fe, demux)) - return errNoDemux; +// will be allocated on demand: +// ePtr demux; +// +// if (allocateDemux(*fe, demux)) +// return errNoDemux; RESULT res; eDVBChannel *ch; - ch = new eDVBChannel(this, fe, demux); + ch = new eDVBChannel(this, fe); ePtr myfe; if (!ch->getFrontend(myfe)) @@ -298,13 +313,13 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel) if (allocateFrontend(eDVBChannelID(), fe)) return errNoFrontend; - ePtr demux; - - if (allocateDemux(*fe, demux)) - return errNoDemux; +// ePtr demux; + // +// if (allocateDemux(*fe, demux)) +// return errNoDemux; eDVBChannel *ch; - ch = new eDVBChannel(this, fe, demux); + ch = new eDVBChannel(this, fe); ePtr myfe; if (!ch->getFrontend(myfe)) @@ -319,11 +334,11 @@ RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr &channel) { ePtr 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 & 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 &demux) +RESULT eDVBChannel::getDemux(ePtr &demux, int cap) { - demux = &m_demux->get(); + ePtr &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) { diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index d4c8eea0..9a85c22c 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -117,7 +117,7 @@ class eDVBResourceManager: public iObject RESULT allocateFrontend(const eDVBChannelID &chid, ePtr &fe); /* allocate a demux able to filter on the selected frontend. */ - RESULT allocateDemux(eDVBRegisteredFrontend *fe, ePtr &demux); + RESULT allocateDemux(eDVBRegisteredFrontend *fe, ePtr &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 &demux); + RESULT getDemux(ePtr &demux, int cap); RESULT getFrontend(ePtr &frontend); /* iDVBPVRChannel */ @@ -195,7 +195,7 @@ public: private: ePtr m_frontend; - ePtr m_demux; + ePtr m_demux, m_decoder_demux; ePtr m_current_frontend_parameters; eDVBChannelID m_channel_id; diff --git a/lib/dvb/dvbtime.cpp b/lib/dvb/dvbtime.cpp index 82ceffd5..bfc2c870 100644 --- a/lib/dvb/dvbtime.cpp +++ b/lib/dvb/dvbtime.cpp @@ -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) diff --git a/lib/dvb/epgcache.cpp b/lib/dvb/epgcache.cpp index c22bf89e..1ec88a39 100644 --- a/lib/dvb/epgcache.cpp +++ b/lib/dvb/epgcache.cpp @@ -231,7 +231,7 @@ void eEPGCache::DVBChannelRunning(iDVBChannel *chan) else { ePtr demux; - if ( data.channel->getDemux(demux) ) + if ( data.channel->getDemux(demux, 0) ) { eDebug("[eEPGCache] no demux!!"); return; diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index d94bf5fd..764c4556 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -434,13 +434,15 @@ public: }; virtual RESULT connectStateChange(const Slot1 &stateChange, ePtr &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 &demux)=0; + virtual RESULT getDemux(ePtr &demux, int cap=0)=0; /* direct frontend access for raw channels and/or status inquiries. */ virtual RESULT getFrontend(ePtr &frontend)=0; diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index a5bd9705..68b1f6c9 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -5,9 +5,10 @@ #include #include -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()) { diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index e260ddd2..beafc5af 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -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 -- 2.30.2