X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/06fb2bcb4ddf528cbe65d58be41cf8ecf8697e76..a2a9746211af69c5f0c5090468fd656fb71e4b4a:/lib/dvb/dvb.cpp diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index ed972bf1..9ddc29b3 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -46,7 +46,7 @@ eDVBResourceManager::eDVBResourceManager() { avail = 1; busy = 0; - m_sec = new eDVBSatelliteEquipmentControl; + m_sec = new eDVBSatelliteEquipmentControl(m_frontend); if (!instance) instance = this; @@ -197,20 +197,54 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter) for (i=0; i frontend; + if (!adapter->getFrontend(frontend, i)) + { + frontend->setTone(iDVBFrontend::toneOff); + frontend->setVoltage(iDVBFrontend::voltageOff); + frontend->setSEC(m_sec); m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter)); + } } } -RESULT eDVBResourceManager::allocateFrontend(const eDVBChannelID &chid, ePtr &fe) +RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, ePtr &feparm) { - /* find first unused frontend. we ignore compatibility for now. */ + ePtr best; + int bestval = 0; + for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) if (!i->m_inuse) + { + int c = i->m_frontend->isCompatibleWith(feparm); + if (c > bestval) + { + c = bestval; + best = i; + } + } + + if (best) + { + fe = new eDVBAllocatedFrontend(best); + return 0; + } + + fe = 0; + + return -1; +} + +RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr &fe, int nr) +{ + for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr) + if ((!nr) && !i->m_inuse) { fe = new eDVBAllocatedFrontend(i); return 0; } + + fe = 0; return -1; } @@ -225,15 +259,22 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtrm_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter))) { + if ((cap & iDVBChannel::capDecode) && n) + continue; + demux = new eDVBAllocatedDemux(i); - eDebug("demux found"); + if (fe) + demux->get().setSourceFrontend(fe->m_frontend->getID()); + else + demux->get().setSourcePVR(0); return 0; } eDebug("demux not found"); @@ -272,30 +313,33 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse } } - /* no currently available channel is tuned to this channelid. create a new one, if possible. */ - - /* allocate a frontend. */ + /* no currently available channel is tuned to this channelid. create a new one, if possible. */ + + if (!m_list) + { + eDebug("no channel list set!"); + return -ENOENT; + } + + ePtr feparm; + if (m_list->getChannelFrontendData(channelid, feparm)) + { + eDebug("channel not found!"); + return -ENOENT; + } + + /* allocate a frontend. */ ePtr fe; - if (allocateFrontend(channelid, fe)) + if (allocateFrontend(fe, feparm)) return errNoFrontend; -// will be allocated on demand: -// ePtr demux; -// -// if (allocateDemux(*fe, demux)) -// return errNoDemux; - RESULT res; ePtr ch; ch = new eDVBChannel(this, fe); - ePtr myfe; - if (!ch->getFrontend(myfe)) - myfe->setSEC(m_sec); - - res = ch->setChannel(channelid); + res = ch->setChannel(channelid, feparm); if (res) { channel = 0; @@ -306,25 +350,16 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse return 0; } -RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel) +RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel, int frontend_index) { ePtr fe; - - if (allocateFrontend(eDVBChannelID(), fe)) + + if (allocateFrontendByIndex(fe, frontend_index)) return errNoFrontend; -// ePtr demux; - // -// if (allocateDemux(*fe, demux)) -// return errNoDemux; - eDVBChannel *ch; ch = new eDVBChannel(this, fe); - ePtr myfe; - if (!ch->getFrontend(myfe)) - myfe->setSEC(m_sec); - channel = ch; return 0; } @@ -334,9 +369,6 @@ RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr &channel) { ePtr demux; -// if (allocateDemux(0, demux)) -// return errNoDemux; - eDVBChannel *ch; ch = new eDVBChannel(this, 0); @@ -452,7 +484,7 @@ void eDVBChannel::ReleaseUse() } } -RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid) +RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr &feparm) { if (m_channel_id) m_mgr->removeChannel(this); @@ -460,24 +492,6 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid) if (!channelid) return 0; - ePtr list; - - if (m_mgr->getChannelList(list)) - { - eDebug("no channel list set!"); - return -ENOENT; - } - - eDebug("tuning to chid: ns: %08x tsid %04x onid %04x", - channelid.dvbnamespace.get(), channelid.transport_stream_id.get(), channelid.original_network_id.get()); - - ePtr feparm; - if (list->getChannelFrontendData(channelid, feparm)) - { - eDebug("channel not found!"); - return -ENOENT; - } - if (!m_frontend) { eDebug("no frontend to tune!"); @@ -487,7 +501,18 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid) m_channel_id = channelid; m_mgr->addChannel(channelid, this); m_state = state_tuning; - return m_frontend->get().tune(*feparm); + /* if tuning fails, shutdown the channel immediately. */ + int res; + res = m_frontend->get().tune(*feparm); + + if (res) + { + m_state = state_release; + m_stateChanged(this); + return res; + } + + return 0; } RESULT eDVBChannel::connectStateChange(const Slot1 &stateChange, ePtr &connection) @@ -509,6 +534,7 @@ RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing) RESULT eDVBChannel::getDemux(ePtr &demux, int cap) { + eDebug("get %d demux", cap); ePtr &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux; if (!our_demux) @@ -516,10 +542,15 @@ RESULT eDVBChannel::getDemux(ePtr &demux, int cap) demux = 0; if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap)) - return 0; + return -1; + } demux = *our_demux; + if (cap & capDecode) + { + our_demux = 0; + } return 0; } @@ -551,7 +582,7 @@ RESULT eDVBChannel::playFile(const char *file) m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY); if (m_pvr_fd_dst < 0) { - eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); + eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved. return -ENODEV; } @@ -577,9 +608,9 @@ RESULT eDVBChannel::getLength(pts_t &len) return m_tstools.calcLen(len); } -RESULT eDVBChannel::getCurrentPosition(pts_t &pos) +RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos) { - if (!m_decoder_demux) + if (!decoding_demux) return -1; off_t begin = 0; @@ -593,7 +624,7 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos) pts_t now; - r = m_decoder_demux->get().getSTC(now); + r = decoding_demux->getSTC(now); if (r) { @@ -618,7 +649,7 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos) return 0; } -RESULT eDVBChannel::seekTo(int relative, pts_t &pts) +RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts) { int bitrate = m_tstools.calcBitrate(); /* in bits/s */ @@ -628,7 +659,7 @@ RESULT eDVBChannel::seekTo(int relative, pts_t &pts) if (relative) { pts_t now; - if (getCurrentPosition(now)) + if (getCurrentPosition(decoding_demux, now)) { eDebug("seekTo: getCurrentPosition failed!"); return -1; @@ -641,11 +672,11 @@ RESULT eDVBChannel::seekTo(int relative, pts_t &pts) off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL; - seekToPosition(offset); + seekToPosition(decoding_demux, offset); return 0; } -RESULT eDVBChannel::seekToPosition(const off_t &r) +RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r) { /* when seeking, we have to ensure that all buffers are flushed. there are basically 3 buffers: @@ -667,8 +698,8 @@ RESULT eDVBChannel::seekToPosition(const off_t &r) ::ioctl(m_pvr_fd_dst, 0); /* flush ratebuffers (video, audio) */ - if (m_decoder_demux) - m_decoder_demux->get().flush(); + if (decoding_demux) + decoding_demux->flush(); /* demux will also flush all decoder.. */ m_pvr_thread->seek(SEEK_SET, r);