aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorFelix Domke <tmbinc@elitedvb.net>2006-03-03 03:13:13 +0000
committerFelix Domke <tmbinc@elitedvb.net>2006-03-03 03:13:13 +0000
commit8ef240801bf66e543cdea9df3b32fc09cebcc7e5 (patch)
tree5518ec66c8b24014faa47659591f0d47f8816155 /lib
parent13e74ce7d8fcccc12bed3ce65c4f35987f206799 (diff)
downloadenigma2-8ef240801bf66e543cdea9df3b32fc09cebcc7e5.tar.gz
enigma2-8ef240801bf66e543cdea9df3b32fc09cebcc7e5.zip
enable playback of multifile (split) movies
Diffstat (limited to 'lib')
-rw-r--r--lib/base/Makefile.am3
-rw-r--r--lib/base/filepush.cpp21
-rw-r--r--lib/base/filepush.h6
-rw-r--r--lib/base/rawfile.cpp132
-rw-r--r--lib/base/rawfile.h30
-rw-r--r--lib/dvb/dvb.cpp17
-rw-r--r--lib/dvb/dvb.h2
-rw-r--r--lib/dvb/tstools.cpp22
-rw-r--r--lib/dvb/tstools.h5
9 files changed, 205 insertions, 33 deletions
diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am
index 877de00d..3741df6e 100644
--- a/lib/base/Makefile.am
+++ b/lib/base/Makefile.am
@@ -7,4 +7,5 @@ libenigma_base_a_SOURCES = \
buffer.cpp ebase.cpp eerror.cpp elock.cpp \
init.cpp message.cpp thread.cpp \
smartptr.cpp estring.cpp connection.cpp \
- filepush.cpp encoding.cpp console.cpp
+ filepush.cpp encoding.cpp console.cpp rawfile.cpp
+
diff --git a/lib/base/filepush.cpp b/lib/base/filepush.cpp
index 51b26239..8d116559 100644
--- a/lib/base/filepush.cpp
+++ b/lib/base/filepush.cpp
@@ -40,7 +40,7 @@ void eFilePushThread::thread()
sigaction(SIGUSR1, &act, 0);
dest_pos = lseek(m_fd_dest, 0, SEEK_CUR);
- source_pos = lseek(m_fd_source, 0, SEEK_CUR);
+ source_pos = m_raw_source.lseek(0, SEEK_CUR);
/* m_stop must be evaluated after each syscall. */
while (!m_stop)
@@ -84,7 +84,7 @@ void eFilePushThread::thread()
m_sg->getNextSourceSpan(source_pos, bytes_read, current_span_offset, current_span_remaining);
if (source_pos != current_span_offset)
- source_pos = lseek(m_fd_source, current_span_offset, SEEK_SET);
+ source_pos = m_raw_source.lseek(current_span_offset, SEEK_SET);
bytes_read = 0;
}
@@ -98,7 +98,7 @@ void eFilePushThread::thread()
m_buf_end = 0;
if (maxread)
- m_buf_end = read(m_fd_source, m_buffer, maxread);
+ m_buf_end = m_raw_source.read(m_buffer, maxread);
if (m_buf_end < 0)
{
@@ -128,7 +128,7 @@ void eFilePushThread::thread()
sendEvent(evtEOF);
#if 0
eDebug("FILEPUSH: end-of-file! (currently unhandled)");
- if (!lseek(m_fd_source, 0, SEEK_SET))
+ if (!m_raw_source.lseek(0, SEEK_SET))
{
eDebug("(looping)");
continue;
@@ -151,11 +151,20 @@ void eFilePushThread::thread()
void eFilePushThread::start(int fd_source, int fd_dest)
{
- m_fd_source = fd_source;
+ m_raw_source.setfd(fd_source);
m_fd_dest = fd_dest;
resume();
}
+int eFilePushThread::start(const char *filename, int fd_dest)
+{
+ if (m_raw_source.open(filename) < 0)
+ return -1;
+ m_fd_dest = fd_dest;
+ resume();
+ return 0;
+}
+
void eFilePushThread::stop()
{
if (!thread_running()) /* FIXME: races */
@@ -172,7 +181,7 @@ void eFilePushThread::pause()
void eFilePushThread::seek(int whence, off_t where)
{
- ::lseek(m_fd_source, where, whence);
+ m_raw_source.lseek(where, whence);
}
void eFilePushThread::resume()
diff --git a/lib/base/filepush.h b/lib/base/filepush.h
index 75037f66..25257880 100644
--- a/lib/base/filepush.h
+++ b/lib/base/filepush.h
@@ -5,6 +5,7 @@
#include <libsig_comp.h>
#include <lib/base/message.h>
#include <sys/types.h>
+#include <lib/base/rawfile.h>
class iFilePushScatterGather
{
@@ -20,6 +21,7 @@ public:
void thread();
void stop();
void start(int sourcefd, int destfd);
+ int start(const char *filename, int destfd);
void pause();
void seek(int whence, off_t where);
@@ -43,9 +45,11 @@ private:
int m_stop;
unsigned char m_buffer[65536];
int m_buf_start, m_buf_end;
- int m_fd_source, m_fd_dest;
+ int m_fd_dest;
int m_send_pvr_commit;
+ eRawFile m_raw_source;
+
eFixedMessagePump<int> m_messagepump;
void recvEvent(const int &evt);
diff --git a/lib/base/rawfile.cpp b/lib/base/rawfile.cpp
new file mode 100644
index 00000000..f5fb91ee
--- /dev/null
+++ b/lib/base/rawfile.cpp
@@ -0,0 +1,132 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <lib/base/rawfile.h>
+#include <lib/base/eerror.h>
+
+eRawFile::eRawFile()
+{
+ m_fd = -1;
+ m_splitsize = 0;
+ m_totallength = 0;
+ m_current_offset = 0;
+ m_base_offset = 0;
+ m_nrfiles = 0;
+ m_current_file = 0;
+}
+
+eRawFile::~eRawFile()
+{
+ close();
+}
+
+int eRawFile::open(const char *filename)
+{
+ close();
+ m_basename = filename;
+ scan();
+ m_current_offset = 0;
+ m_fd = ::open(filename, O_RDONLY | O_LARGEFILE);
+ return m_fd;
+}
+
+void eRawFile::setfd(int fd)
+{
+ close();
+ m_nrfiles = 1;
+ m_fd = fd;
+}
+
+off_t eRawFile::lseek(off_t offset, int whence)
+{
+ /* if there is only one file, use the native lseek - the file could be growing! */
+ if (!m_nrfiles)
+ return ::lseek(m_fd, offset, whence);
+ switch (whence)
+ {
+ case SEEK_SET:
+ m_current_offset = offset;
+ break;
+ case SEEK_CUR:
+ m_current_offset += offset;
+ break;
+ case SEEK_END:
+ m_current_offset = m_totallength + offset;
+ break;
+ }
+ if (m_current_offset < 0)
+ m_current_offset = 0;
+ return m_current_offset;
+}
+
+int eRawFile::close()
+{
+ int ret = ::close(m_fd);
+ m_fd = -1;
+ return ret;
+}
+
+ssize_t eRawFile::read(void *buf, size_t count)
+{
+ switchOffset(m_current_offset);
+ int ret = ::read(m_fd, buf, count);
+ if (ret > 0)
+ m_current_offset += ret;
+ return ret;
+}
+
+int eRawFile::valid()
+{
+ return m_fd != -1;
+}
+
+void eRawFile::scan()
+{
+ m_nrfiles = 0;
+ m_totallength = 0;
+ while (m_nrfiles < 1000) /* .999 is the last possible */
+ {
+ int f = openFile(m_nrfiles);
+ if (f < 0)
+ break;
+ if (!m_nrfiles)
+ m_splitsize = ::lseek(f, 0, SEEK_END);
+ m_totallength += ::lseek(f, 0, SEEK_END);
+ ::close(f);
+
+ ++m_nrfiles;
+ }
+ eDebug("found %d files, splitsize: %llx, totallength: %llx", m_nrfiles, m_splitsize, m_totallength);
+}
+
+int eRawFile::switchOffset(off_t off)
+{
+ if (m_splitsize)
+ {
+ int filenr = off / m_splitsize;
+ if (filenr >= m_nrfiles)
+ filenr = m_nrfiles - 1;
+
+ if (filenr != m_current_file)
+ {
+ close();
+ setfd(openFile(filenr));
+ m_base_offset = m_splitsize * filenr;
+ eDebug("switched to file %d", filenr);
+ }
+ } else
+ m_base_offset = 0;
+
+ return ::lseek(m_fd, off - m_base_offset, SEEK_SET) + m_base_offset;
+}
+
+int eRawFile::openFile(int nr)
+{
+ std::string filename = m_basename;
+ if (m_nrfiles)
+ {
+ char suffix[5];
+ snprintf(suffix, 5, ".%03d", nr);
+ filename += suffix;
+ }
+ return ::open(filename.c_str(), O_RDONLY);
+}
diff --git a/lib/base/rawfile.h b/lib/base/rawfile.h
new file mode 100644
index 00000000..5d15e85d
--- /dev/null
+++ b/lib/base/rawfile.h
@@ -0,0 +1,30 @@
+#ifndef __lib_base_rawfile_h
+#define __lib_base_rawfile_h
+
+#include <string>
+
+class eRawFile
+{
+public:
+ eRawFile();
+ ~eRawFile();
+
+ int open(const char *filename);
+ void setfd(int fd);
+ off_t lseek(off_t offset, int whence);
+ int close();
+ ssize_t read(void *buf, size_t count); /* NOTE: you must be able to handle short reads! */
+ off_t length();
+ int valid();
+private:
+ int m_fd;
+ std::string m_basename;
+ off_t m_splitsize, m_totallength, m_current_offset, m_base_offset;
+ int m_nrfiles;
+ void scan();
+ int m_current_file;
+ int switchOffset(off_t off);
+ int openFile(int nr);
+};
+
+#endif
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index 3bceebb0..f8f95276 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -1008,14 +1008,6 @@ RESULT eDVBChannel::playFile(const char *file)
return -ENODEV;
}
- m_pvr_fd_src = open(file, O_RDONLY|O_LARGEFILE);
- if (m_pvr_fd_src < 0)
- {
- eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
- close(m_pvr_fd_dst);
- return -ENOENT;
- }
-
m_state = state_ok;
m_stateChanged(this);
@@ -1023,7 +1015,13 @@ RESULT eDVBChannel::playFile(const char *file)
m_pvr_thread->enablePVRCommit(1);
m_pvr_thread->setScatterGather(this);
- m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
+ if (m_pvr_thread->start(file, m_pvr_fd_dst))
+ {
+ delete m_pvr_thread;
+ m_pvr_thread = 0;
+ eDebug("can't open PVR file %s (%m)", file);
+ return -ENOENT;
+ }
CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
return 0;
@@ -1034,7 +1032,6 @@ void eDVBChannel::stopFile()
if (m_pvr_thread)
{
m_pvr_thread->stop();
- ::close(m_pvr_fd_src);
::close(m_pvr_fd_dst);
delete m_pvr_thread;
m_pvr_thread = 0;
diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h
index 8b0a3595..6209f281 100644
--- a/lib/dvb/dvb.h
+++ b/lib/dvb/dvb.h
@@ -250,7 +250,7 @@ private:
eFilePushThread *m_pvr_thread;
void pvrEvent(int event);
- int m_pvr_fd_src, m_pvr_fd_dst;
+ int m_pvr_fd_dst;
eDVBTSTools m_tstools;
ePtr<eCueSheet> m_cue;
diff --git a/lib/dvb/tstools.cpp b/lib/dvb/tstools.cpp
index b6792c65..5c99ea60 100644
--- a/lib/dvb/tstools.cpp
+++ b/lib/dvb/tstools.cpp
@@ -7,7 +7,6 @@
eDVBTSTools::eDVBTSTools()
{
- m_fd = -1;
m_pid = -1;
m_maxrange = 256*1024;
@@ -36,16 +35,14 @@ int eDVBTSTools::openFile(const char *filename)
m_use_streaminfo = 0;
}
- m_fd = ::open(filename, O_RDONLY);
- if (m_fd < 0)
+ if (m_file.open(filename) < 0)
return -1;
return 0;
}
void eDVBTSTools::closeFile()
{
- if (m_fd >= 0)
- ::close(m_fd);
+ m_file.close();
}
void eDVBTSTools::setSyncPID(int pid)
@@ -64,13 +61,12 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
if (m_use_streaminfo)
return m_streaminfo.getPTS(offset, pts);
- if (m_fd < 0)
+ if (!m_file.valid() < 0)
return -1;
offset -= offset % 188;
- // TODO: multiple files!
- if (lseek(m_fd, offset, SEEK_SET) < 0)
+ if (m_file.lseek(offset, SEEK_SET) < 0)
return -1;
int left = m_maxrange;
@@ -78,7 +74,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
while (left >= 188)
{
unsigned char block[188];
- if (read(m_fd, block, 188) != 188)
+ if (m_file.read(block, 188) != 188)
{
eDebug("read error");
break;
@@ -95,7 +91,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
break;
++i;
}
- offset = lseek(m_fd, i - 188, SEEK_CUR);
+ offset = m_file.lseek(i - 188, SEEK_CUR);
continue;
}
@@ -204,7 +200,7 @@ int eDVBTSTools::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction
void eDVBTSTools::calcBegin()
{
- if (m_fd < 0)
+ if (!m_file.valid())
return;
if (!m_begin_valid)
@@ -217,10 +213,10 @@ void eDVBTSTools::calcBegin()
void eDVBTSTools::calcEnd()
{
- if (m_fd < 0)
+ if (!m_file.valid())
return;
- off_t end = lseek(m_fd, 0, SEEK_END);
+ off_t end = m_file.lseek(0, SEEK_END);
if (abs(end - m_offset_end) > 1*1024*1024)
{
diff --git a/lib/dvb/tstools.h b/lib/dvb/tstools.h
index 76128071..b6a275dc 100644
--- a/lib/dvb/tstools.h
+++ b/lib/dvb/tstools.h
@@ -3,6 +3,7 @@
#include <sys/types.h>
#include <lib/dvb/pvrparse.h>
+#include <lib/base/rawfile.h>
/*
* Note: we're interested in PTS values, not STC values.
@@ -51,9 +52,11 @@ public:
int calcBitrate(); /* in bits/sec */
private:
- int m_fd, m_pid;
+ int m_pid;
int m_maxrange;
+ eRawFile m_file;
+
int m_begin_valid, m_end_valid;
pts_t m_pts_begin, m_pts_end;
off_t m_offset_begin, m_offset_end;