From 5b65773ec836a6086374657098bbcc55e74abd60 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 12 Nov 2000 14:06:53 +0100 Subject: [PATCH] Using timer priority to interrupt lower priority timer recording --- HISTORY | 8 +++++++- MANUAL | 4 +++- config.c | 10 +++++----- config.h | 5 ++++- dvbapi.c | 30 ++++++++++++++++++++---------- dvbapi.h | 25 +++++++++++++++++++------ menu.c | 19 ++++++++++++++++--- menu.h | 4 +++- 8 files changed, 77 insertions(+), 28 deletions(-) diff --git a/HISTORY b/HISTORY index bf328597..6057a8ad 100644 --- a/HISTORY +++ b/HISTORY @@ -266,7 +266,7 @@ Video Disk Recorder Revision History are programmed via the "Schedules" menu) are now replaced by suitable substitutes. -2000-11-11: Version 0.68 +2000-11-12: Version 0.68 - Date and time in the title of an event info page are now always right adjusted. - The 'current channel' is now handled device specific (in case there is more @@ -281,3 +281,9 @@ Video Disk Recorder Revision History - There can now be a configuration file named 'commands.conf' that defines commands that can be executed through the "Main" menu's "Commands" option (see FORMATS for details on how to define these commands). +- The 'Priority' parameter of the timers is now also used to interrupt a low + priority timer recording if a higher priority timer wants to record. +- A timer recording on a DVB card with a CAM module will now be interrupted + by a timer that needs to use this specific DVB card to record an encrypted + channel, if the timer currently occupying this DVB card doesn't need the + CAM module (and thus can continue recording on a different DVB card). diff --git a/MANUAL b/MANUAL index 3f0b1f7b..a72c580d 100644 --- a/MANUAL +++ b/MANUAL @@ -203,7 +203,9 @@ Video Disk Recorder User's Manual to free space for a new recording. If the disk is full and a new recording needs more space, an existing recording with the lowest Priority (and which has exceeded its guaranteed Lifetime) will be - removed. + removed. If all available DVB cards are currently occupied, a + timer with a higher priority will interrupt the timer with the + lowest priority in order to start recording. Lifetime: The number of days (0..99) a recording made through this timer is guaranteed to remain on disk before it is automatically removed to free up space for a new recording. Note that setting this diff --git a/config.c b/config.c index d4f8b383..f7344169 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.32 2000/11/11 15:41:07 kls Exp $ + * $Id: config.c 1.33 2000/11/12 12:22:40 kls Exp $ */ #include "config.h" @@ -294,8 +294,8 @@ cTimer::cTimer(bool Instant) if (stop >= 2400) stop -= 2400; //TODO VPS??? - priority = 99; - lifetime = 99; + priority = DEFAULTPRIORITY; + lifetime = DEFAULTLIFETIME; *file = 0; summary = NULL; if (Instant && ch) @@ -319,8 +319,8 @@ cTimer::cTimer(const cEventInfo *EventInfo) stop = time->tm_hour * 100 + time->tm_min; if (stop >= 2400) stop -= 2400; - priority = 99; - lifetime = 99; + priority = DEFAULTPRIORITY; + lifetime = DEFAULTLIFETIME; *file = 0; const char *Title = EventInfo->GetTitle(); if (!isempty(Title)) diff --git a/config.h b/config.h index c6f6ba99..dd6b5f88 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.32 2000/11/11 14:39:40 kls Exp $ + * $Id: config.h 1.33 2000/11/12 12:22:24 kls Exp $ */ #ifndef __CONFIG_H @@ -95,6 +95,9 @@ public: bool Switch(cDvbApi *DvbApi = NULL); }; +#define DEFAULTPRIORITY 99 +#define DEFAULTLIFETIME 99 + class cTimer : public cListObject { private: time_t startTime, stopTime; diff --git a/dvbapi.c b/dvbapi.c index 0737d304..886348d7 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.36 2000/11/05 18:30:58 kls Exp $ + * $Id: dvbapi.c 1.37 2000/11/12 12:59:50 kls Exp $ */ #include "dvbapi.h" @@ -1091,6 +1091,8 @@ cDvbApi::cDvbApi(const char *VideoFileName, const char *VbiFileName) pidRecord = pidReplay = 0; fromRecord = toRecord = -1; fromReplay = toReplay = -1; + ca = 0; + priority = -1; videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK); if (videoDev >= 0) { siProcessor = new cSIProcessor(VbiFileName); @@ -1161,22 +1163,25 @@ bool cDvbApi::SetPrimaryDvbApi(int n) return false; } -cDvbApi *cDvbApi::GetDvbApi(int Ca) +cDvbApi *cDvbApi::GetDvbApi(int Ca, int Priority) { cDvbApi *d = NULL; - Ca--; + int index = Ca - 1; for (int i = MAXDVBAPI; --i >= 0; ) { - if (dvbApi[i] && !dvbApi[i]->Recording()) { - if (i == Ca) - return dvbApi[i]; - if (Ca < 0) { + if (dvbApi[i]) { + if (i == index) { // means we need exactly _this_ device d = dvbApi[i]; - if (d != PrimaryDvbApi) + break; + } + else if (Ca == 0) { // means any device would be acceptable + if (!d || !dvbApi[i]->Recording() || (d->Recording() && d->Priority() > dvbApi[i]->Priority())) + d = dvbApi[i]; + if (d && d != PrimaryDvbApi && !d->Recording()) // avoids the PrimaryDvbApi if possible break; } } } - return d; + return (d && (!d->Recording() || d->Priority() < Priority || (!d->Ca() && Ca))) ? d : NULL; } int cDvbApi::Index(void) @@ -1746,7 +1751,7 @@ bool cDvbApi::Replaying(void) return pidReplay; } -bool cDvbApi::StartRecord(const char *FileName) +bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority) { if (Recording()) { esyslog(LOG_ERR, "ERROR: StartRecord() called while recording - ignored!"); @@ -1843,6 +1848,9 @@ bool cDvbApi::StartRecord(const char *FileName) fromRecord = fromRecordPipe[0]; toRecord = toRecordPipe[1]; + + ca = Ca; + priority = Priority; return true; } return false; @@ -1857,6 +1865,8 @@ void cDvbApi::StopRecord(void) toRecord = fromRecord = -1; KillProcess(pidRecord); pidRecord = 0; + ca = 0; + priority = -1; SetReplayMode(VID_PLAY_RESET); //XXX } } diff --git a/dvbapi.h b/dvbapi.h index aa8dbcf3..7e237379 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.22 2000/11/05 13:39:31 kls Exp $ + * $Id: dvbapi.h 1.23 2000/11/12 12:52:41 kls Exp $ */ #ifndef __DVBAPI_H @@ -59,11 +59,15 @@ public: static bool SetPrimaryDvbApi(int n); // Sets the primary DVB device to 'n' (which must be in the range // 1...NumDvbApis) and returns true if this was possible. - static cDvbApi *GetDvbApi(int Ca = 0); + static cDvbApi *GetDvbApi(int Ca, int Priority); // Selects a free DVB device, starting with the highest device number // (but avoiding, if possible, the PrimaryDvbApi). - // If Ca is not 0, the device with the given number will be returned - // if it is not currently recording. + // If Ca is not 0, the device with the given number will be returned. + // If all DVB devices are currently recording, the one recording the + // lowest priority timer (if any) that is lower than the given Priority + // will be returned. + // The caller must check whether the returned DVB device is actually + // recording and stop recording if necessary. int Index(void); // Returns the index of this DvbApi. static bool Init(void); @@ -158,14 +162,23 @@ private: pid_t pidRecord, pidReplay; int fromRecord, toRecord; int fromReplay, toReplay; + int ca; + int priority; void SetReplayMode(int Mode); +protected: + int Ca(void) { return ca; } + // Returns the ca of the current recording session (0..MAXDVBAPI). + int Priority(void) { return priority; } + // Returns the priority of the current recording session (0..99), + // or -1 if no recording is currently active. public: bool Recording(void); // Returns true if we are currently recording. bool Replaying(void); // Returns true if we are currently replaying. - bool StartRecord(const char *FileName); - // Starts recording the current channel into the given file. + bool StartRecord(const char *FileName, int Ca, int Priority); + // Starts recording the current channel into the given file, with + // the given ca and priority. // In order to be able to record longer movies, // a numerical suffix will be appended to the file name. The inital // value of that suffix will be larger than any existing file under diff --git a/menu.c b/menu.c index c9959a4f..92e715e2 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.46 2000/11/11 15:22:56 kls Exp $ + * $Id: menu.c 1.47 2000/11/12 13:03:35 kls Exp $ */ #include "menu.h" @@ -1817,7 +1817,7 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer) timer->SetRecording(true); Channels.SwitchTo(timer->channel, dvbApi); cRecording Recording(timer); - if (dvbApi->StartRecord(Recording.FileName())) + if (dvbApi->StartRecord(Recording.FileName(), Channels.GetByNumber(timer->channel)->ca, timer->priority)) Recording.WriteSummary(); Interface->DisplayRecording(dvbApi->Index(), true); } @@ -1863,8 +1863,9 @@ bool cRecordControls::Start(cTimer *Timer) cChannel *channel = Channels.GetByNumber(ch); if (channel) { - cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca); + cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca, Timer ? Timer->priority : DEFAULTPRIORITY); if (dvbApi) { + Stop(dvbApi); for (int i = 0; i < MAXDVBAPI; i++) { if (!RecordControls[i]) { RecordControls[i] = new cRecordControl(dvbApi, Timer); @@ -1891,6 +1892,18 @@ void cRecordControls::Stop(const char *InstantId) } } +void cRecordControls::Stop(cDvbApi *DvbApi) +{ + for (int i = 0; i < MAXDVBAPI; i++) { + if (RecordControls[i]) { + if (RecordControls[i]->Uses(DvbApi)) { + isyslog(LOG_INFO, "stopping recording on DVB device %d due to higher priority", DvbApi->Index() + 1); + RecordControls[i]->Stop(); + } + } + } +} + const char *cRecordControls::GetInstantId(const char *LastInstantId) { for (int i = 0; i < MAXDVBAPI; i++) { diff --git a/menu.h b/menu.h index d979069e..8153f5d7 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.13 2000/11/01 14:03:09 kls Exp $ + * $Id: menu.h 1.14 2000/11/12 12:33:00 kls Exp $ */ #ifndef _MENU_H @@ -59,6 +59,7 @@ public: cRecordControl(cDvbApi *DvbApi, cTimer *Timer = NULL); virtual ~cRecordControl(); bool Process(void); + bool Uses(cDvbApi *DvbApi) { return DvbApi == dvbApi; } void Stop(bool KeepInstant = false); bool IsInstant(void) { return instantId; } const char *InstantId(void) { return instantId; } @@ -70,6 +71,7 @@ private: public: static bool Start(cTimer *Timer = NULL); static void Stop(const char *InstantId); + static void Stop(cDvbApi *DvbApi); static const char *GetInstantId(const char *LastInstantId); static void Process(void); };