a little bit more error checking
[vuplus_dvbapp] / lib / dvb / tstools.cpp
index 6d64463..bd36308 100644 (file)
@@ -22,19 +22,39 @@ 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;
+
+       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 +64,14 @@ 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)
+               closeSource();
 }
 
 void eDVBTSTools::setSyncPID(int pid)
@@ -74,30 +91,24 @@ 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 || !m_source->valid())
                return -1;
 
        offset -= offset % 188;
-       
-       if (m_file.lseek(offset, SEEK_SET) < 0)
-       {
-               eDebug("lseek failed");
-               return -1;
-       }
-       
+
        int left = m_maxrange;
        
        while (left >= 188)
        {
                unsigned char packet[188];
-               if (m_file.read(packet, 188) != 188)
+               if (m_source->read(offset, packet, 188) != 188)
                {
                        eDebug("read error");
                        break;
                }
                left -= 188;
                offset += 188;
-               
+
                if (packet[0] != 0x47)
                {
                        eDebug("resync");
@@ -107,8 +118,8 @@ int eDVBTSTools::getPTS(off_t &offset, pts_t &pts, int fixed)
                                if (packet[i] == 0x47)
                                        break;
                                ++i;
+                               --offset;
                        }
-                       offset = m_file.lseek(i - 188, SEEK_CUR);
                        continue;
                }
                
@@ -400,7 +411,7 @@ int eDVBTSTools::getNextAccessPoint(pts_t &ts, const pts_t &start, int direction
 
 void eDVBTSTools::calcBegin()
 {
-       if (!m_file.valid())
+       if (!m_source || !m_source->valid())
                return;
 
        if (!(m_begin_valid || m_futile))
@@ -415,10 +426,10 @@ void eDVBTSTools::calcBegin()
 
 void eDVBTSTools::calcEnd()
 {
-       if (!m_file.valid())
+       if (!m_source || !m_source->valid())
                return;
-       
-       off_t end = m_file.lseek(0, SEEK_END);
+
+       off_t end = m_source->lseek(0, SEEK_END);
        
        if (llabs(end - m_last_filelength) > 1*1024*1024)
        {
@@ -568,30 +579,28 @@ 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 || !m_source->valid())
        {
                eDebug(" file not valid");
                return -1;
        }
 
-       if (m_file.lseek(0, SEEK_SET) < 0)
-       {
-               eDebug("seek failed");
-               return -1;
-       }
+       off_t position=0;
 
        int left = 5*1024*1024;
        
        while (left >= 188)
        {
                unsigned char packet[188];
-               if (m_file.read(packet, 188) != 188)
+               int ret = m_source->read(position, packet, 188);
+               if (ret != 188)
                {
                        eDebug("read error");
                        break;
                }
                left -= 188;
-               
+               position += 188;
+
                if (packet[0] != 0x47)
                {
                        int i = 0;
@@ -599,12 +608,11 @@ int eDVBTSTools::findPMT(int &pmt_pid, int &service_id)
                        {
                                if (packet[i] == 0x47)
                                        break;
+                               --position;
                                ++i;
                        }
-                       m_file.lseek(i - 188, SEEK_CUR);
                        continue;
                }
-               
                int pid = ((packet[1] << 8) | packet[2]) & 0x1FFF;
                
                int pusi = !!(packet[1] & 0x40);
@@ -722,18 +730,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 +760,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
                }
        }