}
#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;
fts += 188;
}
- /* force payload only */
- ts[3] &= ~0x30;
- ts[3] |= 0x10;
-
-// memset(ts + 4, 0xFF, (offset % 188) - 4);
m_iframe_state = 1;
}
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);
/* 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;
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);
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;
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())
{
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 */
}
}
}
- 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;
}
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<pts_t, pts_t>(begin, end));
m_lock.Unlock();