From a964269fe9080463cc87aba7b454b6b06b7f8677 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 16 Oct 2011 14:02:34 +0200 Subject: [PATCH] Implemented 'occupied' for devices --- HISTORY | 5 ++++- device.c | 18 ++++++++++++++++-- device.h | 15 ++++++++++++++- vdr.c | 15 ++++++--------- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/HISTORY b/HISTORY index 3dbe1926..85af028f 100644 --- a/HISTORY +++ b/HISTORY @@ -6743,7 +6743,7 @@ Video Disk Recorder Revision History extends over TS packet boundaries is now done by locally skipping TS packets in cFrameDetector. -2011-10-09: Version 1.7.22 +2011-10-16: Version 1.7.22 - Fixed scaling subtitles in case the primary device's GetVideoSize() function doesn't return actual values (thanks to Luca Olivetti). @@ -6762,3 +6762,6 @@ Video Disk Recorder Revision History to Rolf Ahrenberg). - Added cap_net_raw to the capabilities that are not dropped (thanks to Dominic Evans). - Fixed setting the start time of an edited recording (thanks to Christoph Haubrich). +- Temporarily switching free devices to transponders in order to have their running + status updated is now done by marking the devices as "occupied" for a certain + amount of time. diff --git a/device.c b/device.c index ba098d88..8664db9a 100644 --- a/device.c +++ b/device.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.c 2.42 2011/08/26 12:56:00 kls Exp $ + * $Id: device.c 2.43 2011/10/16 14:01:30 kls Exp $ */ #include "device.h" @@ -95,6 +95,8 @@ cDevice::cDevice(void) camSlot = NULL; startScrambleDetection = 0; + occupiedTimeout = 0; + player = NULL; isPlayingVideo = false; ClrAvailableTracks(); @@ -645,7 +647,7 @@ bool cDevice::IsTunedToTransponder(const cChannel *Channel) bool cDevice::MaySwitchTransponder(void) { - return !Receiving(true) && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid); + return time(NULL) > occupiedTimeout && !Receiving(true) && !(pidHandles[ptAudio].pid || pidHandles[ptVideo].pid || pidHandles[ptDolby].pid); } bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) @@ -786,6 +788,18 @@ void cDevice::ForceTransferMode(void) } } +int cDevice::Occupied(void) const +{ + int Seconds = occupiedTimeout - time(NULL); + return Seconds > 0 ? Seconds : 0; +} + +void cDevice::SetOccupied(int Seconds) +{ + if (Seconds >= 0) + occupiedTimeout = time(NULL) + min(Seconds, MAXOCCUPIEDTIMEOUT); +} + bool cDevice::SetChannelDevice(const cChannel *Channel, bool LiveView) { return false; diff --git a/device.h b/device.h index fd587a83..fc6214c0 100644 --- a/device.h +++ b/device.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: device.h 2.27 2011/08/26 12:52:29 kls Exp $ + * $Id: device.h 2.28 2011/10/16 13:27:23 kls Exp $ */ #ifndef __DEVICE_H @@ -30,6 +30,7 @@ #define MAXRECEIVERS 16 // the maximum number of receivers per device #define MAXVOLUME 255 #define VOLUMEDELTA 5 // used to increase/decrease the volume +#define MAXOCCUPIEDTIMEOUT 99 // max. time (in seconds) a device may be occupied enum eSetChannelResult { scrOk, scrNotAvailable, scrNoTransfer, scrFailed }; @@ -220,6 +221,8 @@ public: // Channel facilities +private: + time_t occupiedTimeout; protected: static int currentChannel; public: @@ -300,6 +303,16 @@ public: ///< channel number while replaying. void ForceTransferMode(void); ///< Forces the device into transfermode for the current channel. + int Occupied(void) const; + ///< Returns the number of seconds this device is still occupied for. + void SetOccupied(int Seconds); + ///< Sets the occupied timeout for this device to the given number of + ///< Seconds, This can be used to tune a device to a particular transponder + ///< and make sure it will stay there for a certain amount of time, for + ///< instance to collect EPG data. This function shall only be called + ///< after the device has been successfully tuned to the requested transponder. + ///< Seconds will be silently limited to MAXOCCUPIEDTIMEOUT. Values less than + ///< 0 will be silently ignored. virtual bool HasLock(int TimeoutMs = 0); ///< Returns true if the device has a lock on the requested transponder. ///< Default is true, a specific device implementation may return false diff --git a/vdr.c b/vdr.c index b546b2a4..284230cb 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.tvdr.de * - * $Id: vdr.c 2.25 2011/09/23 13:09:37 kls Exp $ + * $Id: vdr.c 2.26 2011/10/16 14:02:34 kls Exp $ */ #include @@ -860,7 +860,6 @@ int main(int argc, char *argv[]) static time_t LastTimerCheck = 0; if (Now - LastTimerCheck > TIMERCHECKDELTA) { // don't do this too often InhibitEpgScan = false; - static time_t DeviceUsed[MAXDEVICES] = { 0 }; for (cTimer *Timer = Timers.First(); Timer; Timer = Timers.Next(Timer)) { bool InVpsMargin = false; bool NeedsTransponder = false; @@ -900,19 +899,17 @@ int main(int argc, char *argv[]) Device = d; break; } - bool timeout = Now - DeviceUsed[d->DeviceNumber()] > TIMERDEVICETIMEOUT; // only check other devices if they have been left alone for a while if (d->MaySwitchTransponder()) { DeviceAvailable = true; // avoids using the actual device below - if (timeout) - Device = d; // only check other devices if they have been left alone for a while + Device = d; } - else if (timeout && !Device && InVpsMargin && !d->Receiving() && d->ProvidesTransponderExclusively(Timer->Channel())) + else if (!d->Occupied() && !Device && InVpsMargin && !d->Receiving() && d->ProvidesTransponderExclusively(Timer->Channel())) Device = d; // use this one only if no other with less impact can be found } } if (!Device && InVpsMargin && !DeviceAvailable) { cDevice *d = cDevice::ActualDevice(); - if (!d->Receiving() && d->ProvidesTransponder(Timer->Channel()) && Now - DeviceUsed[d->DeviceNumber()] > TIMERDEVICETIMEOUT) + if (!d->Receiving() && d->ProvidesTransponder(Timer->Channel()) && !d->Occupied()) Device = d; // use the actual device as a last resort } // Switch the device to the transponder: @@ -921,8 +918,8 @@ int main(int argc, char *argv[]) if (Device == cDevice::ActualDevice() && !Device->IsPrimaryDevice()) cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode dsyslog("switching device %d to channel %d", Device->DeviceNumber() + 1, Timer->Channel()->Number()); - Device->SwitchChannel(Timer->Channel(), false); - DeviceUsed[Device->DeviceNumber()] = Now; + if (Device->SwitchChannel(Timer->Channel(), false)) + Device->SetOccupied(TIMERDEVICETIMEOUT); } if (cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) { // the previous SwitchChannel() has switched away the current live channel