diff --git a/CONTRIBUTORS b/CONTRIBUTORS index c24496f1..74390cf9 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -13,3 +13,6 @@ Plamen Ganev Heino Goldenstein for modifying scrolling through lists to make it page up and down + +Guido Fiala + for implementing slow forward/back diff --git a/HISTORY b/HISTORY index 0f564cc5..58e7f1cd 100644 --- a/HISTORY +++ b/HISTORY @@ -100,7 +100,7 @@ Video Disk Recorder Revision History the 'timers.conf' file with a text editor, or by defining/modifying the timer via the SVDRP interface. -2000-07-29: +2000-07-30: - When scrolling through a list it now moves a full page up or down when the cursor reaches the top or bottom of the menu (thanks to Heino Goldenstein!). @@ -111,3 +111,4 @@ Video Disk Recorder Revision History - Fixed learning key codes for PC keyboard. - New command line option '-l' to set the log level. - Times in timers.conf are now always printed with 4 digits (leading '0'). +- Slow forward/back mode (thanks to Guido Fiala!). diff --git a/MANUAL b/MANUAL index c9b71a37..9d94a5ad 100644 --- a/MANUAL +++ b/MANUAL @@ -100,8 +100,9 @@ Video Disk Recorder User's Manual - Blue Stops playback and stores the current position, so that playback can be resumed later at that point. - Left - Right Runs playback forward or backward at a higher speed. Press - again to resume normal speed. + Right Runs playback forward or backward at a higher speed; press + again to resume normal speed. If in Pause mode, runs forward or + backward at a slower speed; press again to return to pause mode. - Green Yellow Skips about 60 seconds back or forward. - Ok Brings up the replay progress display, which shows the date, diff --git a/dvbapi.c b/dvbapi.c index ca439da7..c85be90b 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.c 1.17 2000/07/29 19:00:19 kls Exp $ + * $Id: dvbapi.c 1.18 2000/07/30 14:34:07 kls Exp $ */ #include "dvbapi.h" @@ -345,7 +345,7 @@ protected: int Free(void) { return ((tail >= head) ? size + head - tail : head - tail) - 1; } int Available(void) { return (tail >= head) ? tail - head : size - head + tail; } int Readable(void) { return (tail >= head) ? size - tail - (head ? 0 : 1) : head - tail - 1; } // keep a 1 byte gap! - int Writeable(void) { return (tail > head) ? tail - head : size - head; } + int Writeable(void) { return (tail >= head) ? tail - head : size - head; } int Byte(int Offset); bool WaitForOutFile(int Timeout); public: @@ -803,7 +803,7 @@ int cRecordBuffer::WriteWithTimeout(bool EndIfEmpty) // --- cReplayBuffer --------------------------------------------------------- -enum eReplayMode { rmPlay, rmFastForward, rmFastRewind }; +enum eReplayMode { rmPlay, rmFastForward, rmFastRewind, rmSlowRewind }; class cReplayBuffer : public cFileBuffer { private: @@ -812,6 +812,7 @@ private: eReplayMode mode; bool skipAudio; int lastIndex; + int brakeCounter; void SkipAudioBlocks(void); bool NextFile(uchar FileNumber = 0, int FileOffset = -1); void Close(void); @@ -833,6 +834,7 @@ cReplayBuffer::cReplayBuffer(int *OutFile, const char *FileName) fileOffset = 0; replayFile = -1; mode = rmPlay; + brakeCounter = 0; skipAudio = false; lastIndex = -1; if (!fileName) @@ -863,6 +865,7 @@ void cReplayBuffer::SetMode(eReplayMode Mode) { mode = Mode; skipAudio = Mode != rmPlay; + brakeCounter = 0; if (mode != rmPlay) Clear(); } @@ -996,6 +999,10 @@ int cReplayBuffer::Read(int Max = -1) if (Index >= 0) { uchar FileNumber; int FileOffset, Length; + if (mode == rmSlowRewind && (brakeCounter++ % 24) != 0) { + // show every I_FRAME 24 times in rmSlowRewind mode to achieve roughly the same speed as in slow forward mode + Index = index->GetNextIFrame(Index, true, &FileNumber, &FileOffset, &Length); //springe eine Frame vorwärts! + } Index = index->GetNextIFrame(Index, mode == rmFastForward, &FileNumber, &FileOffset, &Length); if (Index >= 0) { if (!NextFile(FileNumber, FileOffset)) @@ -1601,18 +1608,34 @@ bool cDvbApi::StartReplay(const char *FileName, const char *Title) Buffer->SetMode(rmPlay); break; case dvbFastForward: SetReplayMode(VID_PLAY_CLEAR_BUFFER); - SetReplayMode(VID_PLAY_NORMAL); - FastForward = !FastForward; - FastRewind = Paused = false; Buffer->Clear(); - Buffer->SetMode(FastForward ? rmFastForward : rmPlay); + FastForward = !FastForward; + FastRewind = false; + if (Paused) { + Buffer->SetMode(rmPlay); + Buffer->Read(); + SetReplayMode(FastForward ? VID_PLAY_SLOW_MOTION : VID_PLAY_PAUSE); + Buffer->Write(); + } + else { + SetReplayMode(VID_PLAY_NORMAL); + Buffer->SetMode(FastForward ? rmFastForward : rmPlay); + } break; case dvbFastRewind: SetReplayMode(VID_PLAY_CLEAR_BUFFER); - SetReplayMode(VID_PLAY_NORMAL); - FastRewind = !FastRewind; - FastForward = Paused = false; Buffer->Clear(); - Buffer->SetMode(FastRewind ? rmFastRewind : rmPlay); + FastRewind = !FastRewind; + FastForward = false; + if (Paused) { + Buffer->SetMode(FastRewind ? rmSlowRewind : rmPlay); + Buffer->Read(); + SetReplayMode(FastRewind ? VID_PLAY_NORMAL : VID_PLAY_PAUSE); + Buffer->Write(); + } + else { + SetReplayMode(VID_PLAY_NORMAL); + Buffer->SetMode(FastRewind ? rmFastRewind : rmPlay); + } break; case dvbSkip: { int Seconds;