X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/d839a9dc005a469e4509d07305cdf3b4913d3ec1..23876b6f15422655b8c180682b10a09302444bef:/lib/dvb/dvb.cpp diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index c320fc78..a7428493 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -429,7 +429,25 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr unused; - if (m_demux.size() < 5) + if (m_demux.size() == 3) // dm800 / 500hd + { + for (; i != m_demux.end(); ++i, ++n) + { + if (!i->m_inuse) + { + if (!unused) + unused = i; + } + else if (i->m_adapter == fe->m_adapter && + i->m_demux->getSource() == fe->m_frontend->getDVBID()) + { + demux = new eDVBAllocatedDemux(i); + return 0; + } + } + + } + else if (m_demux.size() < 5) // ATI { /* FIXME: hardware demux policy */ if (!(cap & iDVBChannel::capDecode)) @@ -974,7 +992,7 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s } #endif -#if 1 /* This codepath is required on Broadcom-based Dreamboxes (DM800, DM8000) and strips away non-I-frames. */ +#if 0 if (!m_iframe_search) return len; @@ -1026,11 +1044,6 @@ int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, s fts += 188; } - /* force payload only */ - ts[3] &= ~0x30; - ts[3] |= 0x10; - -// memset(ts + 4, 0xFF, (offset % 188) - 4); m_iframe_state = 1; } @@ -1074,7 +1087,7 @@ eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *fronte m_pvr_thread = 0; - m_skipmode_n = m_skipmode_m = 0; + m_skipmode_n = m_skipmode_m = m_skipmode_frames = 0; if (m_frontend) m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged); @@ -1175,6 +1188,8 @@ void eDVBChannel::cueSheetEvent(int event) /* i agree that this might look a bit like black magic. */ m_skipmode_n = 512*1024; /* must be 1 iframe at least. */ m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8; + m_skipmode_frames = m_cue->m_skipmode_ratio / 90000; + m_skipmode_frames_remainder = 0; if (m_cue->m_skipmode_ratio < 0) m_skipmode_m -= m_skipmode_n; @@ -1184,12 +1199,12 @@ void eDVBChannel::cueSheetEvent(int event) if (abs(m_skipmode_m) < abs(m_skipmode_n)) { eWarning("something is wrong with this calculation"); - m_skipmode_n = m_skipmode_m = 0; + m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0; } } else { eDebug("skipmode ratio is 0, normal play"); - m_skipmode_n = m_skipmode_m = 0; + m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0; } } m_pvr_thread->setIFrameSearch(m_skipmode_n != 0); @@ -1232,6 +1247,23 @@ static inline long long align(long long x, int align) x -= x % align; + if (sign) + x = -x; + + return x; +} + + /* align toward zero */ +static inline long long align_with_len(long long x, int align, size_t &len) +{ + int sign = x < 0; + + if (sign) + x = -x; + + x -= x % align; + len += x % align; + if (sign) x = -x; @@ -1265,13 +1297,55 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off if (m_skipmode_n) { - eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n); + eDebug("skipmode %d:%d (x%d)", m_skipmode_m, m_skipmode_n, m_skipmode_frames); max = align(m_skipmode_n, blocksize); } eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m); + + int frame_skip_success = 0; - current_offset += align(m_skipmode_m, blocksize); + if (m_skipmode_m) + { + int frames_to_skip = m_skipmode_frames + m_skipmode_frames_remainder; + eDebug("we are at %llx, and we try to skip %d+%d frames from here", current_offset, m_skipmode_frames, m_skipmode_frames_remainder); + size_t iframe_len; + off_t iframe_start = current_offset; + int frames_skipped = frames_to_skip; + if (!m_tstools.findNextPicture(iframe_start, iframe_len, frames_skipped)) + { + m_skipmode_frames_remainder = frames_to_skip - frames_skipped; + eDebug("successfully skipped %d (out of %d, rem now %d) frames.", frames_skipped, frames_to_skip, m_skipmode_frames_remainder); + current_offset = align_with_len(iframe_start, blocksize, iframe_len); + max = align(iframe_len + 187, blocksize); + frame_skip_success = 1; + } else + { + m_skipmode_frames_remainder = 0; + eDebug("frame skipping failed, reverting to byte-skipping"); + } + } + + if (!frame_skip_success) + { + current_offset += align(m_skipmode_m, blocksize); + + if (m_skipmode_m) + { + eDebug("we are at %llx, and we try to find the iframe here:", current_offset); + size_t iframe_len; + off_t iframe_start = current_offset; + + int direction = (m_skipmode_m < 0) ? -1 : +1; + if (m_tstools.findFrame(iframe_start, iframe_len, direction)) + eDebug("failed"); + else + { + current_offset = align_with_len(iframe_start, blocksize, iframe_len); + max = align(iframe_len, blocksize); + } + } + } while (!m_cue->m_seek_requests.empty()) { @@ -1348,8 +1422,13 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off eDebug("get offset for pts=%lld failed!", pts); continue; } + + size_t iframe_len; + /* try to align to iframe */ + int direction = pts < 0 ? -1 : 1; + m_tstools.findFrame(offset, iframe_len, direction); - eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset); + eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction); current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */ } @@ -1417,30 +1496,23 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off } } - if (m_source_span.empty()) { - if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) - { - eDebug("reached SOF"); - m_skipmode_m = 0; - m_pvr_thread->sendEvent(eFilePushThread::evtUser); - } + if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0)) + { + eDebug("reached SOF"); + m_skipmode_m = 0; + m_pvr_thread->sendEvent(eFilePushThread::evtUser); + } + + if (m_source_span.empty()) + { start = current_offset; size = max; - } else { - off_t tmp2, tmp = align(m_source_span.rbegin()->second, blocksize); - pts_t len; - getLength(len); - m_tstools.getOffset(tmp2, len, 1); - if (current_offset == tmp || current_offset == tmp2) { - start = tmp2; - size = max; - } else { - start = tmp - align(512*1024, blocksize); - size = align(512*1024, blocksize); - } + eDebug("NO CUESHEET. (%08llx, %d)", start, size); + } else + { + start = current_offset; + size = 0; } - - eDebug("END OF CUESHEET. (%08llx, %d)", start, size); return; } @@ -1774,7 +1846,7 @@ void eCueSheet::clear() void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end) { - assert(begin < end); + ASSERT(begin < end); m_lock.WrLock(); m_spans.push_back(std::pair(begin, end)); m_lock.Unlock();