X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fdvb.cpp;h=f0186de70b24a84c529b8aaa6e86ad63f5f3d99a;hp=4bbed519326b36d4c72376fab41ef0bd5b5902f8;hb=7882dec4e8e3e87cee0cf4eeb781119c196ba725;hpb=a4b8eb676ba549ebe8cf347f15888e51d8914789 diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 4bbed51..f0186de 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1026,11 +1026,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 +1069,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 +1170,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 +1181,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); @@ -1238,6 +1235,23 @@ static inline long long align(long long x, int align) 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; + + return x; +} + /* remember, this gets called from another thread. */ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size) { @@ -1265,26 +1279,53 @@ 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); - - current_offset += align(m_skipmode_m, blocksize); + int frame_skip_success = 0; + if (m_skipmode_m) { - eDebug("we are at %llx, and we try to find the iframe here:", current_offset); + 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_tstools.findIFrame(iframe_start, iframe_len, (m_skipmode_m < 0) ? -1 : +1)) - eDebug("failed"); - else + if (m_skipmode_m) { - current_offset = align(iframe_start, blocksize); - max = align(iframe_len, blocksize); + 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); + } } } @@ -1366,9 +1407,10 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off size_t iframe_len; /* try to align to iframe */ - m_tstools.findIFrame(offset, iframe_len, pts < 0 ? -1 : 1); + 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 */ }