summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY2
-rw-r--r--dvbapi.c68
3 files changed, 65 insertions, 6 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 4d5dee50..f3d96430 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -101,6 +101,7 @@ Stefan Huelswitt <huels@iname.com>
for making the width and height of the OSD configurable
for implementing the "Jump" function in replay mode
for implementing "Multi Speed Mode"
+ for implementing backtracing for fast forward/rewind
Ulrich Röder <dynamite@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than
diff --git a/HISTORY b/HISTORY
index be38534c..66970ced 100644
--- a/HISTORY
+++ b/HISTORY
@@ -735,3 +735,5 @@ Video Disk Recorder Revision History
- Switching through channel groups with the "Left" and "Right" keys now
always starts at the group that contains the current channel.
- Implemented "Multi Speed Mode" (thanks to Stefan Huelswitt).
+- Implemented backtracing to hit the right spot after fast forward/rewind
+ (thanks to Stefan Huelswitt).
diff --git a/dvbapi.c b/dvbapi.c
index 69ee8ec2..6e0103ac 100644
--- a/dvbapi.c
+++ b/dvbapi.c
@@ -7,7 +7,7 @@
* DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>
*
- * $Id: dvbapi.c 1.113 2001/09/09 12:52:41 kls Exp $
+ * $Id: dvbapi.c 1.114 2001/09/09 13:34:41 kls Exp $
*/
//#define DVDDEBUG 1
@@ -628,11 +628,68 @@ int ReadFrame(int f, uchar *b, int Length, int Max)
return r;
}
+// --- cBackTrace ----------------------------------------------------------
+
+#define AVG_FRAME_SIZE 15000 // an assumption about the average frame size
+#define DVB_BUF_SIZE (256 * 1024) // an assumption about the dvb firmware buffer size
+#define BACKTRACE_ENTRIES (DVB_BUF_SIZE / AVG_FRAME_SIZE + 20) // how many entries are needed to backtrace buffer contents
+
+class cBackTrace {
+private:
+ int index[BACKTRACE_ENTRIES];
+ int length[BACKTRACE_ENTRIES];
+ int pos, num;
+public:
+ cBackTrace(void);
+ void Clear(void);
+ void Add(int Index, int Length);
+ int Get(bool Forward);
+ };
+
+cBackTrace::cBackTrace(void)
+{
+ Clear();
+}
+
+void cBackTrace::Clear(void)
+{
+ pos = num = 0;
+}
+
+void cBackTrace::Add(int Index, int Length)
+{
+ index[pos] = Index;
+ length[pos] = Length;
+ if (++pos >= BACKTRACE_ENTRIES)
+ pos = 0;
+ if (num < BACKTRACE_ENTRIES)
+ num++;
+}
+
+int cBackTrace::Get(bool Forward)
+{
+ int p = pos;
+ int n = num;
+ int l = DVB_BUF_SIZE + (Forward ? 0 : 256 * 1024); //XXX (256 * 1024) == DVB_BUF_SIZE ???
+ int i = -1;
+
+ while (n && l > 0) {
+ if (--p < 0)
+ p = BACKTRACE_ENTRIES - 1;
+ i = index[p] - 1;
+ l -= length[p];
+ n--;
+ }
+ return i;
+}
+
// --- cPlayBuffer ---------------------------------------------------------
#define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct?
class cPlayBuffer : public cRingBufferFrame {
+private:
+ cBackTrace backTrace;
protected:
enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill };
enum ePlayDirs { pdForward, pdBackward };
@@ -729,6 +786,7 @@ void cPlayBuffer::Output(void)
}
}
writeIndex = frame->Index();
+ backTrace.Add(frame->Index(), frame->Count());
Drop(frame);
}
}
@@ -766,13 +824,15 @@ void cPlayBuffer::Empty(bool Block)
while ((blockInput > 1 || blockOutput > 1) && time(NULL) - t0 < 2)
usleep(1);
Lock();
- readIndex = writeIndex;
+ if ((readIndex = backTrace.Get(playDir == pdForward)) < 0)
+ readIndex = writeIndex;
cRingBufferFrame::Clear();
CHECK(ioctl(videoDev, VIDEO_CLEAR_BUFFER));
CHECK(ioctl(audioDev, AUDIO_CLEAR_BUFFER));
}
if (!Block) {
blockInput = blockOutput = 0;
+ backTrace.Clear();
Unlock();
}
}
@@ -830,10 +890,6 @@ void cPlayBuffer::Forward(void)
TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS);
break;
case pmFast:
- //XXX
- if (playDir == pdForward)
- readIndex -= 150; // this about compensates for the buffered data, so that we don't get too far ahead
- //XXX
if (Setup.MultiSpeedMode)
TrickSpeed(playDir == pdForward ? 1 : -1);
else if (playDir == pdForward)