add support for videotext (VBI)
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 17 Jan 2006 13:08:10 +0000 (13:08 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Tue, 17 Jan 2006 13:08:10 +0000 (13:08 +0000)
so now the videotext from the TV is useable
(needs new drivers!)

lib/dvb/decoder.cpp
lib/dvb/decoder.h
lib/dvb/demux.h
lib/dvb/idvb.h
lib/dvb/pmt.cpp
lib/dvb/pmt.h
lib/service/servicedvb.cpp
lib/service/servicedvbrecord.cpp

index 0f522b2c39ffbcc46eeb8ed0cdbf759add45bbe6..bf0014d87e2fbf85d26f2c782e6a075333c65c3b 100644 (file)
@@ -301,6 +301,57 @@ eDVBPCR::~eDVBPCR()
                ::close(m_fd_demux);
 }
 
+DEFINE_REF(eDVBVText);
+
+eDVBVText::eDVBVText(eDVBDemux *demux): m_demux(demux)
+{
+       char filename[128];
+#if HAVE_DVB_API_VERSION < 3
+       sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
+#else
+       sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
+#endif
+       m_fd_demux = ::open(filename, O_RDWR);
+       if (m_fd_demux < 0)
+               eWarning("%s: %m", filename);
+}
+
+int eDVBVText::startPid(int pid)
+{
+       if (m_fd_demux < 0)
+               return -1;
+       dmx_pes_filter_params pes;
+
+       pes.pid      = pid;
+       pes.input    = DMX_IN_FRONTEND;
+       pes.output   = DMX_OUT_DECODER;
+       pes.pes_type = DMX_PES_TELETEXT;
+       pes.flags    = 0;
+       if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
+       {
+               eWarning("video: DMX_SET_PES_FILTER: %m");
+               return -errno;
+       }
+       if (::ioctl(m_fd_demux, DMX_START) < 0)
+       {
+               eWarning("video: DMX_START: %m");
+               return -errno;
+       }
+       return 0;
+}
+
+void eDVBVText::stop()
+{
+       if (::ioctl(m_fd_demux, DMX_STOP) < 0)
+               eWarning("video: DMX_STOP: %m");
+}
+
+eDVBVText::~eDVBVText()
+{
+       if (m_fd_demux >= 0)
+               ::close(m_fd_demux);
+}
+
 DEFINE_REF(eTSMPEGDecoder);
 
 int eTSMPEGDecoder::setState()
@@ -416,6 +467,22 @@ int eTSMPEGDecoder::setState()
                }
                m_changed &= ~changeAudio;
        }
+       if (m_changed & changeText)
+       {
+               if (m_text)
+                       m_text->stop();
+               m_text = 0;
+               if ((m_textpid >= 0) && (m_textpid < 0x1FFF))
+               {
+                       m_text = new eDVBVText(m_demux);
+                       if (m_text->startPid(m_textpid))
+                       {
+                               eWarning("text: startpid failed!");
+                               res = -1;
+                       }
+               }
+               m_changed &= ~changeText;
+       }
 #endif
        return res;
 }
@@ -464,6 +531,16 @@ RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
        return 0;
 }
 
+RESULT eTSMPEGDecoder::setTextPID(int textpid)
+{
+       if (m_textpid != textpid)
+       {
+               m_changed |= changeText;
+               m_textpid = textpid;
+       }
+       return 0;
+}
+
 RESULT eTSMPEGDecoder::setSyncMaster(int who)
 {
        return -1;
index fb543feda783a803ad8551fc5eb32156922f5034..f1d074dbced85bff77229e5168058e5275c78439 100644 (file)
@@ -62,6 +62,19 @@ public:
        virtual ~eDVBPCR();
 };
 
+class eDVBVText: public iObject
+{
+DECLARE_REF(eDVBVText);
+private:
+       ePtr<eDVBDemux> m_demux;
+       int m_fd_demux;
+public:
+       eDVBVText(eDVBDemux *demux);
+       int startPid(int pid);
+       void stop();
+       virtual ~eDVBVText();
+};
+
 class eTSMPEGDecoder: public Object, public iTSMPEGDecoder
 {
 DECLARE_REF(eTSMPEGDecoder);
@@ -70,12 +83,14 @@ private:
        ePtr<eDVBAudio> m_audio;
        ePtr<eDVBVideo> m_video;
        ePtr<eDVBPCR> m_pcr;
-       int m_vpid, m_apid, m_atype, m_pcrpid;
+       ePtr<eDVBVText> m_text;
+       int m_vpid, m_apid, m_atype, m_pcrpid, m_textpid;
        enum
        {
                changeVideo = 1, 
                changeAudio = 2, 
-               changePCR   = 4
+               changePCR   = 4,
+               changeText  = 8
        };
        int m_changed;
        int m_is_ff, m_is_sm, m_is_trickmode;
@@ -90,6 +105,7 @@ public:
        RESULT setVideoPID(int vpid);
        RESULT setAudioPID(int apid, int type);
        RESULT setSyncPCR(int pcrpid);
+       RESULT setTextPID(int textpid);
        RESULT setSyncMaster(int who);
        RESULT start();
        RESULT freeze(int cont);
index 869c2e9b7fc9fffb6f65d34cbc6a6704ad60163f..167aa785c1991032642c7831419197236c431a7f 100644 (file)
@@ -32,6 +32,7 @@ private:
        friend class eDVBAudio;
        friend class eDVBVideo;
        friend class eDVBPCR;
+       friend class eDVBVText;
        friend class eDVBTSRecorder;
        friend class eDVBCAService;
        Signal1<void, int> m_event;
index 8aa3391dfeda6e9351ee2807cc7709e4756e1327..90457dc1f411fe3164782a516a3a037e52955c85 100644 (file)
@@ -466,12 +466,15 @@ public:
                /** Set Displayed Audio PID and type */
        virtual RESULT setAudioPID(int apid, int type)=0;
 
+               /** Set Displayed Videotext PID */
+       virtual RESULT setTextPID(int vpid)=0;
+
                /** Set Sync mode to PCR */
        virtual RESULT setSyncPCR(int pcrpid)=0;
        enum { sm_Audio, sm_Video };
                /** Set Sync mode to either audio or video master */
        virtual RESULT setSyncMaster(int who)=0;
-       
+
                /** Apply settings */
        virtual RESULT start()=0;
        
index 2455b95ff31ddc0a7bb9df992cfa0cad733e5798..a5e9be4682ad76d412dae4a851e74f1cbb830ac7 100644 (file)
@@ -6,6 +6,7 @@
 #include <lib/dvb_ci/dvbci.h>
 #include <lib/dvb/epgcache.h>
 #include <dvbsi++/ca_program_map_section.h>
+#include <dvbsi++/teletext_descriptor.h>
 #include <dvbsi++/descriptor_tag.h>
 #include <dvbsi++/iso639_language_descriptor.h>
 #include <dvbsi++/stream_identifier_descriptor.h>
@@ -138,17 +139,20 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
        program.pcrPid = -1;
        program.isCrypted = false;
        program.pmtPid = -1;
+       program.textPid = -1;
 
        if (!m_PMT.getCurrent(ptr))
        {
                int cached_apid_ac3 = -1;
                int cached_apid_mpeg = -1;
                int cached_vpid = -1;
+               int cached_tpid = -1;
                if ( m_service && !m_service->cacheEmpty() )
                {
                        cached_vpid = m_service->getCachePID(eDVBService::cVPID);
                        cached_apid_mpeg = m_service->getCachePID(eDVBService::cAC3PID);
                        cached_apid_ac3 = m_service->getCachePID(eDVBService::cAPID);
+                       cached_tpid = m_service->getCachePID(eDVBService::cTPID);
                }
                eDVBTableSpec table_spec;
                ptr->getSpec(table_spec);
@@ -193,6 +197,10 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                                        {
                                                switch ((*desc)->getTag())
                                                {
+                                               case TELETEXT_DESCRIPTOR:
+                                                       if ( program.textPid == -1 || (*es)->getPid() == cached_tpid )
+                                                               program.textPid = (*es)->getPid();
+                                                       break;
                                                case AC3_DESCRIPTOR:
                                                        if (!isvideo)
                                                        {
@@ -269,6 +277,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                        apid_ac3 = m_service->getCachePID(eDVBService::cAC3PID),
                        apid_mpeg = m_service->getCachePID(eDVBService::cAPID),
                        pcrpid = m_service->getCachePID(eDVBService::cPCRPID),
+                       tpid = m_service->getCachePID(eDVBService::cTPID),
                        cnt=0;
                if ( vpid != -1 )
                {
@@ -298,6 +307,11 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program)
                        ++cnt;
                        program.pcrPid = pcrpid;
                }
+               if ( tpid != -1 )
+               {
+                       ++cnt;
+                       program.textPid = tpid;
+               }
                if ( cnt )
                        return 0;
        }
index aabac24dc0ef13a72b1f3f7399e54836896e145d..fb16ea5cf7703e99f109b885d0f764b2b78f15fe 100644 (file)
@@ -111,6 +111,7 @@ public:
                // ca info
                int pcrPid;
                int pmtPid;
+               int textPid;
                bool isCrypted;
        };
        
index d8567fd83fd6930d736760c3f373b3dfea1cec8d..ed6544f5f1701dc5232d95a8cb1935c428ef6fbd 100644 (file)
@@ -1044,7 +1044,10 @@ void eDVBServicePlay::updateTimeshiftPids()
                pids_to_record.insert(0); // PAT
                if (program.pmtPid != -1)
                        pids_to_record.insert(program.pmtPid); // PMT
-               
+
+               if (program.textPid != -1)
+                       pids_to_record.insert(program.textPid); // Videotext
+
                for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
                        i(program.videoStreams.begin()); 
                        i != program.videoStreams.end(); ++i)
@@ -1066,7 +1069,7 @@ void eDVBServicePlay::updateTimeshiftPids()
                                pids_to_record.begin(), pids_to_record.end(), 
                                std::inserter(new_pids, new_pids.begin())
                                );
-               
+
                for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
                        m_record->addPID(*i);
 
@@ -1110,7 +1113,7 @@ void eDVBServicePlay::switchToTimeshift()
 
 void eDVBServicePlay::updateDecoder()
 {
-       int vpid = -1, apid = -1, apidtype = -1, pcrpid = -1;
+       int vpid = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1;
        eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
 
        eDVBServicePMTHandler::program program;
@@ -1153,9 +1156,10 @@ void eDVBServicePlay::updateDecoder()
                        }
                        eDebugNoNewLine(")");
                }
-               eDebug(", and the pcr pid is %04x", program.pcrPid);
-               if (program.pcrPid != 0x1fff)
-                       pcrpid = program.pcrPid;
+               eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
+               pcrpid = program.pcrPid;
+               eDebug(", and the text pid is %04x", program.textPid);
+               tpid = program.textPid;
        }
 
        if (!m_decoder)
@@ -1174,27 +1178,29 @@ void eDVBServicePlay::updateDecoder()
                        m_decoder->setSyncPCR(pcrpid);
                else
                        m_decoder->setSyncPCR(-1);
+               m_decoder->setTextPID(tpid);
                m_decoder->start();
 // 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)
+               /* don't worry about non-existing services, nor pvr services */
+               if (m_dvb_service && !m_is_pvr)
+               {
+                       if (apidtype == eDVBAudio::aMPEG)
                        {
-                               if (apidtype == eDVBAudio::aMPEG)
-                               {
-                                       m_dvb_service->setCachePID(eDVBService::cAPID, apid);
-                                       m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
-                               }
-                               else
-                               {
-                                       m_dvb_service->setCachePID(eDVBService::cAPID, -1);
-                                       m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
-                               }
-                               m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
-                               m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
+                               m_dvb_service->setCachePID(eDVBService::cAPID, apid);
+                               m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
                        }
+                       else
+                       {
+                               m_dvb_service->setCachePID(eDVBService::cAPID, -1);
+                               m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
+                       }
+                       m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
+                       m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
+                       m_dvb_service->setCachePID(eDVBService::cTPID, tpid);
+               }
        }
 }
 
index 10ab8ae7279c572ba3583432955064f01f0a26fe..f4bf557726cbae7de71be225594cddd0f2f4c92a 100644 (file)
@@ -163,10 +163,13 @@ int eDVBServiceRecord::doRecord()
                        }
                        eDebugNoNewLine(")");
                }
-               eDebug(", and the pcr pid is %04x", program.pcrPid);
+               eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
                if (program.pcrPid != 0x1fff)
                        pids_to_record.insert(program.pcrPid);
-               
+               eDebug(", and the text pid is %04x", program.textPid);
+               if (program.textPid != -1)
+                       pids_to_record.insert(program.textPid); // Videotext
+
                        /* find out which pids are NEW and which pids are obsolete.. */
                std::set<int> new_pids, obsolete_pids;