// fixmee.. here we need a better solution to ensure
// that the thread context take notice of the signal
// even when no syscall is in progress
- while(!sendSignal(SIGUSR1))
- {
- eDebug("send SIGUSR1 to thread context");
- usleep(5000); // wait msek
- }
- kill();
+ eDebug("if enigma hangs here, the filepush thread is non-responsive. FIX THAT DAMN THREAD.");
+ sendSignal(SIGUSR1);
+ kill(0);
}
void eFilePushThread::pause()
unsigned char *ts = data + ts_offset;
int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
- if ((d[3] == 0) && (m_pid == pid)) /* picture start */
+ if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid)) /* picture start */
{
- int picture_type = (d[5] >> 3) & 7;
+ int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
d += 4;
// eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
}
} else if ((d[3] & 0xF0) == 0xE0) /* video stream */
{
- if (m_pid != pid)
+ /* verify that this is actually a PES header, not just some ES data */
+ if (ts[1] & 0x40) /* PUSI set */
{
- eDebug("now locked to pid %04x", pid);
- m_pid = pid;
+ int payload_start = 4;
+ if (ts[3] & 0x20) /* adaptation field present */
+ payload_start += ts[4] + 1; /* skip AF */
+ if (payload_start == (offset%184)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */
+ {
+ if (m_pid != pid)
+ {
+ eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]);
+ m_pid = pid;
+ }
+ }
}
// m_pid = 0x6e;
d += 4;
{
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))
+ if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
{
eDebug("span translation failed.\n");
continue;
eDebug("AP relative seeking failed!");
} else
{
- eDebug("next ap is %llx\n", pts);
pts = nextap;
+ eDebug("next ap is %llx\n", pts);
}
}
off_t offset = 0;
- if (m_tstools.getOffset(offset, pts))
+ if (m_tstools.getOffset(offset, pts, -1))
{
eDebug("get offset for pts=%lld failed!", pts);
continue;
}
}
- 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()) {
+ 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;
+ } 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);
+ }
}
- start = current_offset;
- size = max;
-
eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
return;
}
return -1;
m_access_points.clear();
m_pts_to_offset.clear();
- pts_t last = -(1LL<<62);
- int loaded = 0, skipped = 0;
while (1)
{
unsigned long long d[2];
d[0] = bswap_64(d[0]);
d[1] = bswap_64(d[1]);
#endif
- if ((d[1] - last) > 90000/2)
- {
- m_access_points[d[0]] = d[1];
- m_pts_to_offset.insert(std::pair<pts_t,off_t>(d[1], d[0]));
- last = d[1];
- loaded++;
- } else
- skipped++;
+ m_access_points[d[0]] = d[1];
+ m_pts_to_offset.insert(std::pair<pts_t,off_t>(d[1], d[0]));
}
- eDebug("loaded %d, skipped %d", loaded, skipped);
fclose(f);
fixupDiscontinuties();
return 0;
return before_ts + diff;
}
-off_t eMPEGStreamInformation::getAccessPoint(pts_t ts)
+off_t eMPEGStreamInformation::getAccessPoint(pts_t ts, int marg)
{
/* FIXME: more efficient implementation */
off_t last = 0;
+ off_t last2 = 0;
+ pts_t lastc = 0;
for (std::map<off_t, pts_t>::const_iterator i(m_access_points.begin()); i != m_access_points.end(); ++i)
{
pts_t delta = getDelta(i->first);
pts_t c = i->second - delta;
- if (c > ts)
- break;
+ if (c > ts) {
+ if (marg > 0)
+ return (last + i->first)/376*188;
+ else if (marg < 0)
+ return (last + last2)/376*188;
+ else
+ return last;
+ }
+ lastc = c;
+ last2 = last;
last = i->first;
}
- return last;
+ if (marg < 0)
+ return (last + last2)/376*188;
+ else
+ return last;
}
int eMPEGStreamInformation::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction)
{
off_t offset = getAccessPoint(start);
+ pts_t c1, c2;
std::map<off_t, pts_t>::const_iterator i = m_access_points.find(offset);
if (i == m_access_points.end())
{
eDebug("getNextAccessPoint: initial AP not found");
return -1;
}
+ c1 = i->second - getDelta(i->first);
while (direction)
{
if (direction > 0)
if (i == m_access_points.end())
return -1;
++i;
+ c2 = i->second - getDelta(i->first);
+ if (c1 == c2) { // Discontinuity
+ ++i;
+ c2 = i->second - getDelta(i->first);
+ }
+ c1 = c2;
direction--;
}
if (direction < 0)
return -1;
}
--i;
+ c2 = i->second - getDelta(i->first);
+ if (c1 == c2) { // Discontinuity
+ --i;
+ c2 = i->second - getDelta(i->first);
+ }
+ c1 = c2;
direction++;
}
}
/*eDebug("Sequence header but no valid PTS value.")*/;
}
- if (pkt[3] == 0x09) /* MPEG4 AVC unit access delimiter */
+ if (pkt[3] == 0x09 && /* MPEG4 AVC unit access delimiter */
+ (pkt[4] >> 5) == 0) /* and I-frame */
{
if (ptsvalid)
{
/* inter/extrapolate timestamp from offset */
pts_t getInterpolated(off_t offset);
- off_t getAccessPoint(pts_t ts);
+ off_t getAccessPoint(pts_t ts, int marg=0);
int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction);
}
}
-int eDVBTSTools::getOffset(off_t &offset, pts_t &pts)
+int eDVBTSTools::getOffset(off_t &offset, pts_t &pts, int marg)
{
if (m_use_streaminfo)
{
- offset = m_streaminfo.getAccessPoint(pts);
+ if (pts >= m_pts_end && marg > 0 && m_end_valid)
+ offset = m_offset_end;
+ else
+ offset = m_streaminfo.getAccessPoint(pts, marg);
return 0;
} else
{
int fixupPTS(const off_t &offset, pts_t &pts);
/* get (approximate) offset corresponding to PTS */
- int getOffset(off_t &offset, pts_t &pts);
+ int getOffset(off_t &offset, pts_t &pts, int marg=0);
int getNextAccessPoint(pts_t &ts, const pts_t &start, int direction);
ifaces[currif]["gateway"] = map(int, split[1].split('.'))
if self.ifaces[currif].has_key("gateway"):
if self.ifaces[currif]["gateway"] != ifaces[currif]["gateway"] and ifaces[currif]["dhcp"] == False:
- self.ifaces[currif]["gateway"] = map(int, split[1].split('.'))
+ self.ifaces[currif]["gateway"] = map(int, split[1].split('.'))
if (split[0] == "pre-up"):
if self.ifaces[currif].has_key("preup"):
self.ifaces[currif]["preup"] = i
RESULT eDVBServicePlay::setSlowMotion(int ratio)
{
+ eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
if (m_decoder)
return m_decoder->setSlowMotion(ratio);
else
RESULT eDVBServicePlay::setFastForward(int ratio)
{
+ eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
int skipmode, ffratio;
if (ratio > 8)
RESULT eDVBServicePlay::pause()
{
+ eDebug("eDVBServicePlay::pause");
if (!m_is_paused && m_decoder)
{
m_is_paused = 1;
RESULT eDVBServicePlay::unpause()
{
+ eDebug("eDVBServicePlay::unpause");
if (m_is_paused && m_decoder)
{
m_is_paused = 0;