::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()
}
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;
}
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;
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);
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;
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);
friend class eDVBAudio;
friend class eDVBVideo;
friend class eDVBPCR;
+ friend class eDVBVText;
friend class eDVBTSRecorder;
friend class eDVBCAService;
Signal1<void, int> m_event;
/** 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;
#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>
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);
{
switch ((*desc)->getTag())
{
+ case TELETEXT_DESCRIPTOR:
+ if ( program.textPid == -1 || (*es)->getPid() == cached_tpid )
+ program.textPid = (*es)->getPid();
+ break;
case AC3_DESCRIPTOR:
if (!isvideo)
{
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 )
{
++cnt;
program.pcrPid = pcrpid;
}
+ if ( tpid != -1 )
+ {
+ ++cnt;
+ program.textPid = tpid;
+ }
if ( cnt )
return 0;
}
// ca info
int pcrPid;
int pmtPid;
+ int textPid;
bool isCrypted;
};
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)
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);
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;
}
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)
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);
+ }
}
}
}
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;