From 61e420bdf6159af3c31023ae2230f6743cf6d8d3 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Tue, 6 Mar 2012 12:32:38 +0100 Subject: [PATCH] Fixed switching devices to the transponders of VPS recordings in case there are only bonded devices --- HISTORY | 5 ++++- device.c | 27 +++++++++++++++++++++------ device.h | 11 ++++++----- vdr.c | 46 +++++++++++++--------------------------------- 4 files changed, 44 insertions(+), 45 deletions(-) diff --git a/HISTORY b/HISTORY index b40ddcbd..ceb0b438 100644 --- a/HISTORY +++ b/HISTORY @@ -6960,7 +6960,7 @@ Video Disk Recorder Revision History which was made in version 1.1.10, so please report if this has any unwanted side effects. -2012-03-05: Version 1.7.26 +2012-03-06: Version 1.7.26 - Now checking for NULL in cOsd::AddPixmap() (suggested by Christoph Haubrich). - Fixed the German translation of "VDR will shut down in %s minutes" (thanks to @@ -6976,3 +6976,6 @@ Video Disk Recorder Revision History - Made the ST:TNG skin the default in case the user selected skin is not available. - Improved displaying signal strength and quality in the ST:TNG skin's channel display. +- Fixed switching devices to the transponders of VPS recordings in case there + are only bonded devices. The cDevice's "avoid device" mechanism has been replaced + by using "occupied". diff --git a/device.c b/device.c index 663f91ad..0452edc1 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.55 2012/03/03 11:43:05 kls Exp $ + * $Id: device.c 2.56 2012/03/06 12:32:38 kls Exp $ */ #include "device.h" @@ -68,7 +68,6 @@ int cDevice::nextCardIndex = 0; int cDevice::currentChannel = 1; cDevice *cDevice::device[MAXDEVICES] = { NULL }; cDevice *cDevice::primaryDevice = NULL; -cDevice *cDevice::avoidDevice = NULL; cList cDevice::deviceHooks; cDevice::cDevice(void) @@ -228,8 +227,6 @@ static int GetClippedNumProvidedSystems(int AvailableBits, cDevice *Device) cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView, bool Query) { - cDevice *AvoidDevice = avoidDevice; - avoidDevice = NULL; // Collect the current priorities of all CAM slots that can decrypt the channel: int NumCamSlots = CamSlots.Count(); int SlotPriority[NumCamSlots]; @@ -259,8 +256,6 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) continue; // there is no CAM available in this slot for (int i = 0; i < numDevices; i++) { - if (device[i] == AvoidDevice) - continue; // this device shall be temporarily avoided if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1) continue; // a specific card was requested, but not this one if (NumUsableSlots && !CamSlots.Get(j)->Assign(device[i], true)) @@ -319,6 +314,26 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView return d; } +cDevice *cDevice::GetDeviceForTransponder(const cChannel *Channel, int Priority) +{ + cDevice *Device = NULL; + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (cDevice *d = cDevice::GetDevice(i)) { + if (d->IsTunedToTransponder(Channel)) + return d; // if any device is tuned to the transponder, we're done + if (d->ProvidesTransponder(Channel)) { + if (d->MaySwitchTransponder(Channel)) + Device = d; // this device may switch to the transponder without disturbing any receiver or live view + else if (!d->Occupied()) { + if (d->Priority() < Priority && (!Device || d->Priority() < Device->Priority())) + Device = d; // use this one only if no other with less impact can be found + } + } + } + } + return Device; +} + bool cDevice::HasCi(void) { return false; diff --git a/device.h b/device.h index 23aea970..0d9ac3ac 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.36 2012/03/02 10:23:13 kls Exp $ + * $Id: device.h 2.37 2012/03/06 12:13:46 kls Exp $ */ #ifndef __DEVICE_H @@ -109,7 +109,6 @@ private: static int useDevice; static cDevice *device[MAXDEVICES]; static cDevice *primaryDevice; - static cDevice *avoidDevice; public: static int NumDevices(void) { return numDevices; } ///< Returns the total number of devices. @@ -158,9 +157,11 @@ public: ///< in order to just determine whether a device is available for the given ///< Channel. ///< See also ProvidesChannel(). - static void SetAvoidDevice(cDevice *Device) { avoidDevice = Device; } - ///< Sets the given Device to be temporarily avoided in the next call to - ///< GetDevice(const cChannel, int, bool). + static cDevice *GetDeviceForTransponder(const cChannel *Channel, int Priority); + ///< Returns a device that is not currently "occupied" and can be tuned to + ///< the transponder of the given Channel, without disturbing any receiver + ///< at priorities higher or equal to Priority. + ///< If no such device is currently available, NULL will be returned. static void Shutdown(void); ///< Closes down all devices. ///< Must be called at the end of the program. diff --git a/vdr.c b/vdr.c index 47bd1d9b..9715d885 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.31 2012/03/05 10:44:33 kls Exp $ + * $Id: vdr.c 2.32 2012/03/06 12:14:17 kls Exp $ */ #include @@ -762,9 +762,13 @@ int main(int argc, char *argv[]) if ((!Menu || CheckHasProgramme) && Now - lastTime > MINCHANNELWAIT) { // !Menu to avoid interfering with the CAM if a CAM menu is open cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel()); if (Channel && (Channel->Vpid() || Channel->Apid(0))) { - if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel... - && !(LastTimerChannel > 0 && Channels.SwitchTo(LastTimerChannel))) // ...or the one used by the last timer... + if (cDevice::GetDeviceForTransponder(Channel, LIVEPRIORITY) && Channels.SwitchTo(Channel->Number())) // try to switch to the original channel... ; + else if (LastTimerChannel > 0) { + Channel = Channels.GetByNumber(LastTimerChannel); + if (Channel && cDevice::GetDeviceForTransponder(Channel, LIVEPRIORITY) && Channels.SwitchTo(LastTimerChannel)) // ...or the one used by the last timer + ; + } } lastTime = Now; // don't do this too often LastTimerChannel = -1; @@ -878,31 +882,12 @@ int main(int argc, char *argv[]) } if (NeedsTransponder || InVpsMargin) { // Find a device that provides the required transponder: - cDevice *Device = NULL; - bool DeviceAvailable = false; - for (int i = 0; i < cDevice::NumDevices(); i++) { - cDevice *d = cDevice::GetDevice(i); - if (d && d->ProvidesTransponder(Timer->Channel())) { - if (d->IsTunedToTransponder(Timer->Channel())) { - // if any device is tuned to the transponder, we're done - Device = d; - break; - } - if (d->MaySwitchTransponder(Timer->Channel())) { - DeviceAvailable = true; // avoids using the actual device below - Device = d; - } - 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()) && !d->Occupied()) - Device = d; // use the actual device as a last resort - } + cDevice *Device = cDevice::GetDeviceForTransponder(Timer->Channel(), MINPRIORITY); + if (!Device && InVpsMargin) + Device = cDevice::GetDeviceForTransponder(Timer->Channel(), LIVEPRIORITY); // Switch the device to the transponder: if (Device) { + bool HadProgramme = cDevice::PrimaryDevice()->HasProgramme(); if (!Device->IsTunedToTransponder(Timer->Channel())) { if (Device == cDevice::ActualDevice() && !Device->IsPrimaryDevice()) cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode @@ -910,13 +895,8 @@ int main(int argc, char *argv[]) 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 - cDevice::SetAvoidDevice(Device); - if (!Channels.SwitchTo(cDevice::CurrentChannel())) // try to switch to the original channel on a different device... - Channels.SwitchTo(Timer->Channel()->Number()); // ...or avoid toggling between old channel and black screen - Skins.Message(mtInfo, tr("Upcoming recording!")); - } + if (cDevice::PrimaryDevice()->HasDecoder() && HadProgramme && !cDevice::PrimaryDevice()->HasProgramme()) + Skins.Message(mtInfo, tr("Upcoming recording!")); // the previous SwitchChannel() has switched away the current live channel } } }