diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f3d96430..bf3a39cc 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -102,6 +102,7 @@ Stefan Huelswitt for implementing the "Jump" function in replay mode for implementing "Multi Speed Mode" for implementing backtracing for fast forward/rewind + for implementing the replay mode display Ulrich Röder for pointing out that there are channels that have a symbol rate higher than diff --git a/HISTORY b/HISTORY index 66970ced..930bc906 100644 --- a/HISTORY +++ b/HISTORY @@ -716,7 +716,7 @@ Video Disk Recorder Revision History That way every recording will store the actual summary data at the time of the recording. -2001-09-09: Version 0.95 +2001-09-14: Version 0.95 - Fixed behaviour in case the shutdown didn't take place (there were many "next timer event at..." messages in that case). @@ -737,3 +737,5 @@ Video Disk Recorder Revision History - Implemented "Multi Speed Mode" (thanks to Stefan Huelswitt). - Implemented backtracing to hit the right spot after fast forward/rewind (thanks to Stefan Huelswitt). +- Implemented replay mode display (thanks to Stefan Huelswitt, with a few + rewrites by kls). diff --git a/MANUAL b/MANUAL index d7bf23af..83a1aa2a 100644 --- a/MANUAL +++ b/MANUAL @@ -462,6 +462,10 @@ Video Disk Recorder User's Manual 0 = off 1 = on + ShowReplayMode = 0 Turns displaying the current replay mode on or off. + 0 = off + 1 = on + * Executing system commands The "Main" menu option "Commands" allows you to execute any system commands diff --git a/config.c b/config.c index 171400b6..8cf69110 100644 --- a/config.c +++ b/config.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.c 1.68 2001/09/08 14:59:38 kls Exp $ + * $Id: config.c 1.69 2001/09/09 13:52:48 kls Exp $ */ #include "config.h" @@ -813,6 +813,7 @@ cSetup::cSetup(void) MinEventTimeout = 30; MinUserInactivity = 120; MultiSpeedMode = 0; + ShowReplayMode = 0; CurrentChannel = -1; } @@ -851,6 +852,7 @@ bool cSetup::Parse(char *s) else if (!strcasecmp(Name, "MinEventTimeout")) MinEventTimeout = atoi(Value); else if (!strcasecmp(Name, "MinUserInactivity")) MinUserInactivity = atoi(Value); else if (!strcasecmp(Name, "MultiSpeedMode")) MultiSpeedMode = atoi(Value); + else if (!strcasecmp(Name, "ShowReplayMode")) ShowReplayMode = atoi(Value); else if (!strcasecmp(Name, "CurrentChannel")) CurrentChannel = atoi(Value); else return false; @@ -924,6 +926,7 @@ bool cSetup::Save(const char *FileName) fprintf(f, "MinEventTimeout = %d\n", MinEventTimeout); fprintf(f, "MinUserInactivity = %d\n", MinUserInactivity); fprintf(f, "MultiSpeedMode = %d\n", MultiSpeedMode); + fprintf(f, "ShowReplayMode = %d\n", ShowReplayMode); fprintf(f, "CurrentChannel = %d\n", CurrentChannel); f.Close(); isyslog(LOG_INFO, "saved setup to %s", FileName); diff --git a/config.h b/config.h index 8af48869..328d39ab 100644 --- a/config.h +++ b/config.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: config.h 1.75 2001/09/08 14:58:16 kls Exp $ + * $Id: config.h 1.76 2001/09/09 13:51:45 kls Exp $ */ #ifndef __CONFIG_H @@ -298,6 +298,7 @@ public: int MaxVideoFileSize; int MinEventTimeout, MinUserInactivity; int MultiSpeedMode; + int ShowReplayMode; int CurrentChannel; cSetup(void); bool Load(const char *FileName); diff --git a/dvbapi.c b/dvbapi.c index 6e0103ac..bdb2d271 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -7,7 +7,7 @@ * DVD support initially written by Andreas Schultz * based on dvdplayer-0.5 by Matjaz Thaler * - * $Id: dvbapi.c 1.114 2001/09/09 13:34:41 kls Exp $ + * $Id: dvbapi.c 1.115 2001/09/14 13:23:21 kls Exp $ */ //#define DVDDEBUG 1 @@ -720,6 +720,7 @@ public: virtual void SkipSeconds(int Seconds) {} virtual void Goto(int Position, bool Still = false) {} virtual void GetIndex(int &Current, int &Total, bool SnapToIFrame = false) { Current = Total = -1; } + bool GetReplayMode(bool &Play, bool &Forward, int &Speed); bool CanToggleAudioTrack(void) { return canToggleAudioTrack; }; virtual void ToggleAudioTrack(void); }; @@ -944,6 +945,17 @@ void cPlayBuffer::Backward(void) } } +bool cPlayBuffer::GetReplayMode(bool &Play, bool &Forward, int &Speed) +{ + Play = (playMode == pmPlay || playMode == pmFast); + Forward = (playDir == pdForward); + if (playMode == pmFast || playMode == pmSlow) + Speed = Setup.MultiSpeedMode ? abs(trickSpeed - NORMAL_SPEED) : 0; + else + Speed = -1; + return true; +} + void cPlayBuffer::ToggleAudioTrack(void) { if (CanToggleAudioTrack()) { @@ -2912,7 +2924,7 @@ void cDvbApi::Open(int w, int h) cols = w; rows = h; #ifdef DEBUG_OSD - window = subwin(stdscr, h, w, d, 0); + window = subwin(stdscr, h, w, d, (Setup.OSDwidth - w) / 2); syncok(window, true); #define B2C(b) (((b) * 1000) / 255) #define SETCOLOR(n, r, g, b, o) init_color(n, B2C(r), B2C(g), B2C(b)) @@ -2930,7 +2942,7 @@ void cDvbApi::Open(int w, int h) w *= charWidth; h *= lineHeight; d *= lineHeight; - int x = (720 - (Setup.OSDwidth - 1) * charWidth) / 2; //TODO PAL vs. NTSC??? + int x = (720 - w + charWidth) / 2; //TODO PAL vs. NTSC??? int y = (576 - Setup.OSDheight * lineHeight) / 2 + d; //XXX osd = new cDvbOsd(fd_osd, x, y); @@ -3557,6 +3569,11 @@ bool cDvbApi::GetIndex(int &Current, int &Total, bool SnapToIFrame) return false; } +bool cDvbApi::GetReplayMode(bool &Play, bool &Forward, int &Speed) +{ + return replayBuffer && replayBuffer->GetReplayMode(Play, Forward, Speed); +} + void cDvbApi::Goto(int Position, bool Still) { if (replayBuffer) diff --git a/dvbapi.h b/dvbapi.h index d0e22e6e..508942e6 100644 --- a/dvbapi.h +++ b/dvbapi.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.h 1.48 2001/09/08 11:35:25 kls Exp $ + * $Id: dvbapi.h 1.49 2001/09/09 14:37:18 kls Exp $ */ #ifndef __DVBAPI_H @@ -289,6 +289,12 @@ public: bool GetIndex(int &Current, int &Total, bool SnapToIFrame = false); // Returns the current and total frame index, optionally snapped to the // nearest I-frame. + bool GetReplayMode(bool &Play, bool &Forward, int &Speed); + // Returns the current replay mode (if applicable). + // 'Play' tells whether we are playing or pausing, 'Forward' tells whether + // we are going forward or backward and 'Speed' is -1 if this is normal + // play/pause mode, 0 if it is single speed fast/slow forward/back mode + // and >0 if this is multi speed mode. void Goto(int Index, bool Still = false); // Positions to the given index and displays that frame as a still picture // if Still is true. diff --git a/i18n.c b/i18n.c index 9fee5055..1170c244 100644 --- a/i18n.c +++ b/i18n.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: i18n.c 1.41 2001/09/08 15:01:12 kls Exp $ + * $Id: i18n.c 1.42 2001/09/09 13:54:35 kls Exp $ * * Slovenian translations provided by Miha Setina * Italian translations provided by Alberto Carraro @@ -956,6 +956,15 @@ const tPhrase Phrases[] = { "", // TODO "", // TODO }, + { "ShowReplayMode", + "Wiedergabe Status", + "", // TODO + "", // TODO + "", // TODO + "", // TODO + "", // TODO + "", // TODO + }, // The days of the week: { "MTWTFSS", "MDMDFSS", diff --git a/menu.c b/menu.c index 5e582777..3998d2a5 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.117 2001/09/08 15:05:16 kls Exp $ + * $Id: menu.c 1.118 2001/09/14 14:01:21 kls Exp $ */ #include "menu.h" @@ -16,8 +16,9 @@ #include "eit.h" #include "i18n.h" -#define MENUTIMEOUT 120 // seconds -#define MAXWAIT4EPGINFO 10 // seconds +#define MENUTIMEOUT 120 // seconds +#define MAXWAIT4EPGINFO 10 // seconds +#define MODETIMEOUT 3 // seconds const char *FileNameChars = " aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789-.#~^"; @@ -1726,6 +1727,7 @@ void cMenuSetup::Set(void) Add(new cMenuEditIntItem( tr("MinEventTimeout"), &data.MinEventTimeout)); Add(new cMenuEditIntItem( tr("MinUserInactivity"), &data.MinUserInactivity)); Add(new cMenuEditBoolItem(tr("MultiSpeedMode"), &data.MultiSpeedMode)); + Add(new cMenuEditBoolItem(tr("ShowReplayMode"), &data.ShowReplayMode)); } eOSState cMenuSetup::ProcessKey(eKeys Key) @@ -2332,7 +2334,7 @@ int cReplayControl::titleid = 0;//XXX cReplayControl::cReplayControl(void) { dvbApi = cDvbApi::PrimaryDvbApi; - visible = shown = displayFrames = false; + visible = modeOnly = shown = displayFrames = false; lastCurrent = lastTotal = -1; timeoutShow = 0; timeSearchActive = false; @@ -2395,10 +2397,47 @@ void cReplayControl::Hide(void) { if (visible) { Interface->Close(); - needsFastResponse = visible = false; + needsFastResponse = visible = modeOnly = false; } } +bool cReplayControl::ShowMode(void) +{ + if (Setup.ShowReplayMode) { + bool Play, Forward; + int Speed; + if (dvbApi->GetReplayMode(Play, Forward, Speed)) { + + if (!visible) { + // open small display + Interface->Open(9, -1); + Interface->Clear(); + visible = modeOnly = true; + } + + timeoutShow = (modeOnly && !timeoutShow && Speed == -1 && Play) ? time(NULL) + MODETIMEOUT : 0; + const char *Mode; + if (Speed == -1) Mode = Play ? " > " : " || "; + else if (Play) Mode = Forward ? " X>> " : " < " : " <|X "; + char buf[16]; + strn0cpy(buf, Mode, sizeof(buf)); + char *p = strchr(buf, 'X'); + if (p) + *p = Speed > 0 ? '1' + Speed - 1 : ' '; + + eDvbFont OldFont = Interface->SetFont(fontFix); + int w = dvbApi->WidthInCells(buf); + int d = max(Width() - w, 0) / 2; + Interface->Write(d, -1, buf); + Interface->Flush(); + Interface->SetFont(OldFont); + return true; + } + } + return false; +} + bool cReplayControl::ShowProgress(bool Initial) { int Current, Total; @@ -2435,6 +2474,7 @@ bool cReplayControl::ShowProgress(bool Initial) lastCurrent = Current; } lastTotal = Total; + ShowMode(); return true; } return false; @@ -2514,6 +2554,7 @@ void cReplayControl::TimeSearchProcess(eKeys Key) Hide(); else Interface->Fill(12, 2, Width() - 22, 1, clrBackground); + ShowMode(); } } @@ -2624,7 +2665,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key) Hide(); timeoutShow = 0; } - else + else if (!modeOnly) shown = ShowProgress(!shown) || shown; } bool DisplayedFrames = displayFrames; @@ -2633,6 +2674,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key) TimeSearchProcess(Key); return osContinue; } + bool DoShowMode = true; switch (Key) { // Positioning: case kUp: dvbApi->Play(); break; @@ -2652,6 +2694,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key) dvbApi->StopReplay(); return osEnd; default: { + DoShowMode = false; switch (Key) { // Editing: //XXX should we do this only when the ProgressDisplay is on??? @@ -2677,6 +2720,8 @@ eOSState cReplayControl::ProcessKey(eKeys Key) } } } + if (DoShowMode) + ShowMode(); if (DisplayedFrames && !displayFrames) Interface->Fill(0, 2, 11, 1, clrBackground); return osContinue; diff --git a/menu.h b/menu.h index d07684ae..a03c26f3 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.26 2001/09/08 13:58:46 kls Exp $ + * $Id: menu.h 1.27 2001/09/14 13:42:08 kls Exp $ */ #ifndef _MENU_H @@ -102,7 +102,7 @@ class cReplayControl : public cOsdBase { private: cDvbApi *dvbApi; cMarks marks; - bool visible, shown, displayFrames; + bool visible, modeOnly, shown, displayFrames; int lastCurrent, lastTotal; time_t timeoutShow; bool timeSearchActive, timeSearchHide; @@ -118,6 +118,7 @@ private: static int titleid;//XXX #endif //DVDSUPPORT static char *title; + bool ShowMode(void); bool ShowProgress(bool Initial); void MarkToggle(void); void MarkJump(bool Forward); diff --git a/tools.h b/tools.h index 2f89f3f0..50ea74cc 100644 --- a/tools.h +++ b/tools.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: tools.h 1.31 2001/08/26 12:52:49 kls Exp $ + * $Id: tools.h 1.32 2001/09/14 13:40:35 kls Exp $ */ #ifndef __TOOLS_H @@ -31,7 +31,9 @@ extern int SysLogLevel; #define DELETENULL(p) (delete (p), p = NULL) -template inline void swap(T &a, T &b) { T t = a; a = b; b = t; }; +template inline T min(T a, T b) { return a <= b ? a : b; } +template inline T max(T a, T b) { return a >= b ? a : b; } +template inline void swap(T &a, T &b) { T t = a; a = b; b = t; } ssize_t safe_read(int filedes, void *buffer, size_t size); ssize_t safe_write(int filedes, const void *buffer, size_t size);