X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fdvb.cpp;h=ce096039c1c61477ffc028ab6bb24868bed67c89;hp=399e9f58b2593eaa06c3c2e1d52d8f4e8ab2ffa3;hb=68d8c8097853dca09312fc40fadb44956ffdca92;hpb=a995c63c0d6c24bbe23935b901bf735c18833adb diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 399e9f5..ce09603 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -98,6 +98,8 @@ eDVBResourceManager::eDVBResourceManager() m_boxtype = DM500HD; else if (!strncmp(tmp, "dm800se\n", rd)) m_boxtype = DM800SE; + else if (!strncmp(tmp, "dm7020hd\n", rd)) + m_boxtype = DM7020HD; else { eDebug("boxtype detection via /proc/stb/info not possible... use fallback via demux count!\n"); if (m_demux.size() == 3) @@ -108,7 +110,7 @@ eDVBResourceManager::eDVBResourceManager() m_boxtype = DM8000; } - eDebug("found %d adapter, %d frontends(%d sim) and %d demux, boxtype %d", + eDebug("found %zd adapter, %zd frontends(%zd sim) and %zd demux, boxtype %d", m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size(), m_boxtype); eDVBCAService::registerChannelCallback(this); @@ -143,19 +145,20 @@ eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr) #endif if (stat(filename, &s)) break; - ePtr fe; + eDVBFrontend *fe; { int ok = 0; - fe = new eDVBFrontend(m_nr, num_fe, ok); + fe = new eDVBFrontend(m_nr, num_fe, ok, true); if (ok) - m_frontend.push_back(fe); + m_simulate_frontend.push_back(ePtr(fe)); } + { int ok = 0; - fe = new eDVBFrontend(m_nr, num_fe, ok, true); + fe = new eDVBFrontend(m_nr, num_fe, ok, false, fe); if (ok) - m_simulate_frontend.push_back(fe); + m_frontend.push_back(ePtr(fe)); } ++num_fe; } @@ -334,7 +337,7 @@ PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list) } if (assigned != m_frontend.size()) { char blasel[256]; - sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations .. assigned %d socket informations, but %d registered frontends!", + sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations .. assigned %zd socket informations, but %d registered frontends!", m_frontend.size(), assigned); PyErr_SetString(PyExc_StandardError, blasel); return NULL; @@ -520,32 +523,48 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtrm_adapter : m_adapter.begin(); /* look for a demux on the same adapter as the frontend, or the first adapter for dvr playback */ + int source = fe ? fe->m_frontend->getDVBID() : -1; cap |= capHoldDecodeReference; // this is checked in eDVBChannel::getDemux - for (; i != m_demux.end(); ++i, ++n) + if (!fe) { - if (fe) + /* + * For pvr playback, start with the last demux. + * On some hardware, we have less ca devices than demuxes, + * so we should try to leave the first demuxes for live tv, + * and start with the last for pvr playback + */ + i = m_demux.end(); + --i; + } + while (i != m_demux.end()) + { + if (i->m_adapter == adapter) { if (!i->m_inuse) { - if (!unused) - unused = i; + /* mark the first unused demux, we'll use that when we do not find a better match */ + if (!unused) unused = i; } - else if (i->m_adapter == fe->m_adapter && - i->m_demux->getSource() == fe->m_frontend->getDVBID()) + else { - demux = new eDVBAllocatedDemux(i); - return 0; + /* demux is in use, see if we can share it */ + if (source >= 0 && i->m_demux->getSource() == source) + { + demux = new eDVBAllocatedDemux(i); + return 0; + } } } - else if (n == 4) // always use demux4 for PVR (demux 4 can not descramble...) + if (fe) { - if (i->m_inuse) { - demux = new eDVBAllocatedDemux(i); - return 0; - } - unused = i; + ++i; + } + else + { + --i; } } } @@ -716,8 +735,7 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr &channel, in return 0; } - -RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr &channel) +RESULT eDVBResourceManager::allocatePVRChannel(const eDVBChannelID &channelid, eUsePtr &channel) { ePtr demux; @@ -728,7 +746,18 @@ RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr &channel) m_releaseCachedChannelTimer->stop(); } - channel = new eDVBChannel(this, 0); + ePtr ch = new eDVBChannel(this, 0); + if (channelid) + { + /* + * user provided a channelid, with the clear intention for + * this channel to be registered at the resource manager. + * (allowing e.g. epgcache to be started) + */ + ePtr feparm; + ch->setChannel(channelid, feparm); + } + channel = ch; return 0; } @@ -1184,8 +1213,22 @@ void eDVBChannel::frontendStateChanged(iDVBFrontend*fe) } } else if (state == iDVBFrontend::stateFailed) { +#ifdef BUILD_VUPLUS /* ikseong */ + if (m_current_frontend_parameters) + { + eDebug("OURSTATE: lost lock, trying to retune"); + ourstate = state_tuning; + m_frontend->get().tune(*m_current_frontend_parameters); + } + else + { + eDebug("OURSTATE: failed"); + ourstate = state_failed; + } +#else eDebug("OURSTATE: failed"); ourstate = state_failed; +#endif } else eFatal("state unknown"); @@ -1488,7 +1531,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off size = max; else size = aligned_end - current_offset; - eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size); + eDebug("HIT, %lld < %lld < %lld, size: %zd", i->first, current_offset, i->second, size); return; } if (current_offset < aligned_start) @@ -1529,10 +1572,10 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off len = aligned_end - aligned_start; start = aligned_end - len; - eDebug("skipping to %llx, %d", start, len); + eDebug("skipping to %llx, %zd", start, len); } - eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end); + eDebug("result: %llx, %zx (%llx %llx)", start, size, aligned_start, aligned_end); return; } } @@ -1548,7 +1591,7 @@ void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off { start = current_offset; size = max; - eDebug("NO CUESHEET. (%08llx, %d)", start, size); + eDebug("NO CUESHEET. (%08llx, %zd)", start, size); } else { start = current_offset; @@ -1588,14 +1631,15 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtraddChannel(channelid, this); + if (!m_frontend) { - eDebug("no frontend to tune!"); - return -ENODEV; + /* no frontend, no need to tune (must be a streamed service) */ + return 0; } - m_channel_id = channelid; - m_mgr->addChannel(channelid, this); m_state = state_tuning; /* if tuning fails, shutdown the channel immediately. */ int res; @@ -1706,6 +1750,12 @@ RESULT eDVBChannel::getDemux(ePtr &demux, int cap) { ePtr &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux; + if (m_frontend == NULL) + { + /* in dvr mode, we have to stick to a single demux (the one connected to our dvr device) */ + our_demux = m_decoder_demux ? m_decoder_demux : m_demux; + } + if (!our_demux) { demux = 0; @@ -1816,7 +1866,8 @@ RESULT eDVBChannel::playSource(ePtr &source, const char *streaminfo_f m_pvr_thread = new eDVBChannelFilePush(); m_pvr_thread->enablePVRCommit(1); - m_pvr_thread->setStreamMode(1); + /* If the source specifies a length, it's a file. If not, it's a stream */ + m_pvr_thread->setStreamMode(source->length() <= 0); m_pvr_thread->setScatterGather(this); m_event(this, evtPreStart);