tstools.h/cpp: migrate to iDataSource
[vuplus_dvbapp] / lib / dvb / tstools.cpp
index 6d64463..7739f60 100644 (file)
@@ -22,19 +22,41 @@ eDVBTSTools::eDVBTSTools()
        m_futile = 0;
 }
 
+void eDVBTSTools::closeSource()
+{
+       m_source = NULL;
+}
+
 eDVBTSTools::~eDVBTSTools()
 {
-       closeFile();
+       closeSource();
 }
 
 int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
 {
+       eRawFile *f = new eRawFile();
+       ePtr<iDataSource> src = f;
+
+       eSingleLocker l(f->getLock());
+
+       if (f->open(filename, 1) < 0)
+               return -1;
+
+       setSource(src, filename);
+
+       return 0;
+}
+
+void eDVBTSTools::setSource(ePtr<iDataSource> source, const char *stream_info_filename)
+{
        closeFile();
-       
-       if (!nostreaminfo)
+
+       m_source = source;
+
+       if (stream_info_filename)
        {
-               eDebug("loading streaminfo for %s", filename);
-               m_streaminfo.load(filename);
+               eDebug("loading streaminfo for %s", stream_info_filename);
+               m_streaminfo.load(stream_info_filename);
        }
        
        if (!m_streaminfo.empty())
@@ -44,17 +66,16 @@ int eDVBTSTools::openFile(const char *filename, int nostreaminfo)
 //             eDebug("no recorded stream information available");
                m_use_streaminfo = 0;
        }
-       
-       m_samples_taken = 0;
 
-       if (m_file.open(filename, 1) < 0)
-               return -1;
-       return 0;
+       m_samples_taken = 0;
 }
 
 void eDVBTSTools::closeFile()
 {
-       m_file.close();
+       if (m_source) {
+               eSingleLocker l(m_source->getLock());
+               closeSource();
+       }
 }
 
 void eDVBTSTools::setSyncPID(int pid)
@@ -74,12 +95,16 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                if (!m_streaminfo.getPTS(offset, pts))
                        return 0;
        
-       if (!m_file.valid())
+       if (!m_source->valid())
                return -1;
 
        offset -= offset % 188;
-       
-       if (m_file.lseek(offset, SEEK_SET) < 0)
+
+       iDataSourcePositionRestorer r(m_source);
+
+       eSingleLocker l(m_source->getLock());
+
+       if (m_source->lseek(offset, SEEK_SET) < 0)
        {
                eDebug("lseek failed");
                return -1;
@@ -90,7 +115,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
        while (left >= 188)
        {
                unsigned char packet[188];
-               if (m_file.read(packet, 188) != 188)
+               if (m_source->read(packet, 188) != 188)
                {
                        eDebug("read error");
                        break;
@@ -108,7 +133,7 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                                        break;
                                ++i;
                        }
-                       offset = m_file.lseek(i - 188, SEEK_CUR);
+                       offset = m_source->lseek(i - 188, SEEK_CUR);
                        continue;
                }
                
@@ -400,7 +425,7 @@ int eDVBTSTools::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction
 
 void eDVBTSTools::calcBegin()
 {
-       if (!m_file.valid())
+       if (!m_source->valid())
                return;
 
        if (!(m_begin_valid || m_futile))
@@ -415,10 +440,14 @@ void eDVBTSTools::calcBegin()
 
 void eDVBTSTools::calcEnd()
 {
-       if (!m_file.valid())
+       if (!m_source->valid())
                return;
-       
-       off_t end = m_file.lseek(0, SEEK_END);
+
+       iDataSourcePositionRestorer r(m_source);
+
+       eSingleLocker l(m_source->getLock());
+
+       off_t end = m_source->lseek(0, SEEK_END);
        
        if (llabs(end - m_last_filelength) > 1*1024*1024)
        {
@@ -568,13 +597,17 @@ int eDVBTSTools::takeSample(off_t off, pts_t &p)
 int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
 {
                /* FIXME: this will be factored out soon! */
-       if (!m_file.valid())
+       if (!m_source->valid())
        {
                eDebug(" file not valid");
                return -1;
        }
 
-       if (m_file.lseek(0, SEEK_SET) < 0)
+       iDataSourcePositionRestorer r(m_source);
+
+       eSingleLocker l(m_source->getLock());
+
+       if (m_source->lseek(0, SEEK_SET) < 0)
        {
                eDebug("seek failed");
                return -1;
@@ -585,7 +618,7 @@ int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
        while (left >= 188)
        {
                unsigned char packet[188];
-               if (m_file.read(packet, 188) != 188)
+               if (m_source->read(packet, 188) != 188)
                {
                        eDebug("read error");
                        break;
@@ -601,7 +634,7 @@ int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
                                        break;
                                ++i;
                        }
-                       m_file.lseek(i - 188, SEEK_CUR);
+                       m_source->lseek(i - 188, SEEK_CUR);
                        continue;
                }
                
@@ -722,18 +755,23 @@ int eDVBTSTools::findFrame(off_t &_offset, size_t &len, int &direction, int fram
 
 int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int frame_types)
 {
-       int nr_frames = 0;
+       int nr_frames, direction;
 //     eDebug("trying to move %d frames at %llx", distance, offset);
        
        frame_types = frametypeI; /* TODO: intelligent "allow IP frames when not crossing an I-Frame */
 
-       int direction = distance > 0 ? 0 : -1;
-       distance = abs(distance);
-       
        off_t new_offset = offset;
        size_t new_len = len;
        int first = 1;
 
+       if (distance > 0) {
+               direction = 0;
+                nr_frames = 0;
+        } else {
+               direction = -1;
+                nr_frames = -1;
+               distance = -distance+1;
+        }      
        while (distance > 0)
        {
                int dir = direction;
@@ -747,12 +785,18 @@ int eDVBTSTools::findNextPicture(off_t &offset, size_t &len, int &distance, int
                
 //             eDebug("we moved %d, %d to go frames (now at %llx)", dir, distance, new_offset);
 
-               if (distance >= 0 || first)
+               if (distance >= 0 || direction == 0)
                {
                        first = 0;
                        offset = new_offset;
                        len = new_len;
                        nr_frames += abs(dir);
+               } 
+               else if (first) {
+                       first = 0;
+                       offset = new_offset;
+                       len = new_len;
+                       nr_frames += abs(dir) + distance; // never jump forward during rewind
                }
        }