int n=0;
/* FIXME: hardware demux policy */
if (!(cap & iDVBChannel::capDecode))
- ++i, ++n;
+ {
+ if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
+ {
+ ++i, ++n;
+ ++i, ++n;
+ }
+ }
for (; i != m_demux.end(); ++i, ++n)
- if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
+ {
+ int is_decode = n < 2;
+
+ int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
+
+ if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
{
- if ((cap & iDVBChannel::capDecode) && n)
+ if ((cap & iDVBChannel::capDecode) && !is_decode)
continue;
demux = new eDVBAllocatedDemux(i);
demux->get().setSourcePVR(0);
return 0;
}
+ }
eDebug("demux not found");
return -1;
}
{
ePtr<eDVBAllocatedDemux> demux;
+ if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
+ {
+ m_cached_channel_state_changed_conn.disconnect();
+ m_cached_channel=0;
+ m_releaseCachedChannelTimer.stop();
+ }
+
eDVBChannel *ch;
ch = new eDVBChannel(this, 0);
-
+
channel = ch;
return 0;
}
if (i->m_channel_id == ignore)
{
eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
- if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
+ // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
+ // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
+ // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
+ // or 2 when the cached channel is not equal to the compared channel
+ if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
{
ePtr<iDVBFrontend> fe;
if (!i->m_channel->getFrontend(fe))
if ((current_offset >= i->first) && (current_offset < i->second))
{
start = current_offset;
- size = i->second - current_offset;
- if (size > max)
+ /* max can not exceed max(size_t). i->second - current_offset, however, can. */
+ if ((i->second - current_offset) > max)
size = max;
- eDebug("HIT, %lld < %lld < %lld", i->first, current_offset, i->second);
+ else
+ size = i->second - current_offset;
+ eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
return;
}
if (current_offset < i->first)
{
/* in normal playback, just start at the next zone. */
start = i->first;
- size = i->second - i->first;
- if (size > max)
+
+ /* size is not 64bit! */
+ if ((i->second - i->first) > max)
size = max;
+ else
+ size = i->second - i->first;
+
eDebug("skip");
if (m_skipmode_m < 0)
{
/* 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("skipping to %llx, %d", start, size);
+ size_t len;
+
+ if ((i->second - i->first) > max)
+ len = max;
+ else
+ len = i->second - i->first;
+
+ start = i->second - len;
+ eDebug("skipping to %llx, %d", start, len);
}
return;
}
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;
return 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_state = state_ok;
- m_stateChanged(this);
-
+
m_pvr_thread = new eFilePushThread();
m_pvr_thread->enablePVRCommit(1);
m_pvr_thread->setScatterGather(this);
}
CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
+ m_state = state_ok;
+ m_stateChanged(this);
+
return 0;
}