num_adapter++;
}
- eDebug("found %d adapter, %d frontends(%d sim) and %d demux",
- m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size());
+ int fd = open("/proc/stb/info/model", O_RDONLY);
+ char tmp[255];
+ int rd = fd >= 0 ? read(fd, tmp, 255) : 0;
+ if (fd >= 0)
+ close(fd);
+
+ if (!strncmp(tmp, "dm7025\n", rd))
+ m_boxtype = DM7025;
+ else if (!strncmp(tmp, "dm8000\n", rd))
+ m_boxtype = DM8000;
+ else if (!strncmp(tmp, "dm800\n", rd))
+ m_boxtype = DM800;
+ else if (!strncmp(tmp, "dm500hd\n", rd))
+ m_boxtype = DM500HD;
+ else {
+ eDebug("boxtype detection via /proc/stb/info not possible... use fallback via demux count!\n");
+ if (m_demux.size() == 3)
+ m_boxtype = DM800;
+ else if (m_demux.size() < 5)
+ m_boxtype = DM7025;
+ else
+ m_boxtype = DM8000;
+ }
+
+ eDebug("found %d adapter, %d frontends(%d sim) and %d demux, boxtype %d",
+ m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size(), m_boxtype);
eDVBCAService::registerChannelCallback(this);
return err;
}
-RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
+#define capHoldDecodeReference 64
+
+RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int &cap)
{
/* find first unused demux which is on same adapter as frontend (or any, if PVR)
never use the first one unless we need a decoding demux. */
ePtr<eDVBRegisteredDemux> unused;
- if (m_demux.size() == 3) // dm800 / 500hd
+ if (m_boxtype == DM800 || m_boxtype == DM500HD) // dm800 / 500hd
{
+ cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux
for (; i != m_demux.end(); ++i, ++n)
{
if (!i->m_inuse)
if (!unused)
unused = i;
}
- else if (!fe || (i->m_adapter == fe->m_adapter &&
- i->m_demux->getSource() == fe->m_frontend->getDVBID()))
+ else
{
- demux = new eDVBAllocatedDemux(i);
- return 0;
+ if (fe)
+ {
+ if (i->m_adapter == fe->m_adapter &&
+ i->m_demux->getSource() == fe->m_frontend->getDVBID())
+ {
+ demux = new eDVBAllocatedDemux(i);
+ return 0;
+ }
+ }
+ else if (i->m_demux->getSource() == -1) // PVR
+ {
+ demux = new eDVBAllocatedDemux(i);
+ return 0;
+ }
}
}
-
}
- else if (m_demux.size() < 5) // ATI
+ else if (m_boxtype == DM7025) // ATI
{
/* FIXME: hardware demux policy */
if (!(cap & iDVBChannel::capDecode))
}
}
}
- else // we asume dm8000
+ else if (m_boxtype == DM8000)
{
+ cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux
for (; i != m_demux.end(); ++i, ++n)
{
if (fe)
m_frontend = frontend;
m_pvr_thread = 0;
+ m_pvr_fd_dst = -1;
m_skipmode_n = m_skipmode_m = m_skipmode_frames = 0;
return;
}
- m_cue->m_lock.RdLock();
- if (!m_cue->m_decoding_demux)
- {
- start = current_offset;
- size = max;
- eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
- m_cue->m_lock.Unlock();
- return;
- }
-
if (m_skipmode_n)
{
eDebug("skipmode %d:%d (x%d)", m_skipmode_m, m_skipmode_n, m_skipmode_frames);
}
eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
-
int frame_skip_success = 0;
if (m_skipmode_m)
}
}
+ m_cue->m_lock.RdLock();
+
while (!m_cue->m_seek_requests.empty())
{
std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
eDebug("decoder getPTS failed, can't seek relative");
continue;
}
+ if (!m_cue->m_decoding_demux)
+ {
+ eDebug("getNextSourceSpan, no decoding demux. couldn't seek to %llx... ignore request!", pts);
+ start = current_offset;
+ size = max;
+ continue;
+ }
if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
{
eDebug("seekTo: getCurrentPosition failed!");
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 (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
+ eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
}
m_SDT = 0;
}
+int eDVBChannel::reserveDemux()
+{
+ ePtr<iDVBDemux> dmx;
+ if (!getDemux(dmx, 0))
+ {
+ uint8_t id;
+ if (!dmx->getCADemuxID(id))
+ return id;
+ }
+ return -1;
+}
+
RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
{
if (PyCallable_Check(callback))
if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
return -1;
- }
- demux = *our_demux;
+ demux = *our_demux;
+
/* don't hold a reference to the decoding demux, we don't need it. */
/* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
the refcount is lost. thus, decoding demuxes are never allocated.
this poses a big problem for PiP. */
- if (cap & capDecode)
- our_demux = 0;
+
+ if (cap & capHoldDecodeReference) // this is set in eDVBResourceManager::allocateDemux for Dm500HD/DM800 and DM8000
+ ;
+ else if (cap & capDecode)
+ our_demux = 0;
+ }
+ else
+ demux = *our_demux;
+
return 0;
}
/* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
THEN DO A REAL FIX HERE! */
+ if (m_pvr_fd_dst < 0)
+ {
/* (this codepath needs to be improved anyway.) */
#if HAVE_DVB_API_VERSION < 3
- m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
+ m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
#else
- m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
+ 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.
- return -ENODEV;
+ 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.
+ return -ENODEV;
+ }
}
m_pvr_thread = new eDVBChannelFilePush();
m_pvr_thread->setStreamMode(1);
m_pvr_thread->setScatterGather(this);
+ m_event(this, evtPreStart);
+
if (m_pvr_thread->start(file, m_pvr_fd_dst))
{
delete m_pvr_thread;
m_pvr_thread = 0;
+ ::close(m_pvr_fd_dst);
+ m_pvr_fd_dst = -1;
eDebug("can't open PVR file %s (%m)", file);
return -ENOENT;
}
if (m_pvr_thread)
{
m_pvr_thread->stop();
- ::close(m_pvr_fd_dst);
delete m_pvr_thread;
m_pvr_thread = 0;
}
+ if (m_pvr_fd_dst >= 0)
+ ::close(m_pvr_fd_dst);
}
void eDVBChannel::setCueSheet(eCueSheet *cuesheet)