add support for radiotext (python gui component missing yet)
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Wed, 16 Aug 2006 23:43:29 +0000 (23:43 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Wed, 16 Aug 2006 23:43:29 +0000 (23:43 +0000)
lib/dvb/Makefile.am
lib/dvb/pesparse.cpp
lib/dvb/pesparse.h
lib/service/iservice.h
lib/service/servicedvb.cpp
lib/service/servicedvb.h
lib/service/servicemp3.h

index e5b14f38b6ac6a194d3bb3de4e659552123d8e2d..98f4030a18cb61f8606f6e5289af592f895d633a 100644 (file)
@@ -6,5 +6,5 @@ noinst_LIBRARIES = libenigma_dvb.a
 libenigma_dvb_a_SOURCES = dvb.cpp demux.cpp frontend.cpp esection.cpp db.cpp \
        sec.cpp scan.cpp crc32.cpp pmt.cpp decoder.cpp eit.cpp rotor_calc.cpp \
        epgcache.cpp dvbtime.cpp metaparser.cpp volume.cpp tstools.cpp pvrparse.cpp \
-       pesparse.cpp teletext.cpp
+       pesparse.cpp teletext.cpp radiotext.cpp
 
index 30e05894be105070478b805d3614b3a8ad084f92..da50c0400b8f51394a17b4e51dd5a5a227de93d7 100644 (file)
@@ -12,9 +12,10 @@ ePESParser::ePESParser()
        setStreamID(0); /* must be overridden */
 }
 
-void ePESParser::setStreamID(unsigned char id)
+void ePESParser::setStreamID(unsigned char id, unsigned char id_mask)
 {
        m_header[3] = id;
+       m_stream_id_mask = id_mask;
 }
 
 void ePESParser::processData(const __u8 *p, int len)
@@ -43,16 +44,21 @@ void ePESParser::processData(const __u8 *p, int len)
                } else
                {
                        if (m_pes_position < 4)
-                               if (*p != m_header[m_pes_position])
+                       {
+                               unsigned char ch = *p;
+                               if (m_pes_position == 3)
+                                       ch &= m_stream_id_mask;
+                               if (ch != m_header[m_pes_position])
                                {
 //                                     eDebug("sync lost at %d (%02x)", m_pes_position, *p);
                                        m_pes_position = 0;
-                                       while (m_header[m_pes_position] == *p) /* guaranteed to stop at the old m_pes_position */
+                                       while (m_header[m_pes_position] == ch) /* guaranteed to stop at the old m_pes_position */
                                                m_pes_position++;
                                        p++;
                                        len--;
                                        continue;
                                }
+                       }
                        m_pes_buffer[m_pes_position++] = *p++; len--;
                        if (m_pes_position == 6)
                        {
index 2966b7214ade2f65d392cd59bf4090a8d11f45a7..51fab2db3507fea9ac0b02e82f22c78c662002ab 100644 (file)
@@ -7,7 +7,7 @@ class ePESParser
 {
 public:
        ePESParser();
-       void setStreamID(unsigned char id);
+       void setStreamID(unsigned char id, unsigned char id_mask=0xff);
        void processData(const __u8 *data, int len);
        virtual void processPESPacket(__u8 *pkt, int len) = 0;
        virtual ~ePESParser() { }
@@ -15,6 +15,7 @@ private:
        unsigned char m_pes_buffer[65536];
        int m_pes_position, m_pes_length;
        unsigned char m_header[4];
+       unsigned char m_stream_id_mask;
 };
 
 #endif
index 2c395a9ca55e754879f938d8ad6d49b10a7d720c..9d673a819d54db53d949a2ca4ec2965a7953c75d 100644 (file)
@@ -405,6 +405,18 @@ public:
 
 TEMPLATE_TYPEDEF(ePtr<iAudioDelay>, iAudioDelayPtr);
 
+class iRadioText: public iObject
+{
+#ifdef SWIG
+       iRadioText();
+       ~iRadioText();
+#endif
+public:
+       virtual std::string getRadioText(int x=0)=0;
+};
+
+TEMPLATE_TYPEDEF(ePtr<iRadioText>, iRadioTextPtr);
+
 class iSubserviceList: public iObject
 {
 #ifdef SWIG
@@ -493,6 +505,8 @@ public:
                
                        /* only when cueSheet is implemented */
                evCuesheetChanged,
+
+               evUpdatedRadioText
        };
        virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
        virtual RESULT start()=0;
@@ -510,6 +524,7 @@ public:
        virtual SWIG_VOID(RESULT) cueSheet(ePtr<iCueSheet> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) subtitle(ePtr<iSubtitleOutput> &SWIG_OUTPUT)=0;
        virtual SWIG_VOID(RESULT) audioDelay(ePtr<iAudioDelay> &SWIG_OUTPUT)=0;
+       virtual SWIG_VOID(RESULT) radioText(ePtr<iRadioText> &SWIG_OUTPUT)=0;
 };
 
 TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
index d789da69fa578c4310c9f6913d8ed96b0e95e929..977399697396d438a699ff60c21dadd8b8070142 100644 (file)
@@ -1106,6 +1106,12 @@ RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
        return 0;
 }
 
+RESULT eDVBServicePlay::radioText(ePtr<iRadioText> &ptr)
+{
+       ptr = this;
+       return 0;
+}
+
 RESULT eDVBServicePlay::getName(std::string &name)
 {
        if (m_is_pvr)
@@ -1296,13 +1302,17 @@ int eDVBServicePlay::selectAudioStream(int i)
        if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
                return -4;
 
+       if (m_radiotext_parser)
+               m_radiotext_parser->start(program.audioStreams[i].pid);
+
        if (m_dvb_service && !m_is_pvr)
        {
                if (program.audioStreams[i].type == eDVBAudio::aMPEG)
                {
                        m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[i].pid);
                        m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
-               }       else
+               }
+               else
                {
                        m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
                        m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[i].pid);
@@ -1330,6 +1340,22 @@ RESULT eDVBServicePlay::selectChannel(int i)
        return 0;
 }
 
+std::string eDVBServicePlay::getRadioText(int x)
+{
+       if (m_radiotext_parser)
+               switch(x)
+               {
+                       case 0:
+                               return m_radiotext_parser->getCurrentText();
+               }
+       return "";
+}
+
+void eDVBServicePlay::radioTextUpdated()
+{
+       m_event((iPlayableService*)this, evUpdatedRadioText);
+}
+
 int eDVBServiceBase::getFrontendInfo(int w)
 {
        eUsePtr<iDVBChannel> channel;
@@ -1602,7 +1628,9 @@ void eDVBServicePlay::switchToLive()
        m_decoder = 0;
        m_decode_demux = 0;
        m_teletext_parser = 0;
+       m_radiotext_parser = 0;
        m_new_subtitle_page_connection = 0;
+       m_radiotext_updated_connection = 0;
        
                /* free the timeshift service handler, we need the resources */
        m_service_handler_timeshift.free();
@@ -1621,8 +1649,10 @@ void eDVBServicePlay::switchToTimeshift()
        m_decode_demux = 0;
        m_decoder = 0;
        m_teletext_parser = 0;
+       m_radiotext_parser = 0;
        m_new_subtitle_page_connection = 0;
-       
+       m_radiotext_updated_connection = 0;
+
        m_timeshift_active = 1;
 
        m_event((iPlayableService*)this, evSeekableStatusChanged);
@@ -1710,6 +1740,16 @@ void eDVBServicePlay::updateDecoder()
                m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
                m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
 #endif
+               if (apid != 1)
+               {
+                       ePtr<iDVBDemux> data_demux;
+                       if ( (m_timeshift_active && !m_service_handler_timeshift.getDataDemux(data_demux))
+                               || (!m_timeshift_active && !m_service_handler.getDataDemux(data_demux)))
+                       {
+                               m_radiotext_parser = new eDVBRadioTextParser(data_demux);
+                               m_radiotext_parser->connectUpdatedRadiotext(slot(*this, &eDVBServicePlay::radioTextUpdated), m_radiotext_updated_connection);
+                       }
+               }
        }
 
        if (m_decoder)
@@ -1761,6 +1801,9 @@ void eDVBServicePlay::updateDecoder()
                if (m_teletext_parser)
                        m_teletext_parser->start(tpid);
 
+               if (m_radiotext_parser)
+                       m_radiotext_parser->start(apid);
+
                if (!m_is_primary)
                        m_decoder->setTrickmode(1);
 
index 5d3d008545b1d09d0830130d965cda6aa8edd782..0be174e28c22af5d834e49a3aeade9d8f9ea8ec5 100644 (file)
@@ -7,6 +7,7 @@
 #include <lib/dvb/pmt.h>
 #include <lib/dvb/eit.h>
 #include <lib/dvb/teletext.h>
+#include <lib/dvb/radiotext.h>
 #include <lib/base/filepush.h>
 
 class eServiceFactoryDVB: public iServiceHandler
@@ -59,7 +60,7 @@ private:
 class eDVBServiceBase: public iFrontendInformation
 {
 protected:
-       eDVBServicePMTHandler m_service_handler;
+       eDVBServicePMTHandler m_service_handler ;
 public:
                // iFrontendInformation
        int getFrontendInfo(int w);
@@ -73,7 +74,8 @@ class eDVBServicePlay: public eDVBServiceBase,
                public iSeekableService, public Object, public iServiceInformation, 
                public iAudioTrackSelection, public iAudioChannelSelection,
                public iSubserviceList, public iTimeshiftService,
-               public iCueSheet, public iSubtitleOutput, public iAudioDelay
+               public iCueSheet, public iSubtitleOutput, public iAudioDelay,
+               public iRadioText
 {
 DECLARE_REF(eDVBServicePlay);
 public:
@@ -95,7 +97,8 @@ public:
        RESULT timeshift(ePtr<iTimeshiftService> &ptr);
        RESULT cueSheet(ePtr<iCueSheet> &ptr);
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr);
-       RESULT audioDelay(ePtr<iAudioDelay> &ptr);      
+       RESULT audioDelay(ePtr<iAudioDelay> &ptr);
+       RESULT radioText(ePtr<iRadioText> &ptr);
 
                // iPauseableService
        RESULT pause();
@@ -127,6 +130,9 @@ public:
        int getCurrentChannel();
        RESULT selectChannel(int i);
 
+               // iRadioText
+       std::string getRadioText(int i=0);
+
                // iSubserviceList
        int getNumberOfSubservices();
        RESULT getSubservice(eServiceReference &subservice, unsigned int n);
@@ -232,11 +238,16 @@ private:
        ePtr<eConnection> m_new_subtitle_page_connection;
        
        ePtr<eDVBTeletextParser> m_teletext_parser;
+       ePtr<eDVBRadioTextParser> m_radiotext_parser;
        eSubtitleWidget *m_subtitle_widget;
        eTimer m_subtitle_sync_timer;
        std::list<eDVBTeletextSubtitlePage> m_subtitle_pages;
        
        void checkSubtitleTiming();
+
+               /* radiotext */
+       ePtr<eConnection> m_radiotext_updated_connection;
+       void radioTextUpdated();
 };
 
 #endif
index 32c9dc75f28bc5df4e8a20eff7be1eff090a3f2a..4245c816f0c823e0c39c104d46289e887e53e8eb 100644 (file)
@@ -66,6 +66,7 @@ public:
        RESULT cueSheet(ePtr<iCueSheet> &ptr) { ptr = 0; return -1; }
        RESULT subtitle(ePtr<iSubtitleOutput> &ptr) { ptr = 0; return -1; }
        RESULT audioDelay(ePtr<iAudioDelay> &ptr) { ptr = 0; return -1; }
+       RESULT radioText(ePtr<iRadioText> &ptr) { ptr = 0; return -1; }
 
                // iPausableService
        RESULT pause();