remove fatal debug message
[enigma2.git] / lib / dvb / dvb.cpp
index a2a37758c37cdda449bf5f14a4cced62503e4fdf..deb5042bb75da4e3674fc7124daba85a42fef4aa 100644 (file)
@@ -9,6 +9,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
 
 DEFINE_REF(eDVBRegisteredFrontend);
 DEFINE_REF(eDVBRegisteredDemux);
@@ -224,15 +225,22 @@ RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBA
        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");
@@ -346,7 +354,7 @@ RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
 {
        m_active_channels.push_back(active_channel(chid, ch));
-       /* emit */ m_channelAdded(ch);
+//     /* emit */ m_channelAdded(ch);
        return 0;
 }
 
@@ -486,7 +494,18 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid)
        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)
@@ -508,6 +527,7 @@ RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
 
 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)
@@ -515,10 +535,15 @@ RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
                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;
 }
 
@@ -617,32 +642,60 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
        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:
+                          a.) the filepush's internal buffer
+                          b.) the PVR buffer (before demux)
+                          c.) the ratebuffer (after demux)
+                          
+                          it's important to clear them in the correct order, otherwise
+                          the ratebuffer (for example) would immediately refill from
+                          the not-yet-flushed PVR buffer.
+                       */
        eDebug("eDVBChannel: seekToPosition .. %llx", r);
        m_pvr_thread->pause();
+
+               /* flush internal filepush buffer */
+       m_pvr_thread->flush();
+
+               /* HACK: flush PVR buffer */
+       ::ioctl(m_pvr_fd_dst, 0);
+       
+               /* flush ratebuffers (video, audio) */
        if (m_decoder_demux)
                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;
 }