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/rawfile.cpp | |
| parent | 13e74ce7d8fcccc12bed3ce65c4f35987f206799 (diff) | |
| download | enigma2-8ef240801bf66e543cdea9df3b32fc09cebcc7e5.tar.gz enigma2-8ef240801bf66e543cdea9df3b32fc09cebcc7e5.zip | |
enable playback of multifile (split) movies
Diffstat (limited to 'lib/base/rawfile.cpp')
| -rw-r--r-- | lib/base/rawfile.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
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); +} |
