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:
parent
de45b51473
commit
b47ce65b03
@ -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
|
||||
|
2
HISTORY
2
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).
|
||||
|
68
dvbapi.c
68
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)
|
||||
|
Loading…
Reference in New Issue
Block a user