X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/a36fbc3f717012e70a0b37ce5bf8b1920d4a5ff3..cbb644f511c537b8cc1f209adf26f83939e80c3e:/lib/dvb/dvb.cpp diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index cb24fc3c..a2652c5b 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -90,7 +90,7 @@ void eDVBResourceManager::feStateChanged() int mask=0; for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) if (i->m_inuse) - mask |= ( 1 << i->m_frontend->getID() ); + mask |= ( 1 << i->m_frontend->getSlotID() ); /* emit */ frontendUseMaskChanged(mask); } @@ -248,6 +248,31 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter) } } +PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list) +{ + if (!PyList_Check(list)) + { + PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list"); + return NULL; + } + if ((unsigned int)PyList_Size(list) != m_frontend.size()) + { + char blasel[256]; + 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 NULL; + } + int pos=0; + for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) + { + ePyObject obj = PyList_GET_ITEM(list, pos++); + if (!i->m_frontend->setSlotInfo(obj)) + return NULL; + } + Py_RETURN_NONE; +} + RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, ePtr &feparm) { ePtr best; @@ -275,15 +300,51 @@ RESULT eDVBResourceManager::allocateFrontend(ePtr &fe, eP return -1; } -RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr &fe, int nr) +RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr &fe, int slot_index) { - for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr) - if ((!nr) && !i->m_inuse) + for (eSmartPtrList::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i) + if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index) { + // check if another slot linked to this is in use + eDVBRegisteredFrontend *satpos_depends_to_fe = + (eDVBRegisteredFrontend*) i->m_frontend->m_data[eDVBFrontend::SATPOS_DEPENDS_PTR]; + if ( (int)satpos_depends_to_fe != -1 ) + { + if (satpos_depends_to_fe->m_inuse) + { + eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!"); + goto alloc_fe_by_id_not_possible; + } + } + else // check linked tuners + { + eDVBRegisteredFrontend *next = + (eDVBRegisteredFrontend *) i->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR]; + while ( (int)next != -1 ) + { + if (next->m_inuse) + { + eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!"); + goto alloc_fe_by_id_not_possible; + } + next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR]; + } + eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *) + i->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR]; + while ( (int)prev != -1 ) + { + if (prev->m_inuse) + { + eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!"); + goto alloc_fe_by_id_not_possible; + } + prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR]; + } + } fe = new eDVBAllocatedFrontend(i); return 0; } - +alloc_fe_by_id_not_possible: fe = 0; return -1; } @@ -323,7 +384,7 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtrget().setSourceFrontend(fe->m_frontend->getID()); + demux->get().setSourceFrontend(fe->m_frontend->getDVBID()); else demux->get().setSourcePVR(0); return 0; @@ -447,7 +508,7 @@ void eDVBResourceManager::releaseCachedChannel() m_cached_channel=0; } -RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel, int frontend_index) +RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel, int slot_index) { ePtr fe; @@ -458,7 +519,7 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel, in m_releaseCachedChannelTimer.stop(); } - if (allocateFrontendByIndex(fe, frontend_index)) + if (allocateFrontendByIndex(fe, slot_index)) return errNoFrontend; eDVBChannel *ch; @@ -530,7 +591,6 @@ int eDVBResourceManager::canAllocateFrontend(ePtr &fepar if (c > bestval) bestval = c; } - return bestval; } @@ -722,7 +782,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s eDebug("now locked to pid %04x", pid); m_pid = pid; } - m_pid = 0x6e; +// m_pid = 0x6e; d += 4; } else d += 4; /* ignore */ @@ -833,8 +893,10 @@ void eDVBChannel::cueSheetEvent(int event) case eCueSheet::evtSkipmode: { { - eSingleLocker l(m_cue->m_lock); + m_cue->m_lock.WrLock(); m_cue->m_seek_requests.push_back(std::pair(1, 0)); /* resync */ + m_cue->m_lock.Unlock(); + eRdLocker l(m_cue->m_lock); if (m_cue->m_skipmode_ratio) { int bitrate = m_tstools.calcBitrate(); /* in bits/s */ @@ -860,6 +922,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); @@ -887,7 +950,7 @@ void eDVBChannel::cueSheetEvent(int event) } /* align toward zero */ -static inline int align(long long x, int align) +static inline long long align(long long x, int align) { int sign = x < 0; @@ -917,13 +980,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off return; } - eSingleLocker l(m_cue->m_lock); - + m_cue->m_lock.RdLock(); if (!m_cue->m_decoding_demux) { start = current_offset; size = max; eDebug("getNextSourceSpan, no decoding demux. forcing normal play"); + m_cue->m_lock.Unlock(); return; } @@ -933,14 +996,18 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off max = align(m_skipmode_n, blocksize); } - eDebug("getNextSourceSpan, current offset is %08llx!", current_offset); + eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m); current_offset += align(m_skipmode_m, blocksize); while (!m_cue->m_seek_requests.empty()) { std::pair seek = m_cue->m_seek_requests.front(); + m_cue->m_lock.Unlock(); + m_cue->m_lock.WrLock(); m_cue->m_seek_requests.pop_front(); + m_cue->m_lock.Unlock(); + m_cue->m_lock.RdLock(); int relative = seek.first; pts_t pts = seek.second; @@ -993,7 +1060,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 { @@ -1010,14 +1077,16 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off } eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset); - current_offset = offset; + current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */ } + m_cue->m_lock.Unlock(); + for (std::list >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i) { - int aligned_start = align(i->first, blocksize); - int aligned_end = align(i->second, blocksize); - + long long aligned_start = align(i->first, blocksize); + long long aligned_end = align(i->second, blocksize); + if ((current_offset >= aligned_start) && (current_offset < aligned_end)) { start = current_offset; @@ -1036,7 +1105,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; @@ -1057,8 +1126,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; @@ -1066,19 +1138,21 @@ 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 = blocksize; + size = max; eDebug("END OF CUESHEET. (%08llx, %d)", start, size); return; @@ -1344,25 +1418,24 @@ eCueSheet::eCueSheet() void eCueSheet::seekTo(int relative, const pts_t &pts) { - { - eSingleLocker l(m_lock); - m_seek_requests.push_back(std::pair(relative, pts)); - } + m_lock.WrLock(); + m_seek_requests.push_back(std::pair(relative, pts)); + m_lock.Unlock(); m_event(evtSeek); } void eCueSheet::clear() { - eSingleLocker l(m_lock); + m_lock.WrLock(); m_spans.clear(); + m_lock.Unlock(); } void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end) { - { - eSingleLocker l(m_lock); - m_spans.push_back(std::pair(begin, end)); - } + m_lock.WrLock(); + m_spans.push_back(std::pair(begin, end)); + m_lock.Unlock(); } void eCueSheet::commitSpans() @@ -1372,10 +1445,9 @@ void eCueSheet::commitSpans() void eCueSheet::setSkipmode(const pts_t &ratio) { - { - eSingleLocker l(m_lock); - m_skipmode_ratio = ratio; - } + m_lock.WrLock(); + m_skipmode_ratio = ratio; + m_lock.Unlock(); m_event(evtSkipmode); }