fix pts relative seeking, make pts_t signed
authorFelix Domke <tmbinc@elitedvb.net>
Tue, 15 Nov 2005 05:06:43 +0000 (05:06 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Tue, 15 Nov 2005 05:06:43 +0000 (05:06 +0000)
lib/dvb/dvb.cpp
lib/dvb/dvb.h
lib/dvb/idvb.h
lib/service/iservice.h
lib/service/servicedvb.cpp

index 78cef63..ed972bf 100644 (file)
@@ -618,27 +618,34 @@ RESULT eDVBChannel::getCurrentPosition(pts_t &pos)
        return 0;
 }
 
-RESULT eDVBChannel::seekTo(pts_t &pts)
+RESULT eDVBChannel::seekTo(int relative, pts_t &pts)
 {
-#if 0
-       eDebug("eDVBChannel: seekTo .. %llx", pts);
-       m_pvr_thread->pause();
-       if (m_decoder_demux)
-               m_decoder_demux->get().flush();
-               /* demux will also flush all decoder.. */
+       int bitrate = m_tstools.calcBitrate(); /* in bits/s */
        
-       off_t r;
+       if (bitrate == -1)
+               return -1;
        
-       if (!m_tstools.getPosition(pts, r));
-               m_pvr_thread->seek(r);
-       else
-               eDebug("getPosition failed!");
-       m_pvr_thread->resume();
-#endif
+       if (relative)
+       {
+               pts_t now;
+               if (getCurrentPosition(now))
+               {
+                       eDebug("seekTo: getCurrentPosition failed!");
+                       return -1;
+               }
+               pts += now;
+       }
+       
+       if (pts < 0)
+               pts = 0;
+       
+       off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
+       
+       seekToPosition(offset);
        return 0;
 }
 
-RESULT eDVBChannel::seekToPosition(int relative, const off_t &r)
+RESULT eDVBChannel::seekToPosition(const off_t &r)
 {
                        /* when seeking, we have to ensure that all buffers are flushed.
                           there are basically 3 buffers:
@@ -664,7 +671,7 @@ RESULT eDVBChannel::seekToPosition(int relative, const off_t &r)
                m_decoder_demux->get().flush();
 
                /* demux will also flush all decoder.. */
-       m_pvr_thread->seek(relative ? SEEK_CUR : SEEK_SET, r);
+       m_pvr_thread->seek(SEEK_SET, r);
        m_pvr_thread->resume();
        return 0;
 }
index 01a0e47..b739f0a 100644 (file)
@@ -192,8 +192,10 @@ public:
        RESULT playFile(const char *file);
        RESULT getLength(pts_t &len);
        RESULT getCurrentPosition(pts_t &pos);
-       RESULT seekTo(pts_t &pts);
-       RESULT seekToPosition(int relative, const off_t &off);
+       RESULT seekTo(int relative, pts_t &pts);
+                       /* seeking to relative positions won't work - 
+                          there is an unknown amount of buffers in between */
+       RESULT seekToPosition(const off_t &off);
 
 private:
        ePtr<eDVBAllocatedFrontend> m_frontend;
index a23960a..b68c014 100644 (file)
@@ -470,7 +470,8 @@ public:
        virtual void ReleaseUse() = 0;
 };
 
-typedef unsigned long long pts_t;
+       /* signed, so we can express deltas. */
+typedef long long pts_t;
 
 class iDVBPVRChannel: public iDVBChannel
 {
@@ -486,8 +487,8 @@ public:
        
        virtual RESULT getLength(pts_t &pts) = 0;
        virtual RESULT getCurrentPosition(pts_t &pos) = 0;
-       virtual RESULT seekTo(pts_t &pts) = 0;
-       virtual RESULT seekToPosition(int relative, const off_t &pts) = 0;
+       virtual RESULT seekTo(int relative, pts_t &pts) = 0;
+       virtual RESULT seekToPosition(const off_t &pts) = 0;
 };
 
 class iDVBSectionReader;
index 376ed02..98b9ba0 100644 (file)
@@ -146,7 +146,7 @@ public:
 
 SWIG_ALLOW_OUTPUT_SIMPLE(eServiceReference);
 
-typedef unsigned long long pts_t;
+typedef long long pts_t;
 
        /* the reason we have the servicereference as additional argument is
           that we don't have to create one object for every entry in a possibly
index d49c5f6..f805ee7 100644 (file)
@@ -652,8 +652,9 @@ RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
        if (m_service_handler.getPVRChannel(pvr_channel))
                return -1;
        
-                       /* this is of couse wrong: PTS values don't match with bytes. */
-       return pvr_channel->seekToPosition(SEEK_CUR, direction * to);
+       to *= direction;
+       
+       return pvr_channel->seekTo(1, to);
 }
 
 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)