1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Implemented backtracing for fast forward/rewind

This commit is contained in:
Klaus Schmidinger 2001-09-09 13:36:16 +02:00
parent de45b51473
commit b47ce65b03
3 changed files with 65 additions and 6 deletions

View File

@ -101,6 +101,7 @@ Stefan Huelswitt <huels@iname.com>
for making the width and height of the OSD configurable for making the width and height of the OSD configurable
for implementing the "Jump" function in replay mode for implementing the "Jump" function in replay mode
for implementing "Multi Speed Mode" for implementing "Multi Speed Mode"
for implementing backtracing for fast forward/rewind
Ulrich Röder <dynamite@efr-net.de> Ulrich Röder <dynamite@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than for pointing out that there are channels that have a symbol rate higher than

View File

@ -735,3 +735,5 @@ Video Disk Recorder Revision History
- Switching through channel groups with the "Left" and "Right" keys now - Switching through channel groups with the "Left" and "Right" keys now
always starts at the group that contains the current channel. always starts at the group that contains the current channel.
- Implemented "Multi Speed Mode" (thanks to Stefan Huelswitt). - Implemented "Multi Speed Mode" (thanks to Stefan Huelswitt).
- Implemented backtracing to hit the right spot after fast forward/rewind
(thanks to Stefan Huelswitt).

View File

@ -7,7 +7,7 @@
* DVD support initially written by Andreas Schultz <aschultz@warp10.net> * DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si> * 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 //#define DVDDEBUG 1
@ -628,11 +628,68 @@ int ReadFrame(int f, uchar *b, int Length, int Max)
return r; 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 --------------------------------------------------------- // --- cPlayBuffer ---------------------------------------------------------
#define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct? #define MAX_VIDEO_SLOWMOTION 63 // max. arg to pass to VIDEO_SLOWMOTION // TODO is this value correct?
class cPlayBuffer : public cRingBufferFrame { class cPlayBuffer : public cRingBufferFrame {
private:
cBackTrace backTrace;
protected: protected:
enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill }; enum ePlayModes { pmPlay, pmPause, pmSlow, pmFast, pmStill };
enum ePlayDirs { pdForward, pdBackward }; enum ePlayDirs { pdForward, pdBackward };
@ -729,6 +786,7 @@ void cPlayBuffer::Output(void)
} }
} }
writeIndex = frame->Index(); writeIndex = frame->Index();
backTrace.Add(frame->Index(), frame->Count());
Drop(frame); Drop(frame);
} }
} }
@ -766,13 +824,15 @@ void cPlayBuffer::Empty(bool Block)
while ((blockInput > 1 || blockOutput > 1) && time(NULL) - t0 < 2) while ((blockInput > 1 || blockOutput > 1) && time(NULL) - t0 < 2)
usleep(1); usleep(1);
Lock(); Lock();
readIndex = writeIndex; if ((readIndex = backTrace.Get(playDir == pdForward)) < 0)
readIndex = writeIndex;
cRingBufferFrame::Clear(); cRingBufferFrame::Clear();
CHECK(ioctl(videoDev, VIDEO_CLEAR_BUFFER)); CHECK(ioctl(videoDev, VIDEO_CLEAR_BUFFER));
CHECK(ioctl(audioDev, AUDIO_CLEAR_BUFFER)); CHECK(ioctl(audioDev, AUDIO_CLEAR_BUFFER));
} }
if (!Block) { if (!Block) {
blockInput = blockOutput = 0; blockInput = blockOutput = 0;
backTrace.Clear();
Unlock(); Unlock();
} }
} }
@ -830,10 +890,6 @@ void cPlayBuffer::Forward(void)
TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS); TrickSpeed(Setup.MultiSpeedMode ? -1 : -MAX_SPEEDS);
break; break;
case pmFast: 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) if (Setup.MultiSpeedMode)
TrickSpeed(playDir == pdForward ? 1 : -1); TrickSpeed(playDir == pdForward ? 1 : -1);
else if (playDir == pdForward) else if (playDir == pdForward)