X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/4bc08995411e21f3564f09e136809be68ddf96a8..87bf3a0bcf54b168b8fe70cf8aaf4663eada60dc:/lib/dvb/demux.cpp diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index 191d9c38..c3383a7e 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -4,9 +4,14 @@ #include #include #include +#include + #if HAVE_DVB_API_VERSION < 3 #include +#ifndef DMX_SET_NEGFILTER_MASK + #define DMX_SET_NEGFILTER_MASK _IOW('o',48,uint8_t *) +#endif #else #include #endif @@ -14,6 +19,7 @@ #include "crc32.h" #include +#include #include #include #include @@ -21,6 +27,7 @@ eDVBDemux::eDVBDemux(int adapter, int demux): adapter(adapter), demux(demux) { + m_dvr_busy = 0; } eDVBDemux::~eDVBDemux() @@ -38,6 +45,14 @@ RESULT eDVBDemux::createSectionReader(eMainloop *context, ePtr &recorder) +{ + if (m_dvr_busy) + return -EBUSY; + recorder = new eDVBTSRecorder(this); + return 0; +} + RESULT eDVBDemux::getMPEGDecoder(ePtr &decoder) { decoder = new eTSMPEGDecoder(this, 0); @@ -61,7 +76,10 @@ void eDVBSectionReader::data(int) if ((c = crc32((unsigned)-1, data, r))) eFatal("crc32 failed! is %x\n", c); } - read(data); + if (active) + read(data); + else + eDebug("data.. but not active"); } eDVBSectionReader::eDVBSectionReader(eDVBDemux *demux, eMainloop *context, RESULT &res): demux(demux) @@ -151,7 +169,8 @@ RESULT eDVBSectionReader::stop() { if (!active) return -1; - + + active=0; ::ioctl(fd, DMX_STOP); return 0; @@ -162,3 +181,163 @@ RESULT eDVBSectionReader::connectRead(const Slot1 &r, ePtrm_dvr_busy = 1; +} + +eDVBTSRecorder::~eDVBTSRecorder() +{ + stop(); + delete m_thread; + m_demux->m_dvr_busy = 0; +} + +RESULT eDVBTSRecorder::start() +{ + if (m_running) + return -1; + + if (m_target_fd == -1) + return -2; + + char filename[128]; +#if HAVE_DVB_API_VERSION < 3 + snprintf(filename, 128, "/dev/dvb/card%d/dvr%d", m_demux->adapter, m_demux->demux); +#else + snprintf(filename, 128, "/dev/dvb/adapter%d/dvr%d", m_demux->adapter, m_demux->demux); +#endif + m_source_fd = ::open(filename, O_RDONLY); + + if (m_source_fd < 0) + { + eDebug("FAILED to open dvr (%s) in ts recoder (%m)", filename); + return -3; + } + + m_thread->start(m_source_fd, m_target_fd); + m_running = 1; + + for (std::map::iterator i(m_pids.begin()); i != m_pids.end(); ++i) + startPID(i->first); + + return 0; +} + +RESULT eDVBTSRecorder::addPID(int pid) +{ + if (m_pids.find(pid) != m_pids.end()) + return -1; + + m_pids.insert(std::pair(pid, -1)); + if (m_running) + startPID(pid); + return 0; +} + +RESULT eDVBTSRecorder::removePID(int pid) +{ + if (m_pids.find(pid) == m_pids.end()) + return -1; + + if (m_running) + stopPID(pid); + + m_pids.erase(pid); + return 0; +} + +RESULT eDVBTSRecorder::setFormat(int format) +{ + if (m_running) + return -1; + m_format = format; + return 0; +} + +RESULT eDVBTSRecorder::setTargetFD(int fd) +{ + m_target_fd = fd; + return 0; +} + +RESULT eDVBTSRecorder::setBoundary(off_t max) +{ + return -1; // not yet implemented +} + +RESULT eDVBTSRecorder::stop() +{ + for (std::map::iterator i(m_pids.begin()); i != m_pids.end(); ++i) + stopPID(i->first); + + if (!m_running) + return -1; + m_thread->stop(); + + close(m_source_fd); + + return 0; +} + +RESULT eDVBTSRecorder::connectEvent(const Slot1 &event, ePtr &conn) +{ + conn = new eConnection(this, m_event.connect(event)); + return 0; +} + +RESULT eDVBTSRecorder::startPID(int pid) +{ + char filename[128]; +#if HAVE_DVB_API_VERSION < 3 + snprintf(filename, 128, "/dev/dvb/card%d/demux%d", m_demux->adapter, m_demux->demux); +#else + snprintf(filename, 128, "/dev/dvb/adapter%d/demux%d", m_demux->adapter, m_demux->demux); +#endif + int fd = ::open(filename, O_RDWR); + if (fd < 0) + { + eDebug("FAILED to open demux (%s) in ts recoder (%m)", filename); + return -1; + } + +#if HAVE_DVB_API_VERSION < 3 + dmxPesFilterParams flt; + + flt.pesType = DMX_PES_OTHER; +#else + dmx_pes_filter_params flt; + + flt.pes_type = DMX_PES_OTHER; +#endif + + flt.pid = pid; + flt.input = DMX_IN_FRONTEND; + flt.output = DMX_OUT_TS_TAP; + + flt.flags = DMX_IMMEDIATE_START; + + int res = ::ioctl(fd, DMX_SET_PES_FILTER, &flt); + if (res < 0) + { + eDebug("set pes filter failed!"); + ::close(fd); + return -1; + } + m_pids[pid] = fd; + + return 0; +} + +void eDVBTSRecorder::stopPID(int pid) +{ + ::close(m_pids[pid]); + m_pids[pid] = -1; +}