X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/23876b6f15422655b8c180682b10a09302444bef..97d46aee1158e549c110d66a0e1c4185c3cbbdf3:/lib/dvb/dvb.cpp diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index a7428493..6eaadb04 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -82,8 +82,32 @@ eDVBResourceManager::eDVBResourceManager() 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); @@ -414,7 +438,9 @@ alloc_fe_by_id_not_possible: return err; } -RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr &demux, int cap) +#define capHoldDecodeReference 64 + +RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr &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. */ @@ -429,8 +455,9 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr 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) @@ -438,16 +465,26 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtrm_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)) @@ -474,8 +511,9 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr &demux, int cap) 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; } @@ -1705,16 +1746,19 @@ RESULT eDVBChannel::playFile(const char *file) /* 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(); @@ -1722,10 +1766,14 @@ RESULT eDVBChannel::playFile(const char *file) 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; } @@ -1742,10 +1790,11 @@ void eDVBChannel::stopFile() 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)