/* 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;
+
+ if (m_cue->m_skipmode_ratio < 0)
+ m_skipmode_m -= m_skipmode_n;
eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
if (abs(m_skipmode_m) < abs(m_skipmode_n))
{
- eFatal("damn, something is wrong with this calculation");
+ eWarning("something is wrong with this calculation");
m_skipmode_n = m_skipmode_m = 0;
}
break;
}
case eCueSheet::evtSpanChanged:
- eDebug("source span translation not yet supported");
- // recheckCuesheetSpans();
+ {
+ m_source_span.clear();
+ for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
+ {
+ off_t offset_in, offset_out;
+ pts_t pts_in = i->first, pts_out = i->second;
+ if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
+ {
+ eDebug("span translation failed.\n");
+ continue;
+ }
+ eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
+ m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
+ }
break;
}
+ }
}
/* remember, this gets called from another thread. */
eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
- if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
- {
- eDebug("reached SOF");
- m_skipmode_m = 0;
- m_pvr_thread->sendEvent(eFilePushThread::evtUser);
- }
-
current_offset += m_skipmode_m;
while (!m_cue->m_seek_requests.empty())
int relative = seek.first;
pts_t pts = seek.second;
- int bitrate = m_tstools.calcBitrate(); /* in bits/s */
-
- if (bitrate == -1)
- continue;
-
+ pts_t now = 0;
if (relative)
{
- pts_t now;
if (!m_cue->m_decoder)
{
eDebug("no decoder - can't seek relative");
eDebug("seekTo: getCurrentPosition failed!");
continue;
}
+ }
+
+ if (relative == 1) /* pts relative */
pts += now;
+
+ if (relative != 2)
+ if (pts < 0)
+ pts = 0;
+
+ if (relative == 2) /* AP relative */
+ {
+ eDebug("AP relative seeking: %lld, at %lld", pts, now);
+ pts_t nextap;
+ if (m_tstools.getNextAccessPoint(nextap, now, pts))
+ {
+ pts = now;
+ eDebug("AP relative seeking failed!");
+ } else
+ {
+ eDebug("next ap is %llx\n", pts);
+ pts = nextap;
+ }
}
-
- if (pts < 0)
- pts = 0;
-
- off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
+ off_t offset = 0;
+ if (m_tstools.getOffset(offset, pts))
+ continue;
+
eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
current_offset = offset;
}
}
if (current_offset < i->first)
{
- start = i->first;
- size = i->second - i->first;
- if (size > max)
+ /* ok, our current offset is in an 'out' zone. */
+ if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
+ {
+ /* in normal playback, just start at the next zone. */
+ start = i->first;
+ size = i->second - i->first;
+ if (size > max)
+ size = max;
+ eDebug("skip");
+ if (m_skipmode_m < 0)
+ {
+ eDebug("reached SOF");
+ /* reached SOF */
+ m_skipmode_m = 0;
+ m_pvr_thread->sendEvent(eFilePushThread::evtUser);
+ }
+ } else
+ {
+ /* when skipping reverse, however, choose the zone before. */
+ --i;
+ eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
+ size_t len = i->second - i->first;
+ if (max > len)
+ max = len;
+ start = i->second - max;
size = max;
- eDebug("skip");
+ eDebug("skipping to %llx, %d", start, size);
+ }
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;
eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
-
- if (size < 4096)
- eFatal("blub");
return;
}
THEN DO A REAL FIX HERE! */
/* (this codepath needs to be improved anyway.) */
+#if HAVE_DVB_API_VERSION < 3
+ m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
+#else
m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
+#endif
if (m_pvr_fd_dst < 0)
{
eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
eSingleLock l(m_lock);
m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
}
+}
+
+void eCueSheet::commitSpans()
+{
m_event(evtSpanChanged);
}