initialize self.list
[enigma2.git] / lib / service / servicedvb.cpp
index 790ca2f7bd736a92a2c175ab63aba7b7eb9a4f3a..53bc17a8d8c82fe7699520a1c6ec98fa16477a8f 100644 (file)
@@ -6,7 +6,6 @@
 #include <lib/base/estring.h>
 #include <lib/base/init_num.h>
 #include <lib/base/init.h>
-#include <lib/base/nconfig.h> // access to python config
 #include <lib/dvb/dvb.h>
 #include <lib/dvb/db.h>
 #include <lib/dvb/decoder.h>
@@ -17,6 +16,7 @@
 #include <lib/dvb/metaparser.h>
 #include <lib/dvb/tstools.h>
 #include <lib/python/python.h>
+#include <lib/base/nconfig.h> // access to python config
 
                /* for subtitles */
 #include <lib/gui/esubtitle.h>
@@ -428,13 +428,38 @@ int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref
                        return 0;
                }
 
+               int prio_order = eDVBFrontend::getTypePriorityOrder();
                int cur=0;
                eDVBChannelID chid, chid_ignore;
                ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
                for (std::list<eServiceReference>::iterator it(bouquet->m_services.begin()); it != bouquet->m_services.end(); ++it)
                {
+                       static unsigned char prio_map[6][3] = {
+                               { 3, 2, 1 }, // -S -C -T
+                               { 3, 1, 2 }, // -S -T -C
+                               { 2, 3, 1 }, // -C -S -T
+                               { 1, 3, 2 }, // -C -T -S
+                               { 1, 2, 3 }, // -T -C -S
+                               { 2, 1, 3 }  // -T -S -C
+                       };
                        ((const eServiceReferenceDVB&)*it).getChannelID(chid);
                        int tmp=res->canAllocateChannel(chid, chid_ignore);
+                       switch(tmp)
+                       {
+                               case 0:
+                                       break;
+                               case 30000: // cached DVB-T channel
+                               case 1: // DVB-T frontend
+                                       tmp = prio_map[prio_order][2];
+                                       break;
+                               case 40000: // cached DVB-C channel
+                               case 2:
+                                       tmp = prio_map[prio_order][1];
+                                       break;
+                               default: // DVB-S
+                                       tmp = prio_map[prio_order][0];
+                                       break;
+                       }
                        if (tmp > cur)
                        {
                                m_playable_service = *it;
@@ -1025,7 +1050,7 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        m_subtitle_widget = 0;
        
        m_tune_state = -1;
-       
+
        CONNECT(m_subtitle_sync_timer.timeout, eDVBServicePlay::checkSubtitleTiming);
 }
 
@@ -1345,6 +1370,9 @@ RESULT eDVBServicePlay::seekTo(pts_t to)
                return -1;
        
        m_cue->seekTo(0, to);
+       m_dvb_subtitle_pages.clear();
+       m_subtitle_pages.clear();
+
        return 0;
 }
 
@@ -1372,6 +1400,8 @@ RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
                return 0;
        
        m_cue->seekTo(mode, to);
+       m_dvb_subtitle_pages.clear();
+       m_subtitle_pages.clear();
        return 0;
 }
 
@@ -1694,6 +1724,8 @@ RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int
        if (i >= program.audioStreams.size())
                return -2;
        
+       info.m_pid = program.audioStreams[i].pid;
+
        if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
                info.m_description = "MPEG";
        else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
@@ -1730,7 +1762,7 @@ int eDVBServicePlay::selectAudioStream(int i)
        if (h.getProgramInfo(program))
                return -1;
 
-       if ((unsigned int)i >= program.audioStreams.size())
+       if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
                return -2;
 
        if (!m_decoder)
@@ -1740,16 +1772,37 @@ int eDVBServicePlay::selectAudioStream(int i)
        if (stream == -1)
                stream = program.defaultAudioStream;
 
-       m_current_audio_pid = program.audioStreams[stream].pid;
+       int apid = -1, apidtype = -1;
 
-       if (m_decoder->setAudioPID(program.audioStreams[stream].pid, program.audioStreams[stream].type))
+       if (((unsigned int)stream) < program.audioStreams.size())
+       {
+               apid = program.audioStreams[stream].pid;
+               apidtype = program.audioStreams[stream].type;
+       }
+
+       m_current_audio_pid = apid;
+
+       if (m_decoder->setAudioPID(apid, apidtype))
        {
                eDebug("set audio pid failed");
                return -4;
        }
 
+               /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
+       if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
+               if (!m_rds_decoder)
+               {
+                       ePtr<iDVBDemux> data_demux;
+                       if (!h.getDataDemux(data_demux))
+                       {
+                               m_rds_decoder = new eDVBRdsDecoder(data_demux);
+                               m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+                       }
+               }
+
+               /* if we decided that we need one, update the pid */
        if (m_rds_decoder)
-               m_rds_decoder->start(program.audioStreams[stream].pid);
+               m_rds_decoder->start(apid);
 
                        /* store new pid as default only when:
                                a.) we have an entry in the service db for the current service,
@@ -1758,17 +1811,18 @@ int eDVBServicePlay::selectAudioStream(int i)
                                    anything in the best case, or destroy the default setting in
                                    case the real default is not yet available.)
                        */
-       if (m_dvb_service && !m_is_pvr && (i != -1))
+       if (m_dvb_service && !m_is_pvr && ((i != -1)
+               || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
        {
-               if (program.audioStreams[stream].type == eDVBAudio::aMPEG)
+               if (apidtype == eDVBAudio::aMPEG)
                {
-                       m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[stream].pid);
+                       m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
                        m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
                }
                else
                {
                        m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
-                       m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[stream].pid);
+                       m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
                }
        }
 
@@ -2248,16 +2302,10 @@ void eDVBServicePlay::switchToTimeshift()
 
 void eDVBServicePlay::updateDecoder()
 {
-       int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
+       int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
 
        eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
 
-       bool defaultac3=false;
-       std::string default_ac3;
-
-       if (!ePythonConfigQuery::getConfigValue("config.av.defaultac3", default_ac3))
-               defaultac3 = default_ac3 == "True";
-
        eDVBServicePMTHandler::program program;
        if (h.getProgramInfo(program))
                eDebug("getting program info failed.");
@@ -2290,14 +2338,6 @@ void eDVBServicePlay::updateDecoder()
                                i(program.audioStreams.begin());
                                i != program.audioStreams.end(); ++i)
                        {
-                               if (apid == -1 || (apidtype == eDVBAudio::aMPEG && defaultac3))
-                               {
-                                       if ( apid == -1 || (i->type != eDVBAudio::aMPEG) )
-                                       {
-                                               apid = i->pid;
-                                               apidtype = i->type;
-                                       }
-                               }
                                if (i != program.audioStreams.begin())
                                        eDebugNoNewLine(", ");
                                eDebugNoNewLine("%04x", i->pid);
@@ -2372,19 +2412,7 @@ void eDVBServicePlay::updateDecoder()
                selectAudioStream();
 
                if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
-               {
                        m_decoder->setSyncPCR(pcrpid);
-                       if (apid != -1)
-                       {
-                               ePtr<iDVBDemux> data_demux;
-                               if (!h.getDataDemux(data_demux))
-                               {
-                                       m_rds_decoder = new eDVBRdsDecoder(data_demux);
-                                       m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
-                                       m_rds_decoder->start(apid);
-                               }
-                       }
-               }
                else
                        m_decoder->setSyncPCR(-1);
 
@@ -2411,23 +2439,10 @@ void eDVBServicePlay::updateDecoder()
 
                m_decoder->setAudioChannel(achannel);
 
-// how we can do this better?
-// update cache pid when the user changed the audio track or video track
-// TODO handling of difference audio types.. default audio types..
-
                /* don't worry about non-existing services, nor pvr services */
                if (m_dvb_service && !m_is_pvr)
                {
-                       if (apidtype == eDVBAudio::aMPEG)
-                       {
-                               m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
-                               m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
-                       }
-                       else
-                       {
-                               m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
-                               m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
-                       }
+                               /* (audio pid will be set in selectAudioTrack */
                        m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
                        m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
                        m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
@@ -2786,6 +2801,10 @@ void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
 {
        if (m_subtitle_widget)
        {
+               pts_t pos = 0;
+               if (m_decoder)
+                       m_decoder->getPTS(0, pos);
+               eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
                m_subtitle_pages.push_back(page);
                checkSubtitleTiming();
        }
@@ -2793,7 +2812,7 @@ void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
 
 void eDVBServicePlay::checkSubtitleTiming()
 {
-//     eDebug("checkSubtitleTiming");
+       eDebug("checkSubtitleTiming");
        if (!m_subtitle_widget)
                return;
        while (1)
@@ -2822,36 +2841,36 @@ void eDVBServicePlay::checkSubtitleTiming()
                if (m_decoder)
                        m_decoder->getPTS(0, pos);
 
-//             eDebug("%lld %lld", pos, show_time);
+               eDebug("%lld %lld", pos, show_time);
                int diff =  show_time - pos;
                if (diff < 0)
                {
                        eDebug("[late (%d ms)]", -diff / 90);
                        diff = 0;
                }
-               if (diff > 900000)
-               {
-                       eDebug("[invalid]");
-                       diff = 0;
-               }
+//             if (diff > 900000)
+//             {
+//                     eDebug("[invalid]");
+//                     diff = 0;
+//             }
        
-               if (!diff)
+               if ((diff/90)<20)
                {
                        if (type == TELETEXT)
                        {
-                               eDebug("display teletext subtitle page");
+                               eDebug("display teletext subtitle page %lld", show_time);
                                m_subtitle_widget->setPage(page);
                                m_subtitle_pages.pop_front();
                        }
                        else
                        {
-                               eDebug("display dvb subtitle Page");
+                               eDebug("display dvb subtitle Page %lld", show_time);
                                m_subtitle_widget->setPage(dvb_page);
                                m_dvb_subtitle_pages.pop_front();
                        }
                } else
                {
-//                     eDebug("start subtitle delay %d", diff / 90);
+                       eDebug("start subtitle delay %d", diff / 90);
                        m_subtitle_sync_timer.start(diff / 90, 1);
                        break;
                }
@@ -2862,6 +2881,10 @@ void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
 {
        if (m_subtitle_widget)
        {
+               pts_t pos = 0;
+               if (m_decoder)
+                       m_decoder->getPTS(0, pos);
+               eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
                m_dvb_subtitle_pages.push_back(p);
                checkSubtitleTiming();
        }