aboutsummaryrefslogtreecommitdiff
path: root/lib/dvb
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2005-04-30 17:59:17 +0000
committerFelix Domke <tmbinc@elitedvb.net>2005-04-30 17:59:17 +0000
commit7fd4f3d49a6d2f93cae4769cf8678358ebd1abce (patch)
treef0d6b716eedc1c432f8fe316bd77fa355a074513 /lib/dvb
parent110c675aaad3ed8798ebf927652ae04511d31cb8 (diff)
downloadenigma2-7fd4f3d49a6d2f93cae4769cf8678358ebd1abce.tar.gz
enigma2-7fd4f3d49a6d2f93cae4769cf8678358ebd1abce.zip
- add ts recorder
- rename: isection.h -> idemux.h
Diffstat (limited to 'lib/dvb')
-rw-r--r--lib/dvb/demux.cpp258
-rw-r--r--lib/dvb/demux.h41
-rw-r--r--lib/dvb/eit.h2
-rw-r--r--lib/dvb/esection.h2
-rw-r--r--lib/dvb/pmt.cpp2
-rw-r--r--lib/dvb/pmt.h2
-rw-r--r--lib/dvb/scan.h2
-rw-r--r--lib/dvb/specs.h2
8 files changed, 305 insertions, 6 deletions
diff --git a/lib/dvb/demux.cpp b/lib/dvb/demux.cpp
index f24fcddc..f6bdbd7b 100644
--- a/lib/dvb/demux.cpp
+++ b/lib/dvb/demux.cpp
@@ -4,6 +4,9 @@
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
+#include <signal.h>
+
+#include <lib/base/thread.h>
#if HAVE_DVB_API_VERSION < 3
#include <ost/dmx.h>
@@ -24,6 +27,7 @@
eDVBDemux::eDVBDemux(int adapter, int demux): adapter(adapter), demux(demux)
{
+ m_dvr_busy = 0;
}
eDVBDemux::~eDVBDemux()
@@ -41,6 +45,14 @@ RESULT eDVBDemux::createSectionReader(eMainloop *context, ePtr<iDVBSectionReader
return res;
}
+RESULT eDVBDemux::createTSRecorder(ePtr<iDVBTSRecorder> &recorder)
+{
+ if (m_dvr_busy)
+ return -EBUSY;
+ recorder = new eDVBTSRecorder(this);
+ return 0;
+}
+
RESULT eDVBDemux::getMPEGDecoder(ePtr<iTSMPEGDecoder> &decoder)
{
decoder = new eTSMPEGDecoder(this, 0);
@@ -165,3 +177,249 @@ RESULT eDVBSectionReader::connectRead(const Slot1<void,const __u8*> &r, ePtr<eCo
conn = new eConnection(this, read.connect(r));
return 0;
}
+
+DEFINE_REF(eDVBTSRecorder);
+
+class eDVBTSRecorderThread: public eThread
+{
+public:
+ eDVBTSRecorderThread();
+ void thread();
+ void stop();
+ void start(int sourcefd, int destfd);
+private:
+ int m_stop;
+ unsigned char m_buffer[65536];
+ int m_buf_start, m_buf_end;
+ int m_fd_source, m_fd_dest;
+};
+
+eDVBTSRecorderThread::eDVBTSRecorderThread()
+{
+ m_stop = 0;
+ m_buf_start = m_buf_end = 0;
+}
+
+static void signal_handler(int x)
+{
+}
+
+void eDVBTSRecorderThread::thread()
+{
+ eDebug("RECORDING THREAD START");
+ // this is race. FIXME.
+
+ /* we set the signal to not restart syscalls, so we can detect our signal. */
+ struct sigaction act;
+ act.sa_handler = signal_handler; // no, SIG_IGN doesn't do it :/
+ act.sa_flags = 0;
+ sigaction(SIGUSR1, &act, 0);
+
+ /* m_stop must be evaluated after each syscall. */
+ while (!m_stop)
+ {
+ /* first try flushing the bufptr */
+ if (m_buf_start != m_buf_end)
+ {
+ // TODO: take care of boundaries.
+ int w = write(m_fd_dest, m_buffer + m_buf_start, m_buf_end - m_buf_start);
+ if (w <= 0)
+ {
+ if (errno == -EINTR)
+ continue;
+ eDebug("eDVBTSRecorder *write error* - not yet handled");
+ // ... we would stop the thread
+ }
+ printf("TSRECORD: wrote %d bytes\n", w);
+ m_buf_start += w;
+ continue;
+ }
+
+ /* now fill our buffer. */
+ m_buf_start = 0;
+ m_buf_end = read(m_fd_source, m_buffer, sizeof(m_buffer));
+ if (m_buf_end < 0)
+ {
+ m_buf_end = 0;
+ if (errno == EINTR)
+ continue;
+ eDebug("eDVBTSRecorder *read error* - not yet handled");
+ }
+ printf("TSRECORD: read %d bytes\n", m_buf_end);
+ }
+
+ eDebug("RECORDING THREAD STOP");
+}
+
+void eDVBTSRecorderThread::start(int fd_source, int fd_dest)
+{
+ m_fd_source = fd_source;
+ m_fd_dest = fd_dest;
+ m_stop = 0;
+ run();
+}
+
+void eDVBTSRecorderThread::stop()
+{
+ m_stop = 1;
+ sendSignal(SIGUSR1);
+ kill();
+}
+
+eDVBTSRecorder::eDVBTSRecorder(eDVBDemux *demux): m_demux(demux)
+{
+ m_running = 0;
+ m_format = 0;
+ m_target_fd = -1;
+ m_thread = new eDVBTSRecorderThread();
+ m_demux->m_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<int,int>::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<int,int>(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<int,int>::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<void,int> &event, ePtr<eConnection> &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;
+}
diff --git a/lib/dvb/demux.h b/lib/dvb/demux.h
index d8c1078e..b2d571ac 100644
--- a/lib/dvb/demux.h
+++ b/lib/dvb/demux.h
@@ -2,19 +2,23 @@
#define __dvb_demux_h
#include <lib/dvb/idvb.h>
-#include <lib/dvb/isection.h>
+#include <lib/dvb/idemux.h>
class eDVBDemux: public iDVBDemux
{
int adapter, demux;
+
+ int m_dvr_busy;
friend class eDVBSectionReader;
friend class eDVBAudio;
friend class eDVBVideo;
+ friend class eDVBTSRecorder;
public:
DECLARE_REF(eDVBDemux);
eDVBDemux(int adapter, int demux);
virtual ~eDVBDemux();
RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader);
+ RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder);
RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader);
};
@@ -38,4 +42,39 @@ public:
RESULT connectRead(const Slot1<void,const __u8*> &read, ePtr<eConnection> &conn);
};
+class eDVBTSRecorderThread;
+
+class eDVBTSRecorder: public iDVBTSRecorder, public Object
+{
+ DECLARE_REF(eDVBTSRecorder);
+public:
+ eDVBTSRecorder(eDVBDemux *demux);
+ ~eDVBTSRecorder();
+
+ RESULT start();
+ RESULT addPID(int pid);
+ RESULT removePID(int pid);
+
+ RESULT setFormat(int pid);
+
+ RESULT setTargetFD(int fd);
+ RESULT setBoundary(off_t max);
+
+ RESULT stop();
+
+ RESULT connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &conn);
+private:
+ RESULT startPID(int pid);
+ void stopPID(int pid);
+
+ eDVBTSRecorderThread *m_thread;
+
+ std::map<int,int> m_pids;
+ Signal1<void,int> m_event;
+
+ ePtr<eDVBDemux> m_demux;
+
+ int m_running, m_format, m_target_fd, m_source_fd;
+};
+
#endif
diff --git a/lib/dvb/eit.h b/lib/dvb/eit.h
index 7ec16bc8..a026773c 100644
--- a/lib/dvb/eit.h
+++ b/lib/dvb/eit.h
@@ -1,7 +1,7 @@
#ifndef __lib_dvb_eit_h
#define __lib_dvb_eit_h
-#include <lib/dvb/isection.h>
+#include <lib/dvb/idemux.h>
#include <lib/dvb/esection.h>
#include <lib/dvb_si/eit.h>
#include <lib/service/event.h>
diff --git a/lib/dvb/esection.h b/lib/dvb/esection.h
index df0b93e5..2d71eef8 100644
--- a/lib/dvb/esection.h
+++ b/lib/dvb/esection.h
@@ -1,7 +1,7 @@
#ifndef __esection_h
#define __esection_h
-#include <lib/dvb/isection.h>
+#include <lib/dvb/idemux.h>
#include <set>
class eGTable: public iObject, public Object
diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp
index 8c4388a4..3f9ac7f7 100644
--- a/lib/dvb/pmt.cpp
+++ b/lib/dvb/pmt.cpp
@@ -44,6 +44,7 @@ void eDVBServicePMTHandler::PMTready(int error)
void eDVBServicePMTHandler::PATready(int)
{
+ eDebug("got PAT");
ePtr<eTable<ProgramAssociationTable> > ptr;
if (!m_PAT.getCurrent(ptr))
{
@@ -67,6 +68,7 @@ void eDVBServicePMTHandler::PATready(int)
int eDVBServicePMTHandler::getProgramInfo(struct program &program)
{
+ eDebug("got PMT");
ePtr<eTable<ProgramMapTable> > ptr;
program.videoStreams.clear();
diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h
index 03df198b..136c1673 100644
--- a/lib/dvb/pmt.h
+++ b/lib/dvb/pmt.h
@@ -3,7 +3,7 @@
#include <lib/dvb/idvb.h>
#include <lib/dvb/dvb.h>
-#include <lib/dvb/isection.h>
+#include <lib/dvb/idemux.h>
#include <lib/dvb/esection.h>
#include <lib/dvb_si/pmt.h>
#include <lib/dvb_si/pat.h>
diff --git a/lib/dvb/scan.h b/lib/dvb/scan.h
index 2f75291b..bfd3add9 100644
--- a/lib/dvb/scan.h
+++ b/lib/dvb/scan.h
@@ -4,7 +4,7 @@
#include <lib/dvb_si/nit.h>
#include <lib/dvb_si/sdt.h>
#include <lib/dvb_si/bat.h>
-#include <lib/dvb/isection.h>
+#include <lib/dvb/idemux.h>
#include <lib/dvb/esection.h>
#include <lib/dvb/db.h>
diff --git a/lib/dvb/specs.h b/lib/dvb/specs.h
index 1a0353e5..5c26bfad 100644
--- a/lib/dvb/specs.h
+++ b/lib/dvb/specs.h
@@ -2,7 +2,7 @@
#define __lib_dvb_specs_h
#include <lib/dvb/idvb.h>
-#include <lib/dvb/isection.h>
+#include <lib/dvb/idemux.h>
#include <lib/dvb_si/pmt.h>
#include <lib/dvb_si/sdt.h>
#include <lib/dvb_si/nit.h>