diff options
| author | Felix Domke <tmbinc@elitedvb.net> | 2006-03-03 03:13:13 +0000 |
|---|---|---|
| committer | Felix Domke <tmbinc@elitedvb.net> | 2006-03-03 03:13:13 +0000 |
| commit | 8ef240801bf66e543cdea9df3b32fc09cebcc7e5 (patch) | |
| tree | 5518ec66c8b24014faa47659591f0d47f8816155 /lib/base | |
| parent | 13e74ce7d8fcccc12bed3ce65c4f35987f206799 (diff) | |
| download | enigma2-8ef240801bf66e543cdea9df3b32fc09cebcc7e5.tar.gz enigma2-8ef240801bf66e543cdea9df3b32fc09cebcc7e5.zip | |
enable playback of multifile (split) movies
Diffstat (limited to 'lib/base')
| -rw-r--r-- | lib/base/Makefile.am | 3 | ||||
| -rw-r--r-- | lib/base/filepush.cpp | 21 | ||||
| -rw-r--r-- | lib/base/filepush.h | 6 | ||||
| -rw-r--r-- | lib/base/rawfile.cpp | 132 | ||||
| -rw-r--r-- | lib/base/rawfile.h | 30 |
5 files changed, 184 insertions, 8 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 |
