X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fbase%2Ffilepush.cpp;h=e9775e39e64fbeee41ec057b2db23c386f5e8ce4;hb=HEAD;hp=91f24ba064026502d3b69316d89c2409bd133bec;hpb=a13c7eb8d063f3fc68562dfa3ffb8cbfc814219e;p=vuplus_dvbapp diff --git a/lib/base/filepush.cpp b/lib/base/filepush.cpp index 91f24ba..e9775e3 100644 --- a/lib/base/filepush.cpp +++ b/lib/base/filepush.cpp @@ -1,12 +1,24 @@ #include #include +#include #include #include #include +#include +#if 0 +#include +#else +#include +#endif #define PVR_COMMIT 1 +#define MAJORSD_ 8 +#define MAJORMMCBLK 179 +#define LIMIT_FILESIZE_NOHDD 2*1024*1024*1024LL // 2GBytes + //FILE *f = fopen("/log.ts", "wb"); +static bool g_is_diskfull = false; eFilePushThread::eFilePushThread(int io_prio_class, int io_prio_level, int blocksize) :prio_class(io_prio_class), prio(io_prio_level), m_messagepump(eApp, 0) @@ -19,6 +31,8 @@ eFilePushThread::eFilePushThread(int io_prio_class, int io_prio_level, int block flush(); enablePVRCommit(0); CONNECT(m_messagepump.recv_msg, eFilePushThread::recvEvent); + m_is_timeshift = false; + m_hdd_connected = true; } static void signal_handler(int x) @@ -29,7 +43,7 @@ void eFilePushThread::thread() { setIoPrio(prio_class, prio); - off_t dest_pos = 0, source_pos = 0; + off_t dest_pos = 0; size_t bytes_read = 0; off_t current_span_offset = 0; @@ -37,6 +51,40 @@ void eFilePushThread::thread() size_t written_since_last_sync = 0; +#if 0 + DIR *tsdir_info; + struct dirent *tsdir_entry; + tsdir_info = opendir("/sys/block"); + if (tsdir_info != NULL) { + m_hdd_connected = false; + while (tsdir_entry = readdir(tsdir_info)) { + if (strncmp(tsdir_entry->d_name, "sd", 2) == 0) { + eDebug("HDD found: %s", tsdir_entry->d_name); + m_hdd_connected = true; + break; + } + } + } +#else + if (m_tspath.empty()) + defaultTSPath(m_is_timeshift); + + struct stat tspath_st; + if (stat(m_tspath.c_str(), &tspath_st) == 0) { + if (major(tspath_st.st_dev) == MAJORSD_) { + eDebug("%s location on HDD!", m_tspath.c_str()); + m_hdd_connected = true; + } else if (major(tspath_st.st_dev) == MAJORMMCBLK) { + eDebug("%s location on eMMC!", m_tspath.c_str()); + m_hdd_connected = false; + } else { + eDebug("%s location on other device", m_tspath.c_str()); + } + } else { + eDebug("stat failed!"); + } +#endif + eDebug("FILEPUSH THREAD START"); /* we set the signal to not restart syscalls, so we can detect our signal. */ @@ -46,9 +94,7 @@ void eFilePushThread::thread() sigaction(SIGUSR1, &act, 0); hasStarted(); - - source_pos = m_raw_source.lseek(0, SEEK_CUR); - + /* m_stop must be evaluated after each syscall. */ while (!m_stop) { @@ -108,10 +154,19 @@ void eFilePushThread::thread() // eDebug("wrote %d bytes", w); if (w <= 0) { - if (errno == EINTR || errno == EAGAIN || errno == EBUSY) + if (w < 0 && (errno == EINTR || errno == EAGAIN || errno == EBUSY)) continue; eDebug("eFilePushThread WRITE ERROR"); sendEvent(evtWriteError); + + struct statfs fs; + if (statfs(m_tspath.c_str(), &fs) < 0) { + eDebug("statfs failed!"); + } + if ((off_t)fs.f_bavail < 1) { + eDebug("not enough diskspace!"); + g_is_diskfull = true; + } break; // ... we would stop the thread } @@ -133,18 +188,29 @@ void eFilePushThread::thread() continue; } + if (!m_hdd_connected) { + struct stat limit_filesize; + if (fstat(m_fd_dest, &limit_filesize) == 0) { + if (limit_filesize.st_size > LIMIT_FILESIZE_NOHDD) { + eDebug("eFilePushThread %lld > %lld LIMIT FILESIZE", limit_filesize.st_size, LIMIT_FILESIZE_NOHDD); + sendEvent(evtWriteError); + + g_is_diskfull = true; + break; + } + } + } + /* now fill our buffer. */ if (m_sg && !current_span_remaining) { - m_sg->getNextSourceSpan(source_pos, bytes_read, current_span_offset, current_span_remaining); + m_sg->getNextSourceSpan(m_current_position, bytes_read, current_span_offset, current_span_remaining); ASSERT(!(current_span_remaining % m_blocksize)); - - if (source_pos != current_span_offset) - source_pos = m_raw_source.lseek(current_span_offset, SEEK_SET); + m_current_position = current_span_offset; bytes_read = 0; } - + size_t maxread = sizeof(m_buffer); /* if we have a source span, don't read past the end */ @@ -157,9 +223,9 @@ void eFilePushThread::thread() m_buf_start = 0; m_filter_end = 0; m_buf_end = 0; - + if (maxread) - m_buf_end = m_raw_source.read(m_buffer, maxread); + m_buf_end = m_source->read(m_current_position, m_buffer, maxread); if (m_buf_end < 0) { @@ -177,10 +243,7 @@ void eFilePushThread::thread() /* a read might be mis-aligned in case of a short read. */ int d = m_buf_end % m_blocksize; if (d) - { - m_raw_source.lseek(-d, SEEK_CUR); m_buf_end -= d; - } if (m_buf_end == 0) { @@ -216,43 +279,50 @@ void eFilePushThread::thread() sleep(1); continue; } -#if 0 - eDebug("FILEPUSH: end-of-file! (currently unhandled)"); - if (!m_raw_source.lseek(0, SEEK_SET)) - { - eDebug("(looping)"); - continue; - } -#endif break; } else { - source_pos += m_buf_end; + m_current_position += m_buf_end; bytes_read += m_buf_end; if (m_sg) current_span_remaining -= m_buf_end; } // printf("FILEPUSH: read %d bytes\n", m_buf_end); + + if (g_is_diskfull) { + sendEvent(evtUser+3); + g_is_diskfull = false; + } } fdatasync(m_fd_dest); eDebug("FILEPUSH THREAD STOP"); } -void eFilePushThread::start(int fd_source, int fd_dest) +void eFilePushThread::start(int fd, int fd_dest) { - m_raw_source.setfd(fd_source); - m_fd_dest = fd_dest; - resume(); + eRawFile *f = new eRawFile(); + ePtr source = f; + f->setfd(fd); + start(source, fd_dest); } -int eFilePushThread::start(const char *filename, int fd_dest) +int eFilePushThread::start(const char *file, int fd_dest) { - if (m_raw_source.open(filename) < 0) + eRawFile *f = new eRawFile(); + ePtr source = f; + if (f->open(file) < 0) return -1; + start(source, fd_dest); + return 0; +} + +void eFilePushThread::start(ePtr &source, int fd_dest) +{ + m_source = source; m_fd_dest = fd_dest; + m_current_position = 0; resume(); - return 0; } void eFilePushThread::stop() @@ -273,11 +343,6 @@ void eFilePushThread::pause() stop(); } -void eFilePushThread::seek(int whence, off_t where) -{ - m_raw_source.lseek(where, whence); -} - void eFilePushThread::resume() { m_stop = 0; @@ -299,6 +364,16 @@ void eFilePushThread::setStreamMode(int s) m_stream_mode = s; } +void eFilePushThread::setTimeshift(bool s) +{ + m_is_timeshift = s; +} + +void eFilePushThread::setTSPath(const std::string s) +{ + m_tspath = s; +} + void eFilePushThread::setScatterGather(iFilePushScatterGather *sg) { m_sg = sg; @@ -314,6 +389,36 @@ void eFilePushThread::recvEvent(const int &evt) m_event(evt); } +void eFilePushThread::defaultTSPath(bool s) +{ + std::string tspath; + + if (s) { + if (ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1) + eDebug("could not query ts path from config"); + } else { + if (ePythonConfigQuery::getConfigValue("config.usage.instantrec_path", tspath) == -1) { + eDebug("could not query ts path from config"); + } else { + if (tspath == "") { + if (ePythonConfigQuery::getConfigValue("config.usage.default_path", tspath) == -1) + eDebug("could not query ts path from config"); + } else if (tspath == "") { + if (ePythonConfigQuery::getConfigValue("config.movielist.last_videodir", tspath) == -1) + eDebug("could not query ts path from config"); + } else if (tspath == "") { + if (ePythonConfigQuery::getConfigValue("config.movielist.last_timer_videodir", tspath) == -1) + eDebug("could not query ts path from config"); + } + } + } + + if (!tspath.empty()) + tspath.append("/"); + + m_tspath = tspath; +} + int eFilePushThread::filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining) { return len;