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

Using timer priority to interrupt lower priority timer recording

This commit is contained in:
Klaus Schmidinger 2000-11-12 14:06:53 +01:00
parent 54a2e99c7b
commit 5b65773ec8
8 changed files with 77 additions and 28 deletions

View File

@ -266,7 +266,7 @@ Video Disk Recorder Revision History
are programmed via the "Schedules" menu) are now replaced by suitable are programmed via the "Schedules" menu) are now replaced by suitable
substitutes. 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. - 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 - 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 - There can now be a configuration file named 'commands.conf' that defines
commands that can be executed through the "Main" menu's "Commands" option commands that can be executed through the "Main" menu's "Commands" option
(see FORMATS for details on how to define these commands). (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).

4
MANUAL
View File

@ -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 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 recording needs more space, an existing recording with the lowest
Priority (and which has exceeded its guaranteed Lifetime) will be 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 Lifetime: The number of days (0..99) a recording made through this timer is
guaranteed to remain on disk before it is automatically removed guaranteed to remain on disk before it is automatically removed
to free up space for a new recording. Note that setting this to free up space for a new recording. Note that setting this

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "config.h"
@ -294,8 +294,8 @@ cTimer::cTimer(bool Instant)
if (stop >= 2400) if (stop >= 2400)
stop -= 2400; stop -= 2400;
//TODO VPS??? //TODO VPS???
priority = 99; priority = DEFAULTPRIORITY;
lifetime = 99; lifetime = DEFAULTLIFETIME;
*file = 0; *file = 0;
summary = NULL; summary = NULL;
if (Instant && ch) if (Instant && ch)
@ -319,8 +319,8 @@ cTimer::cTimer(const cEventInfo *EventInfo)
stop = time->tm_hour * 100 + time->tm_min; stop = time->tm_hour * 100 + time->tm_min;
if (stop >= 2400) if (stop >= 2400)
stop -= 2400; stop -= 2400;
priority = 99; priority = DEFAULTPRIORITY;
lifetime = 99; lifetime = DEFAULTLIFETIME;
*file = 0; *file = 0;
const char *Title = EventInfo->GetTitle(); const char *Title = EventInfo->GetTitle();
if (!isempty(Title)) if (!isempty(Title))

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __CONFIG_H
@ -95,6 +95,9 @@ public:
bool Switch(cDvbApi *DvbApi = NULL); bool Switch(cDvbApi *DvbApi = NULL);
}; };
#define DEFAULTPRIORITY 99
#define DEFAULTLIFETIME 99
class cTimer : public cListObject { class cTimer : public cListObject {
private: private:
time_t startTime, stopTime; time_t startTime, stopTime;

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "dvbapi.h"
@ -1091,6 +1091,8 @@ cDvbApi::cDvbApi(const char *VideoFileName, const char *VbiFileName)
pidRecord = pidReplay = 0; pidRecord = pidReplay = 0;
fromRecord = toRecord = -1; fromRecord = toRecord = -1;
fromReplay = toReplay = -1; fromReplay = toReplay = -1;
ca = 0;
priority = -1;
videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK); videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK);
if (videoDev >= 0) { if (videoDev >= 0) {
siProcessor = new cSIProcessor(VbiFileName); siProcessor = new cSIProcessor(VbiFileName);
@ -1161,22 +1163,25 @@ bool cDvbApi::SetPrimaryDvbApi(int n)
return false; return false;
} }
cDvbApi *cDvbApi::GetDvbApi(int Ca) cDvbApi *cDvbApi::GetDvbApi(int Ca, int Priority)
{ {
cDvbApi *d = NULL; cDvbApi *d = NULL;
Ca--; int index = Ca - 1;
for (int i = MAXDVBAPI; --i >= 0; ) { for (int i = MAXDVBAPI; --i >= 0; ) {
if (dvbApi[i] && !dvbApi[i]->Recording()) { if (dvbApi[i]) {
if (i == Ca) if (i == index) { // means we need exactly _this_ device
return dvbApi[i];
if (Ca < 0) {
d = dvbApi[i]; 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; break;
} }
} }
} }
return d; return (d && (!d->Recording() || d->Priority() < Priority || (!d->Ca() && Ca))) ? d : NULL;
} }
int cDvbApi::Index(void) int cDvbApi::Index(void)
@ -1746,7 +1751,7 @@ bool cDvbApi::Replaying(void)
return pidReplay; return pidReplay;
} }
bool cDvbApi::StartRecord(const char *FileName) bool cDvbApi::StartRecord(const char *FileName, int Ca, int Priority)
{ {
if (Recording()) { if (Recording()) {
esyslog(LOG_ERR, "ERROR: StartRecord() called while recording - ignored!"); esyslog(LOG_ERR, "ERROR: StartRecord() called while recording - ignored!");
@ -1843,6 +1848,9 @@ bool cDvbApi::StartRecord(const char *FileName)
fromRecord = fromRecordPipe[0]; fromRecord = fromRecordPipe[0];
toRecord = toRecordPipe[1]; toRecord = toRecordPipe[1];
ca = Ca;
priority = Priority;
return true; return true;
} }
return false; return false;
@ -1857,6 +1865,8 @@ void cDvbApi::StopRecord(void)
toRecord = fromRecord = -1; toRecord = fromRecord = -1;
KillProcess(pidRecord); KillProcess(pidRecord);
pidRecord = 0; pidRecord = 0;
ca = 0;
priority = -1;
SetReplayMode(VID_PLAY_RESET); //XXX SetReplayMode(VID_PLAY_RESET); //XXX
} }
} }

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __DVBAPI_H
@ -59,11 +59,15 @@ public:
static bool SetPrimaryDvbApi(int n); static bool SetPrimaryDvbApi(int n);
// Sets the primary DVB device to 'n' (which must be in the range // Sets the primary DVB device to 'n' (which must be in the range
// 1...NumDvbApis) and returns true if this was possible. // 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 // Selects a free DVB device, starting with the highest device number
// (but avoiding, if possible, the PrimaryDvbApi). // (but avoiding, if possible, the PrimaryDvbApi).
// If Ca is not 0, the device with the given number will be returned // If Ca is not 0, the device with the given number will be returned.
// if it is not currently recording. // 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); int Index(void);
// Returns the index of this DvbApi. // Returns the index of this DvbApi.
static bool Init(void); static bool Init(void);
@ -158,14 +162,23 @@ private:
pid_t pidRecord, pidReplay; pid_t pidRecord, pidReplay;
int fromRecord, toRecord; int fromRecord, toRecord;
int fromReplay, toReplay; int fromReplay, toReplay;
int ca;
int priority;
void SetReplayMode(int Mode); 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: public:
bool Recording(void); bool Recording(void);
// Returns true if we are currently recording. // Returns true if we are currently recording.
bool Replaying(void); bool Replaying(void);
// Returns true if we are currently replaying. // Returns true if we are currently replaying.
bool StartRecord(const char *FileName); bool StartRecord(const char *FileName, int Ca, int Priority);
// Starts recording the current channel into the given file. // Starts recording the current channel into the given file, with
// the given ca and priority.
// In order to be able to record longer movies, // In order to be able to record longer movies,
// a numerical suffix will be appended to the file name. The inital // a numerical suffix will be appended to the file name. The inital
// value of that suffix will be larger than any existing file under // value of that suffix will be larger than any existing file under

19
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "menu.h"
@ -1817,7 +1817,7 @@ cRecordControl::cRecordControl(cDvbApi *DvbApi, cTimer *Timer)
timer->SetRecording(true); timer->SetRecording(true);
Channels.SwitchTo(timer->channel, dvbApi); Channels.SwitchTo(timer->channel, dvbApi);
cRecording Recording(timer); cRecording Recording(timer);
if (dvbApi->StartRecord(Recording.FileName())) if (dvbApi->StartRecord(Recording.FileName(), Channels.GetByNumber(timer->channel)->ca, timer->priority))
Recording.WriteSummary(); Recording.WriteSummary();
Interface->DisplayRecording(dvbApi->Index(), true); Interface->DisplayRecording(dvbApi->Index(), true);
} }
@ -1863,8 +1863,9 @@ bool cRecordControls::Start(cTimer *Timer)
cChannel *channel = Channels.GetByNumber(ch); cChannel *channel = Channels.GetByNumber(ch);
if (channel) { if (channel) {
cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca); cDvbApi *dvbApi = cDvbApi::GetDvbApi(channel->ca, Timer ? Timer->priority : DEFAULTPRIORITY);
if (dvbApi) { if (dvbApi) {
Stop(dvbApi);
for (int i = 0; i < MAXDVBAPI; i++) { for (int i = 0; i < MAXDVBAPI; i++) {
if (!RecordControls[i]) { if (!RecordControls[i]) {
RecordControls[i] = new cRecordControl(dvbApi, Timer); 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) const char *cRecordControls::GetInstantId(const char *LastInstantId)
{ {
for (int i = 0; i < MAXDVBAPI; i++) { for (int i = 0; i < MAXDVBAPI; i++) {

4
menu.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef _MENU_H
@ -59,6 +59,7 @@ public:
cRecordControl(cDvbApi *DvbApi, cTimer *Timer = NULL); cRecordControl(cDvbApi *DvbApi, cTimer *Timer = NULL);
virtual ~cRecordControl(); virtual ~cRecordControl();
bool Process(void); bool Process(void);
bool Uses(cDvbApi *DvbApi) { return DvbApi == dvbApi; }
void Stop(bool KeepInstant = false); void Stop(bool KeepInstant = false);
bool IsInstant(void) { return instantId; } bool IsInstant(void) { return instantId; }
const char *InstantId(void) { return instantId; } const char *InstantId(void) { return instantId; }
@ -70,6 +71,7 @@ private:
public: public:
static bool Start(cTimer *Timer = NULL); static bool Start(cTimer *Timer = NULL);
static void Stop(const char *InstantId); static void Stop(const char *InstantId);
static void Stop(cDvbApi *DvbApi);
static const char *GetInstantId(const char *LastInstantId); static const char *GetInstantId(const char *LastInstantId);
static void Process(void); static void Process(void);
}; };