Fixed switching devices to the transponders of VPS recordings in case there are only bonded devices

This commit is contained in:
Klaus Schmidinger 2012-03-06 12:32:38 +01:00
parent a57acf570d
commit 61e420bdf6
4 changed files with 44 additions and 45 deletions

View File

@ -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 which was made in version 1.1.10, so please report if this has any unwanted
side effects. 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). - 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 - 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. - 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 - Improved displaying signal strength and quality in the ST:TNG skin's channel
display. 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".

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: 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" #include "device.h"
@ -68,7 +68,6 @@ int cDevice::nextCardIndex = 0;
int cDevice::currentChannel = 1; int cDevice::currentChannel = 1;
cDevice *cDevice::device[MAXDEVICES] = { NULL }; cDevice *cDevice::device[MAXDEVICES] = { NULL };
cDevice *cDevice::primaryDevice = NULL; cDevice *cDevice::primaryDevice = NULL;
cDevice *cDevice::avoidDevice = NULL;
cList<cDeviceHook> cDevice::deviceHooks; cList<cDeviceHook> cDevice::deviceHooks;
cDevice::cDevice(void) 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 *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: // Collect the current priorities of all CAM slots that can decrypt the channel:
int NumCamSlots = CamSlots.Count(); int NumCamSlots = CamSlots.Count();
int SlotPriority[NumCamSlots]; int SlotPriority[NumCamSlots];
@ -259,8 +256,6 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY) if (NumUsableSlots && SlotPriority[j] > MAXPRIORITY)
continue; // there is no CAM available in this slot continue; // there is no CAM available in this slot
for (int i = 0; i < numDevices; i++) { 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) if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->CardIndex() + 1)
continue; // a specific card was requested, but not this one continue; // a specific card was requested, but not this one
if (NumUsableSlots && !CamSlots.Get(j)->Assign(device[i], true)) 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; 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) bool cDevice::HasCi(void)
{ {
return false; return false;

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: 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 #ifndef __DEVICE_H
@ -109,7 +109,6 @@ private:
static int useDevice; static int useDevice;
static cDevice *device[MAXDEVICES]; static cDevice *device[MAXDEVICES];
static cDevice *primaryDevice; static cDevice *primaryDevice;
static cDevice *avoidDevice;
public: public:
static int NumDevices(void) { return numDevices; } static int NumDevices(void) { return numDevices; }
///< Returns the total number of devices. ///< Returns the total number of devices.
@ -158,9 +157,11 @@ public:
///< in order to just determine whether a device is available for the given ///< in order to just determine whether a device is available for the given
///< Channel. ///< Channel.
///< See also ProvidesChannel(). ///< See also ProvidesChannel().
static void SetAvoidDevice(cDevice *Device) { avoidDevice = Device; } static cDevice *GetDeviceForTransponder(const cChannel *Channel, int Priority);
///< Sets the given Device to be temporarily avoided in the next call to ///< Returns a device that is not currently "occupied" and can be tuned to
///< GetDevice(const cChannel, int, bool). ///< 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); static void Shutdown(void);
///< Closes down all devices. ///< Closes down all devices.
///< Must be called at the end of the program. ///< Must be called at the end of the program.

46
vdr.c
View File

@ -22,7 +22,7 @@
* *
* The project's page is at http://www.tvdr.de * 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 <getopt.h> #include <getopt.h>
@ -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 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()); cChannel *Channel = Channels.GetByNumber(cDevice::CurrentChannel());
if (Channel && (Channel->Vpid() || Channel->Apid(0))) { if (Channel && (Channel->Vpid() || Channel->Apid(0))) {
if (!Channels.SwitchTo(cDevice::CurrentChannel()) // try to switch to the original channel... if (cDevice::GetDeviceForTransponder(Channel, LIVEPRIORITY) && Channels.SwitchTo(Channel->Number())) // try to switch to the original channel...
&& !(LastTimerChannel > 0 && Channels.SwitchTo(LastTimerChannel))) // ...or the one used by the last timer...
; ;
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 lastTime = Now; // don't do this too often
LastTimerChannel = -1; LastTimerChannel = -1;
@ -878,31 +882,12 @@ int main(int argc, char *argv[])
} }
if (NeedsTransponder || InVpsMargin) { if (NeedsTransponder || InVpsMargin) {
// Find a device that provides the required transponder: // Find a device that provides the required transponder:
cDevice *Device = NULL; cDevice *Device = cDevice::GetDeviceForTransponder(Timer->Channel(), MINPRIORITY);
bool DeviceAvailable = false; if (!Device && InVpsMargin)
for (int i = 0; i < cDevice::NumDevices(); i++) { Device = cDevice::GetDeviceForTransponder(Timer->Channel(), LIVEPRIORITY);
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
}
// Switch the device to the transponder: // Switch the device to the transponder:
if (Device) { if (Device) {
bool HadProgramme = cDevice::PrimaryDevice()->HasProgramme();
if (!Device->IsTunedToTransponder(Timer->Channel())) { if (!Device->IsTunedToTransponder(Timer->Channel())) {
if (Device == cDevice::ActualDevice() && !Device->IsPrimaryDevice()) if (Device == cDevice::ActualDevice() && !Device->IsPrimaryDevice())
cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode
@ -910,13 +895,8 @@ int main(int argc, char *argv[])
if (Device->SwitchChannel(Timer->Channel(), false)) if (Device->SwitchChannel(Timer->Channel(), false))
Device->SetOccupied(TIMERDEVICETIMEOUT); Device->SetOccupied(TIMERDEVICETIMEOUT);
} }
if (cDevice::PrimaryDevice()->HasDecoder() && !cDevice::PrimaryDevice()->HasProgramme()) { if (cDevice::PrimaryDevice()->HasDecoder() && HadProgramme && !cDevice::PrimaryDevice()->HasProgramme())
// the previous SwitchChannel() has switched away the current live channel Skins.Message(mtInfo, tr("Upcoming recording!")); // 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!"));
}
} }
} }
} }