add support for rds data on own pids (i.e. hitradio ffh, harmony fm)
[enigma2.git] / lib / service / servicedvb.cpp
index e62d7783e8104b2eb7c49837ebd48d1d58fd8dd7..d04039dfba8ec3a7973fc6de60c1e08574012048 100644 (file)
@@ -920,7 +920,7 @@ eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *serv
        m_is_primary = 1;
        m_is_pvr = !m_reference.path.empty();
        
-       m_timeshift_enabled = m_timeshift_active = 0;
+       m_timeshift_enabled = m_timeshift_active = 0, m_timeshift_changed = 0;
        m_skipmode = 0;
        
        CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
@@ -1758,21 +1758,26 @@ int eDVBServicePlay::selectAudioStream(int i)
                return -4;
        }
 
+       int rdsPid = apid;
+
                /* 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)
+       {
+               int different_pid = program.videoStreams.empty() && program.audioStreams.size() == 1 && program.audioStreams[stream].rdsPid != -1;
+               if (different_pid)
+                       rdsPid = program.audioStreams[stream].rdsPid;
+               if (!m_rds_decoder || m_rds_decoder->getPid() != rdsPid)
                {
+                       m_rds_decoder = 0;
                        ePtr<iDVBDemux> data_demux;
                        if (!h.getDataDemux(data_demux))
                        {
-                               m_rds_decoder = new eDVBRdsDecoder(data_demux);
+                               m_rds_decoder = new eDVBRdsDecoder(data_demux, different_pid);
                                m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
+                               m_rds_decoder->start(rdsPid);
                        }
                }
-
-               /* if we decided that we need one, update the pid */
-       if (m_rds_decoder)
-               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,
@@ -2229,6 +2234,7 @@ void eDVBServicePlay::switchToLive()
                /* free the timeshift service handler, we need the resources */
        m_service_handler_timeshift.free();
        m_timeshift_active = 0;
+       m_timeshift_changed = 1;
 
        m_event((iPlayableService*)this, evSeekableStatusChanged);
 
@@ -2251,6 +2257,7 @@ void eDVBServicePlay::switchToTimeshift()
        m_video_event_connection = 0;
 
        m_timeshift_active = 1;
+       m_timeshift_changed = 1;
 
        eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
        r.path = m_timeshift_file;
@@ -2318,28 +2325,43 @@ void eDVBServicePlay::updateDecoder()
        if (!m_decoder)
        {
                h.getDecodeDemux(m_decode_demux);
+               if (m_timeshift_changed)
+                       m_decoder = 0;
                if (m_decode_demux)
                {
                        m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
                        if (m_decoder)
                                m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
+                       if (m_is_primary)
+                       {
+                               m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
+                               m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
+                               m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
+                               m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
+                               if (m_timeshift_changed)
+                               {
+                                       ePyObject subs = getCachedSubtitle();
+                                       if (subs != Py_None)
+                                       {
+                                               int type = PyInt_AsLong(PyTuple_GET_ITEM(subs, 0)),
+                                                   pid = PyInt_AsLong(PyTuple_GET_ITEM(subs, 1)),
+                                                   comp_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 2)), // ttx page
+                                                   anc_page = PyInt_AsLong(PyTuple_GET_ITEM(subs, 3)); // ttx magazine
+                                               if (type == 0) // dvb
+                                                       m_subtitle_parser->start(pid, comp_page, anc_page);
+                                               else if (type == 1) // ttx
+                                                       m_teletext_parser->setPageAndMagazine(comp_page, anc_page);
+                                       }
+                                       Py_DECREF(subs);
+                               }
+                       }
                }
-               if (m_decode_demux && m_is_primary)
-               {
-                       m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
-                       m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
-                       m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
-                       m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
-               } else
-               {
-                       m_teletext_parser = 0;
-                       m_subtitle_parser = 0;
-               }
-
                if (m_cue)
                        m_cue->setDecodingDemux(m_decode_demux, m_decoder);
        }
 
+       m_timeshift_changed = 0;
+
        if (m_decoder)
        {
                if (m_dvb_service)
@@ -2703,7 +2725,7 @@ PyObject *eDVBServicePlay::getCachedSubtitle()
                                        PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
                                else
                                        PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
-                               PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
+                               PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(pid)); // pid
                                PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
                                PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
                                return tuple;