free teletext parser references, this fixes timeshift when internal teletext decoder...
[enigma2.git] / lib / service / servicedvb.cpp
index de4f84ee691b3adf90eef027504182a148b956f7..f7da3a3bd3f48ebddd0f26a2ea163f1517718d73 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <dvbsi++/event_information_section.h>
 
-// #define INTERNAL_TELETEXT
+#define INTERNAL_TELETEXT
 
 #ifndef BYTE_ORDER
 #error no byte order defined!
@@ -630,7 +630,7 @@ RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServ
 }
 
 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service): 
-       m_reference(ref), m_dvb_service(service), m_is_paused(0)
+       m_reference(ref), m_dvb_service(service), m_is_paused(0), m_current_audio_channel(-1)
 {
        m_is_primary = 1;
        m_is_pvr = !m_reference.path.empty();
@@ -646,6 +646,8 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        m_cutlist_enabled = 1;
        
        m_subtitle_widget = 0;
+       
+       CONNECT(m_subtitle_sync_timer.timeout, eDVBServicePlay::checkSubtitleTiming);
 }
 
 eDVBServicePlay::~eDVBServicePlay()
@@ -1277,17 +1279,18 @@ int eDVBServicePlay::selectAudioStream(int i)
 
 int eDVBServicePlay::getCurrentChannel()
 {
-       int curChannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
-       return curChannel == -1 ? STEREO : curChannel;
+       return m_current_audio_channel == -1 ? STEREO : m_current_audio_channel;
 }
 
 RESULT eDVBServicePlay::selectChannel(int i)
 {
        if (i < iAudioChannelSelection::LEFT || i > iAudioChannelSelection::RIGHT)
                i = -1;  // Stereo
-       if (m_dvb_service->getCacheEntry(eDVBService::cACHANNEL) != i)
+       if (m_current_audio_channel != i)
        {
-               m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
+               if (m_dvb_service)
+                       m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
+               m_current_audio_channel=i;
                if (m_decoder)
                        m_decoder->setAudioChannel(i);
        }
@@ -1566,6 +1569,7 @@ void eDVBServicePlay::switchToLive()
        m_decoder = 0;
        m_decode_demux = 0;
        m_teletext_parser = 0;
+       m_new_subtitle_page_connection = 0;
        
                /* free the timeshift service handler, we need the resources */
        m_service_handler_timeshift.free();
@@ -1584,6 +1588,7 @@ void eDVBServicePlay::switchToTimeshift()
        m_decode_demux = 0;
        m_decoder = 0;
        m_teletext_parser = 0;
+       m_new_subtitle_page_connection = 0;
        
        m_timeshift_active = 1;
 
@@ -1683,18 +1688,18 @@ void eDVBServicePlay::updateDecoder()
                        m_decoder->setSyncPCR(pcrpid);
                else
                        m_decoder->setSyncPCR(-1);
-#ifndef INTERNAL_TELETEXT
+
                m_decoder->setTextPID(tpid);
-#else
+
                if (m_teletext_parser)
                        m_teletext_parser->start(tpid);
-#endif
 
                if (!m_is_primary)
                        m_decoder->setTrickmode(1);
 
                m_decoder->start();
 
+               m_current_audio_channel=achannel;
                m_decoder->setAudioChannel(achannel);
 
 // how we can do this better?
@@ -1843,13 +1848,23 @@ void eDVBServicePlay::cutlistToCuesheet()
        m_cue->commitSpans();
 }
 
-RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, int index)
+RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, PyObject *entry)
 {
        if (m_subtitle_widget)
                disableSubtitles(parent);
        
+       if (!m_teletext_parser)
+               return -1;
+       
+       if (!PyInt_Check(entry))
+               return -1;
+       
        m_subtitle_widget = new eSubtitleWidget(parent);
        m_subtitle_widget->resize(parent->size()); /* full size */
+       
+       int page = PyInt_AsLong(entry);
+       
+       m_teletext_parser->setPage(page);
 
        return 0;
 }
@@ -1861,16 +1876,75 @@ RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
        return 0;
 }
 
-RESULT eDVBServicePlay::getSubtitleList(PyList *list)
+PyObject *eDVBServicePlay::getSubtitleList()
 {
-       return -1;
+       if (!m_teletext_parser)
+       {
+               Py_INCREF(Py_None);
+               return Py_None;
+       }
+       
+       PyObject *l = PyList_New(0);
+       
+       for (std::set<int>::iterator i(m_teletext_parser->m_found_subtitle_pages.begin()); i != m_teletext_parser->m_found_subtitle_pages.end(); ++i)
+       {
+               PyObject *tuple = PyTuple_New(2);
+               char desc[20];
+               sprintf(desc, "Page %x", *i);
+               PyTuple_SetItem(tuple, 0, PyString_FromString(desc));
+               PyTuple_SetItem(tuple, 1, PyInt_FromLong(*i));
+               PyList_Append(l, tuple);
+       }
+       
+       return l;
 }
 
 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
 {
-       eDebug("new subtitle page received!");
        if (m_subtitle_widget)
-               m_subtitle_widget->addPage(page);
+       {
+               m_subtitle_pages.push_back(page);
+               
+               checkSubtitleTiming();
+       }
+}
+
+void eDVBServicePlay::checkSubtitleTiming()
+{
+       while (1)
+       {
+               if (m_subtitle_pages.empty())
+                       return;
+       
+               eDVBTeletextSubtitlePage p = m_subtitle_pages.front();
+       
+               pts_t pos = 0;
+       
+               if (m_decoder)
+                       m_decoder->getPTS(0, pos);
+       
+               int diff = p.m_pts - pos;
+               if (diff < 0)
+               {
+                       eDebug("[late (%d ms)]", -diff / 90);
+                       diff = 0;
+               }
+               if (diff > 900000)
+               {
+                       eDebug("[invalid]");
+                       diff = 0;
+               }
+       
+               if (!diff)
+               {
+                       m_subtitle_widget->setPage(p);
+                       m_subtitle_pages.pop_front();
+               } else
+               {
+                       m_subtitle_sync_timer.start(diff / 90, 1);
+                       break;
+               }
+       }
 }
 
 DEFINE_REF(eDVBServicePlay)