From: Andreas Monzner Date: Tue, 17 Jan 2006 13:08:10 +0000 (+0000) Subject: add support for videotext (VBI) X-Git-Tag: 2.6.0~4410 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/d7010ab56f9b823d56a5a5fa3ba7f7764bbfece4 add support for videotext (VBI) so now the videotext from the TV is useable (needs new drivers!) --- diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 0f522b2c..bf0014d8 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -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; diff --git a/lib/dvb/decoder.h b/lib/dvb/decoder.h index fb543fed..f1d074db 100644 --- a/lib/dvb/decoder.h +++ b/lib/dvb/decoder.h @@ -62,6 +62,19 @@ public: virtual ~eDVBPCR(); }; +class eDVBVText: public iObject +{ +DECLARE_REF(eDVBVText); +private: + ePtr 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 m_audio; ePtr m_video; ePtr m_pcr; - int m_vpid, m_apid, m_atype, m_pcrpid; + ePtr 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); diff --git a/lib/dvb/demux.h b/lib/dvb/demux.h index 869c2e9b..167aa785 100644 --- a/lib/dvb/demux.h +++ b/lib/dvb/demux.h @@ -32,6 +32,7 @@ private: friend class eDVBAudio; friend class eDVBVideo; friend class eDVBPCR; + friend class eDVBVText; friend class eDVBTSRecorder; friend class eDVBCAService; Signal1 m_event; diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 8aa3391d..90457dc1 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -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; diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 2455b95f..a5e9be46 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -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; } diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index aabac24d..fb16ea5c 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -111,6 +111,7 @@ public: // ca info int pcrPid; int pmtPid; + int textPid; bool isCrypted; }; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index d8567fd8..ed6544f5 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -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::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::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); + } } } diff --git a/lib/service/servicedvbrecord.cpp b/lib/service/servicedvbrecord.cpp index 10ab8ae7..f4bf5577 100644 --- a/lib/service/servicedvbrecord.cpp +++ b/lib/service/servicedvbrecord.cpp @@ -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 new_pids, obsolete_pids;