if (i == m_demux.end())
return -1;
+ int n=0;
/* FIXME: hardware demux policy */
if (!(cap & iDVBChannel::capDecode))
- ++i;
+ ++i, ++n;
- for (; i != m_demux.end(); ++i)
+ for (; i != m_demux.end(); ++i, ++n)
if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
{
+ if ((cap & iDVBChannel::capDecode) && n)
+ continue;
+
demux = new eDVBAllocatedDemux(i);
- eDebug("demux found");
+ if (fe)
+ demux->get().setSourceFrontend(fe->m_frontend->getID());
+ else
+ demux->get().setSourcePVR(0);
return 0;
}
eDebug("demux not found");
m_channel_id = channelid;
m_mgr->addChannel(channelid, this);
m_state = state_tuning;
- return m_frontend->get().tune(*feparm);
+ /* if tuning fails, shutdown the channel immediately. */
+ int res;
+ res = m_frontend->get().tune(*feparm);
+
+ if (res)
+ {
+ m_state = state_release;
+ m_stateChanged(this);
+ return res;
+ }
+
+ return 0;
}
RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
{
+ eDebug("get %d demux", cap);
ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
if (!our_demux)
demux = 0;
if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
- return 0;
+ return -1;
+
}
demux = *our_demux;
+ if (cap & capDecode)
+ {
+ our_demux = 0;
+ }
return 0;
}
return 0;
}
-RESULT eDVBChannel::seekTo(pts_t &pts)
+RESULT eDVBChannel::seekTo(int relative, pts_t &pts)
{
-#if 0
- eDebug("eDVBChannel: seekTo .. %llx", pts);
- m_pvr_thread->pause();
- if (m_decoder_demux)
- m_decoder_demux->get().flush();
- /* demux will also flush all decoder.. */
+ int bitrate = m_tstools.calcBitrate(); /* in bits/s */
- off_t r;
+ if (bitrate == -1)
+ return -1;
- if (!m_tstools.getPosition(pts, r));
- m_pvr_thread->seek(r);
- else
- eDebug("getPosition failed!");
- m_pvr_thread->resume();
-#endif
+ if (relative)
+ {
+ pts_t now;
+ if (getCurrentPosition(now))
+ {
+ eDebug("seekTo: getCurrentPosition failed!");
+ return -1;
+ }
+ pts += now;
+ }
+
+ if (pts < 0)
+ pts = 0;
+
+ off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
+
+ seekToPosition(offset);
return 0;
}
-RESULT eDVBChannel::seekToPosition(int relative, const off_t &r)
+RESULT eDVBChannel::seekToPosition(const off_t &r)
{
/* when seeking, we have to ensure that all buffers are flushed.
there are basically 3 buffers:
m_decoder_demux->get().flush();
/* demux will also flush all decoder.. */
- m_pvr_thread->seek(relative ? SEEK_CUR : SEEK_SET, r);
+ m_pvr_thread->seek(SEEK_SET, r);
m_pvr_thread->resume();
return 0;
}