X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/be7160f4c15f23e853a3a0ad7b0ad54107ed9ca1..c797d4040a1dfac3873b481111a84a5c557432f3:/lib/dvb/dvb.cpp diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 6e87585e..0eb614db 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,8 @@ eDVBResourceManager::eDVBResourceManager() eDebug("found %d adapter, %d frontends and %d demux", m_adapter.size(), m_frontend.size(), m_demux.size()); + eDVBCAService::registerChannelCallback(this); + CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel); } @@ -248,12 +251,12 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter) } } -void eDVBResourceManager::setFrontendSlotInformations(ePyObject list) +PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list) { if (!PyList_Check(list)) { PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list"); - return; + return NULL; } if ((unsigned int)PyList_Size(list) != m_frontend.size()) { @@ -261,45 +264,58 @@ void eDVBResourceManager::setFrontendSlotInformations(ePyObject list) sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist", m_frontend.size(), PyList_Size(list)); PyErr_SetString(PyExc_StandardError, blasel); - return; + return NULL; } int pos=0; for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) { ePyObject obj = PyList_GET_ITEM(list, pos++); - i->m_frontend->setSlotInfo(obj); + if (!i->m_frontend->setSlotInfo(obj)) + return NULL; } + Py_RETURN_NONE; } RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, ePtr &feparm) { ePtr best; int bestval = 0; + int foundone = 0; for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) + { + int c = i->m_frontend->isCompatibleWith(feparm); + + if (c) /* if we have at least one frontend which is compatible with the source, flag this. */ + foundone = 1; + if (!i->m_inuse) { - int c = i->m_frontend->isCompatibleWith(feparm); if (c > bestval) { bestval = c; best = i; } } + } if (best) { fe = new eDVBAllocatedFrontend(best); return 0; } - + fe = 0; - - return -1; + + if (foundone) + return errAllSourcesBusy; + else + return errNoSourceFound; } RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr &fe, int slot_index) { + int err = errNoSourceFound; for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index) { @@ -311,6 +327,7 @@ RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr if (satpos_depends_to_fe->m_inuse) { eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!"); + err = errAllSourcesBusy; goto alloc_fe_by_id_not_possible; } } @@ -323,6 +340,7 @@ RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr if (next->m_inuse) { eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!"); + err = errAllSourcesBusy; goto alloc_fe_by_id_not_possible; } next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR]; @@ -334,6 +352,7 @@ RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr if (prev->m_inuse) { eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!"); + err = errAllSourcesBusy; goto alloc_fe_by_id_not_possible; } prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR]; @@ -344,7 +363,7 @@ RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr } alloc_fe_by_id_not_possible: fe = 0; - return -1; + return err; } RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr &demux, int cap) @@ -442,22 +461,23 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse if (!m_list) { eDebug("no channel list set!"); - return -ENOENT; + return errNoChannelList; } ePtr feparm; if (m_list->getChannelFrontendData(channelid, feparm)) { eDebug("channel not found!"); - return -ENOENT; + return errChannelNotInList; } /* allocate a frontend. */ ePtr fe; - - if (allocateFrontend(fe, feparm)) - return errNoFrontend; + + int err = allocateFrontend(fe, feparm); + if (err) + return err; RESULT res; ePtr ch; @@ -517,9 +537,10 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel, in m_releaseCachedChannelTimer.stop(); } - if (allocateFrontendByIndex(fe, slot_index)) - return errNoFrontend; - + int err = allocateFrontendByIndex(fe, slot_index); + if (err) + return err; + eDVBChannel *ch; ch = new eDVBChannel(this, fe); @@ -592,14 +613,41 @@ int eDVBResourceManager::canAllocateFrontend(ePtr &fepar return bestval; } +int tuner_type_channel_default(ePtr &channellist, const eDVBChannelID &chid) +{ + if (channellist) + { + ePtr feparm; + if (!channellist->getChannelFrontendData(chid, feparm)) + { + int system; + if (!feparm->getSystem(system)) + { + switch(system) + { + case iDVBFrontend::feSatellite: + return 50000; + case iDVBFrontend::feCable: + return 40000; + case iDVBFrontend::feTerrestrial: + return 30000; + default: + break; + } + } + } + } + return 0; +} + int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore) { - int ret=30000; + int ret=0; if (m_cached_channel) { eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel); if(channelid==cache_chan->getChannelID()) - return ret; + return tuner_type_channel_default(m_list, channelid); } /* first, check if a channel is already existing. */ @@ -610,7 +658,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons if (i->m_channel_id == channelid) { // eDebug("found shared channel.."); - return ret; + return tuner_type_channel_default(m_list, channelid); } } @@ -680,14 +728,12 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons if (!m_list) { eDebug("no channel list set!"); - ret = 0; goto error; } if (m_list->getChannelFrontendData(channelid, feparm)) { eDebug("channel not found!"); - ret = 0; goto error; } @@ -920,6 +966,7 @@ void eDVBChannel::cueSheetEvent(int event) m_skipmode_n = m_skipmode_m = 0; } } + ASSERT(m_pvr_thread); m_pvr_thread->setIFrameSearch(m_skipmode_n != 0); eDebug("flush pvr"); flushPVR(m_cue->m_decoding_demux); @@ -1057,7 +1104,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off pts_t nextap; if (m_tstools.getNextAccessPoint(nextap, now, pts)) { - pts = now; + pts = now - 90000; /* approx. 1s */ eDebug("AP relative seeking failed!"); } else { @@ -1102,7 +1149,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off { /* in normal playback, just start at the next zone. */ start = i->first; - + /* size is not 64bit! */ if ((i->second - i->first) > max) size = max; @@ -1123,8 +1170,11 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off --i; eDebug("skip to previous block, which is %llx..%llx", i->first, i->second); size_t len; - - if ((i->second - i->first) > max) + + aligned_start = align(i->first, blocksize); + aligned_end = align(i->second, blocksize); + + if ((aligned_end - aligned_start) > max) len = max; else len = aligned_end - aligned_start; @@ -1132,19 +1182,19 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off start = aligned_end - len; eDebug("skipping to %llx, %d", start, len); } - + eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end); return; } } - + if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) { eDebug("reached SOF"); m_skipmode_m = 0; m_pvr_thread->sendEvent(eFilePushThread::evtUser); } - + start = current_offset; size = max;