pts: as the decoding demux isn't stored in the dvbchannel (it could be shared, and...
[enigma2.git] / lib / dvb / dvb.cpp
index bd3571a6d446e39cd2df5278c322fae007e2719e..04c2b40eaf2f7edf49e49dcfb11d4c2718453a36 100644 (file)
@@ -197,20 +197,39 @@ void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
        for (i=0; i<num_fe; ++i)
        {
                ePtr<eDVBFrontend> frontend;
+
                if (!adapter->getFrontend(frontend, i))
+               {
+                       frontend->setSEC(m_sec);
                        m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
+               }
        }
 }
 
-RESULT eDVBResourceManager::allocateFrontend(const eDVBChannelID &chid, ePtr<eDVBAllocatedFrontend> &fe)
+RESULT eDVBResourceManager::allocateFrontend(ePtr<iDVBFrontendParameters> &feparm, ePtr<eDVBAllocatedFrontend> &fe)
 {
-               /* find first unused frontend. we ignore compatibility for now. */
+       ePtr<eDVBRegisteredFrontend> best;
+       int bestval = 0;
+
        for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
                if (!i->m_inuse)
                {
-                       fe = new eDVBAllocatedFrontend(i);
-                       return 0;
+                       int c = i->m_frontend->isCompatibleWith(feparm);
+                       if (c > bestval)
+                       {
+                               c = bestval;
+                               best = i;
+                       }
                }
+
+       if (best)
+       {
+               fe = new eDVBAllocatedFrontend(best);
+               return 0;
+       }
+       
+       fe = 0;
+       
        return -1;
 }
 
@@ -279,13 +298,26 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse
                }
        }
        
-               /* no currently available channel is tuned to this channelid. create a new one, if possible. */
-               
-               /* allocate a frontend. */
+       /* no currently available channel is tuned to this channelid. create a new one, if possible. */
+
+       if (!m_list)
+       {
+               eDebug("no channel list set!");
+               return -ENOENT;
+       }
+
+       ePtr<iDVBFrontendParameters> feparm;
+       if (m_list->getChannelFrontendData(channelid, feparm))
+       {
+               eDebug("channel not found!");
+               return -ENOENT;
+       }
+
+       /* allocate a frontend. */
        
        ePtr<eDVBAllocatedFrontend> fe;
        
-       if (allocateFrontend(channelid, fe))
+       if (allocateFrontend(feparm, fe))
                return errNoFrontend;
        
 // will be allocated on demand:
@@ -293,16 +325,12 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse
 //     
 //     if (allocateDemux(*fe, demux))
 //             return errNoDemux;
-       
+
        RESULT res;
        ePtr<eDVBChannel> ch;
        ch = new eDVBChannel(this, fe);
 
-       ePtr<iDVBFrontend> myfe;
-       if (!ch->getFrontend(myfe))
-               myfe->setSEC(m_sec);
-
-       res = ch->setChannel(channelid);
+       res = ch->setChannel(channelid, feparm);
        if (res)
        {
                channel = 0;
@@ -316,8 +344,10 @@ RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUse
 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel)
 {
        ePtr<eDVBAllocatedFrontend> fe;
-       
-       if (allocateFrontend(eDVBChannelID(), fe))
+
+#warning FIXME allocateRawChannel
+
+//     if (allocateFrontend(eDVBChannelID(), fe))
                return errNoFrontend;
        
 //     ePtr<eDVBAllocatedDemux> demux;
@@ -328,10 +358,6 @@ RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel)
        eDVBChannel *ch;
        ch = new eDVBChannel(this, fe);
 
-       ePtr<iDVBFrontend> myfe;
-       if (!ch->getFrontend(myfe))
-               myfe->setSEC(m_sec);
-
        channel = ch;
        return 0;
 }
@@ -459,7 +485,7 @@ void eDVBChannel::ReleaseUse()
        }
 }
 
-RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid)
+RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
 {
        if (m_channel_id)
                m_mgr->removeChannel(this);
@@ -467,24 +493,6 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid)
        if (!channelid)
                return 0;
 
-       ePtr<iDVBChannelList> list;
-       
-       if (m_mgr->getChannelList(list))
-       {
-               eDebug("no channel list set!");
-               return -ENOENT;
-       }
-       
-       eDebug("tuning to chid: ns: %08x tsid %04x onid %04x",
-               channelid.dvbnamespace.get(), channelid.transport_stream_id.get(), channelid.original_network_id.get());
-
-       ePtr<iDVBFrontendParameters> feparm;
-       if (list->getChannelFrontendData(channelid, feparm))
-       {
-               eDebug("channel not found!");
-               return -ENOENT;
-       }
-       
        if (!m_frontend)
        {
                eDebug("no frontend to tune!");
@@ -575,7 +583,7 @@ RESULT eDVBChannel::playFile(const char *file)
        m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
        if (m_pvr_fd_dst < 0)
        {
-               eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)");
+               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;
        }
        
@@ -601,9 +609,9 @@ RESULT eDVBChannel::getLength(pts_t &len)
        return m_tstools.calcLen(len);
 }
 
-RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
+RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
 {
-       if (!m_decoder_demux)
+       if (!decoding_demux)
                return -1;
        
        off_t begin = 0;
@@ -617,7 +625,7 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
        
        pts_t now;
        
-       r = m_decoder_demux->get().getSTC(now);
+       r = decoding_demux->getSTC(now);
 
        if (r)
        {
@@ -642,7 +650,7 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
        return 0;
 }
 
-RESULT eDVBChannel::seekTo(int relative, pts_t &pts)
+RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
 {
        int bitrate = m_tstools.calcBitrate(); /* in bits/s */
        
@@ -652,7 +660,7 @@ RESULT eDVBChannel::seekTo(int relative, pts_t &pts)
        if (relative)
        {
                pts_t now;
-               if (getCurrentPosition(now))
+               if (getCurrentPosition(decoding_demux, now))
                {
                        eDebug("seekTo: getCurrentPosition failed!");
                        return -1;
@@ -665,11 +673,11 @@ RESULT eDVBChannel::seekTo(int relative, pts_t &pts)
        
        off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
        
-       seekToPosition(offset);
+       seekToPosition(decoding_demux, offset);
        return 0;
 }
 
-RESULT eDVBChannel::seekToPosition(const off_t &r)
+RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
 {
                        /* when seeking, we have to ensure that all buffers are flushed.
                           there are basically 3 buffers:
@@ -691,8 +699,8 @@ RESULT eDVBChannel::seekToPosition(const off_t &r)
        ::ioctl(m_pvr_fd_dst, 0);
        
                /* flush ratebuffers (video, audio) */
-       if (m_decoder_demux)
-               m_decoder_demux->get().flush();
+       if (decoding_demux)
+               decoding_demux->flush();
 
                /* demux will also flush all decoder.. */
        m_pvr_thread->seek(SEEK_SET, r);