X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fdemux.cpp;h=f2b494a8d5900d4b48db3a7be10cd841164c9fdd;hp=11465186c35a447594e70935560e2275d9b3e5cd;hb=d8e08fe0a7304ed06b3de0b9ad6d4265ec8063b8;hpb=bce53d4a67d1655a496eebe5912c8573e880114e diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp index 1146518..f2b494a 100644 --- a/lib/dvb/demux.cpp +++ b/lib/dvb/demux.cpp @@ -12,50 +12,20 @@ #define FUZZING_PROPABILITY 100 #endif -#if HAVE_DVB_API_VERSION < 3 -#include - -#ifndef DMX_SET_NEGFILTER_MASK - #define DMX_SET_NEGFILTER_MASK _IOW('o',48,uint8_t *) -#endif - -#ifndef DMX_GET_STC - struct dmx_stc - { - unsigned int num; /* input : which STC? O..N */ - unsigned int base; /* output: divisor for stc to get 90 kHz clock */ - unsigned long long stc; /* output: src in 'base'*90 kHz units */ - }; - #define DMX_GET_STC _IOR('o', 50, struct dmx_stc) -#endif - -#else #include -#define HAVE_ADD_PID - -#ifdef HAVE_ADD_PID -#define DMX_ADD_PID _IO('o', 51) -#define DMX_REMOVE_PID _IO('o', 52) - -typedef enum { - DMX_TAP_TS = 0, - DMX_TAP_PES = DMX_PES_OTHER, /* for backward binary compat. */ -} dmx_tap_type_t; - -#endif - +#ifndef DMX_ADD_PID +#define DMX_ADD_PID _IOW('o', 51, __u16) +#define DMX_REMOVE_PID _IOW('o', 52, __u16) #endif #include "crc32.h" #include -#include #include #include #include #include -#include eDVBDemux::eDVBDemux(int adapter, int demux): adapter(adapter), demux(demux) { @@ -69,20 +39,23 @@ eDVBDemux::~eDVBDemux() int eDVBDemux::openDemux(void) { char filename[128]; -#if HAVE_DVB_API_VERSION < 3 - snprintf(filename, 128, "/dev/dvb/card%d/demux%d", adapter, demux); -#else snprintf(filename, 128, "/dev/dvb/adapter%d/demux%d", adapter, demux); -#endif return ::open(filename, O_RDWR); } +int eDVBDemux::openDVR(int flags) +{ + char filename[128]; + snprintf(filename, 128, "/dev/dvb/adapter%d/dvr%d", adapter, demux); + return ::open(filename, flags); +} + DEFINE_REF(eDVBDemux) RESULT eDVBDemux::setSourceFrontend(int fenum) { -#if HAVE_DVB_API_VERSION >= 3 int fd = openDemux(); + if (fd < 0) return -1; int n = DMX_SOURCE_FRONT0 + fenum; int res = ::ioctl(fd, DMX_SET_SOURCE, &n); if (res) @@ -91,21 +64,17 @@ RESULT eDVBDemux::setSourceFrontend(int fenum) source = fenum; ::close(fd); return res; -#endif - return 0; } RESULT eDVBDemux::setSourcePVR(int pvrnum) { -#if HAVE_DVB_API_VERSION >= 3 int fd = openDemux(); + if (fd < 0) return -1; int n = DMX_SOURCE_DVR0 + pvrnum; int res = ::ioctl(fd, DMX_SET_SOURCE, &n); source = -1; ::close(fd); return res; -#endif - return 0; } RESULT eDVBDemux::createSectionReader(eMainloop *context, ePtr &reader) @@ -134,9 +103,9 @@ RESULT eDVBDemux::createTSRecorder(ePtr &recorder) return 0; } -RESULT eDVBDemux::getMPEGDecoder(ePtr &decoder, int primary) +RESULT eDVBDemux::getMPEGDecoder(ePtr &decoder, int index) { - decoder = new eTSMPEGDecoder(this, primary ? 0 : 1); + decoder = new eTSMPEGDecoder(this, index); return 0; } @@ -239,6 +208,14 @@ eDVBSectionReader::~eDVBSectionReader() ::close(fd); } +RESULT eDVBSectionReader::setBufferSize(int size) +{ + int res=::ioctl(fd, DMX_SET_BUFFER_SIZE, size); + if (res < 0) + eDebug("eDVBSectionReader DMX_SET_BUFFER_SIZE failed(%m)"); + return res; +} + RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask) { RESULT res; @@ -246,18 +223,10 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask) return -ENODEV; notifier->start(); -#if HAVE_DVB_API_VERSION < 3 - dmxSctFilterParams sct; -#else dmx_sct_filter_params sct; -#endif sct.pid = mask.pid; sct.timeout = 0; -#if HAVE_DVB_API_VERSION < 3 - sct.flags = 0; -#else sct.flags = DMX_IMMEDIATE_START; -#endif #if !FUZZING if (mask.flags & eDVBSectionFilterMask::rfCRC) { @@ -269,26 +238,13 @@ RESULT eDVBSectionReader::start(const eDVBSectionFilterMask &mask) memcpy(sct.filter.filter, mask.data, DMX_FILTER_SIZE); memcpy(sct.filter.mask, mask.mask, DMX_FILTER_SIZE); -#if HAVE_DVB_API_VERSION >= 3 memcpy(sct.filter.mode, mask.mode, DMX_FILTER_SIZE); - if (::ioctl(fd, DMX_SET_BUFFER_SIZE, 8192*8) < 0) - eDebug("DMX_SET_BUFFER_SIZE failed(%m)"); -#endif + setBufferSize(8192*8); res = ::ioctl(fd, DMX_SET_FILTER, &sct); if (!res) { -#if HAVE_DVB_API_VERSION < 3 - res = ::ioctl(fd, DMX_SET_NEGFILTER_MASK, mask.mode); - if (!res) - { - res = ::ioctl(fd, DMX_START, 0); - if (!res) - active = 1; - } -#else active = 1; -#endif } return res; } @@ -344,7 +300,7 @@ eDVBPESReader::eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res): if (m_fd >= 0) { - ::ioctl(m_fd, DMX_SET_BUFFER_SIZE, 64*1024); + setBufferSize(64*1024); ::fcntl(m_fd, F_SETFL, O_NONBLOCK); m_notifier = eSocketNotifier::create(context, m_fd, eSocketNotifier::Read, false); CONNECT(m_notifier->activated, eDVBPESReader::data); @@ -356,6 +312,14 @@ eDVBPESReader::eDVBPESReader(eDVBDemux *demux, eMainloop *context, RESULT &res): } } +RESULT eDVBPESReader::setBufferSize(int size) +{ + int res = ::ioctl(m_fd, DMX_SET_BUFFER_SIZE, size); + if (res < 0) + eDebug("eDVBPESReader DMX_SET_BUFFER_SIZE failed(%m)"); + return res; +} + DEFINE_REF(eDVBPESReader) eDVBPESReader::~eDVBPESReader() @@ -372,16 +336,9 @@ RESULT eDVBPESReader::start(int pid) m_notifier->start(); -#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_TAP; @@ -415,25 +372,6 @@ RESULT eDVBPESReader::connectRead(const Slot2 &r, ePtrm_event, eDVBTSRecorder::filepushEvent); -#ifndef HAVE_ADD_PID - m_demux->m_dvr_busy = 1; -#endif + CONNECT(m_thread->m_event, eDVBTSRecorder::filepushEvent); } eDVBTSRecorder::~eDVBTSRecorder() { stop(); delete m_thread; -#ifndef HAVE_ADD_PID - m_demux->m_dvr_busy = 0; -#endif } RESULT eDVBTSRecorder::start() { + std::map::iterator i(m_pids.begin()); + if (m_running) return -1; if (m_target_fd == -1) return -2; - char filename[128]; -#ifndef HAVE_ADD_PID -#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); + if (i == m_pids.end()) return -3; - } -#else + + char filename[128]; snprintf(filename, 128, "/dev/dvb/adapter%d/demux%d", m_demux->adapter, m_demux->demux); m_source_fd = ::open(filename, O_RDONLY); @@ -523,39 +451,49 @@ RESULT eDVBTSRecorder::start() eDebug("FAILED to open demux (%s) in ts recoder (%m)", filename); return -3; } - - ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, 1024*1024); + + setBufferSize(1024*1024); dmx_pes_filter_params flt; - flt.pes_type = (dmx_pes_type_t)DMX_TAP_TS; - flt.pid = (__u16)-1; + flt.pes_type = DMX_PES_OTHER; + flt.output = DMX_OUT_TSDEMUX_TAP; + flt.pid = i->first; + ++i; flt.input = DMX_IN_FRONTEND; - flt.output = DMX_OUT_TAP; flt.flags = 0; int res = ::ioctl(m_source_fd, DMX_SET_PES_FILTER, &flt); if (res) { eDebug("DMX_SET_PES_FILTER: %m"); ::close(m_source_fd); + m_source_fd = -1; return -3; } ::ioctl(m_source_fd, DMX_START); - -#endif if (m_target_filename != "") m_thread->startSaveMetaInformation(m_target_filename); 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) + + while (i != m_pids.end()) { startPID(i->first); - + ++i; + } + return 0; } +RESULT eDVBTSRecorder::setBufferSize(int size) +{ + int res = ::ioctl(m_source_fd, DMX_SET_BUFFER_SIZE, size); + if (res < 0) + eDebug("eDVBTSRecorder DMX_SET_BUFFER_SIZE failed(%m)"); + return res; +} + RESULT eDVBTSRecorder::addPID(int pid) { if (m_pids.find(pid) != m_pids.end()) @@ -581,8 +519,6 @@ RESULT eDVBTSRecorder::removePID(int pid) RESULT eDVBTSRecorder::setTimingPID(int pid, int type) { - if (m_running) - return -1; m_thread->setTimingPID(pid, type); return 0; } @@ -596,6 +532,17 @@ RESULT eDVBTSRecorder::setTargetFD(int fd) RESULT eDVBTSRecorder::setTargetFilename(const char *filename) { m_target_filename = filename; + + std::string target_path = m_target_filename; + std::string::size_type filePos = target_path.rfind('/'); + m_thread->setTSPath(target_path.erase(filePos)); + + return 0; +} + +RESULT eDVBTSRecorder::enableAccessPoints(bool enable) +{ + m_thread->enableAccessPoints(enable); return 0; } @@ -604,20 +551,49 @@ RESULT eDVBTSRecorder::setBoundary(off_t max) return -1; // not yet implemented } +RESULT eDVBTSRecorder::setTimeshift(bool enable) +{ + m_thread->setTimeshift(enable); +} + RESULT eDVBTSRecorder::stop() { + int state=3; + for (std::map::iterator i(m_pids.begin()); i != m_pids.end(); ++i) stopPID(i->first); if (!m_running) return -1; + + /* workaround for record thread stop */ + if (m_source_fd >= 0) + { + if (::ioctl(m_source_fd, DMX_STOP) < 0) + perror("DMX_STOP"); + else + state &= ~1; + + if (::close(m_source_fd) < 0) + perror("close"); + else + state &= ~2; + m_source_fd = -1; + } + m_thread->stop(); - - close(m_source_fd); - m_source_fd = -1; - + + if (state & 3) + { + if (m_source_fd >= 0) + { + ::close(m_source_fd); + m_source_fd = -1; + } + } + + m_running = 0; m_thread->stopSaveMetaInformation(); - return 0; } @@ -641,41 +617,9 @@ RESULT eDVBTSRecorder::connectEvent(const Slot1 &event, ePtropenDemux(); - if (fd < 0) - { - eDebug("FAILED to open demux in ts recoder (%m)"); - 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; -#else while(true) { - if (::ioctl(m_source_fd, DMX_ADD_PID, pid) < 0) { + __u16 p = pid; + if (::ioctl(m_source_fd, DMX_ADD_PID, &p) < 0) { perror("DMX_ADD_PID"); if (errno == EAGAIN || errno == EINTR) { eDebug("retry!"); @@ -685,20 +629,16 @@ RESULT eDVBTSRecorder::startPID(int pid) m_pids[pid] = 1; break; } -#endif return 0; } void eDVBTSRecorder::stopPID(int pid) { -#ifndef HAVE_ADD_PID - if (m_pids[pid] != -1) - ::close(m_pids[pid]); -#else if (m_pids[pid] != -1) { while(true) { - if (::ioctl(m_source_fd, DMX_REMOVE_PID, pid) < 0) { + __u16 p = pid; + if (::ioctl(m_source_fd, DMX_REMOVE_PID, &p) < 0) { perror("DMX_REMOVE_PID"); if (errno == EAGAIN || errno == EINTR) { eDebug("retry!"); @@ -708,7 +648,6 @@ void eDVBTSRecorder::stopPID(int pid) break; } } -#endif m_pids[pid] = -1; }