diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 789a39f5..4dcc7be9 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1566,6 +1566,8 @@ Patrick Fischer for reporting an error in the cFilter example in PLUGINS.html for making the static cControl functions thread safe for suggesting that the cTimer constructor should take an optional cChannel + for suggesting that any cReceivers still attached to a cDevice when that device + switches to a different transponder shall be automatically detached Ralf Müller for a patch that was used to implement cUnbufferedFile diff --git a/HISTORY b/HISTORY index ec7f4db3..4db9f066 100644 --- a/HISTORY +++ b/HISTORY @@ -4113,3 +4113,6 @@ Video Disk Recorder Revision History displayed will close the OSD. In order to assign this new key to an existing remote control setup, the remote.conf file needs to be deleted and VDR has to be restarted to go through the process of learning the remote control keys. +- Any cReceivers still attached to a cDevice when that device switches to a + different transponder are now automatically detached (suggested by Patrick + Fischer). diff --git a/device.c b/device.c index 5fad4d96..53320335 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 1.116 2006/01/06 12:56:44 kls Exp $ + * $Id: device.c 1.117 2006/01/06 13:50:00 kls Exp $ */ #include "device.h" @@ -604,10 +604,14 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) if (LiveView) StopReplay(); + // If this card is switched to an other transponder, any receivers still + // attached to it ineed to be automatically detached: + bool NeedsDetachReceivers = false; + // If this card can't receive this channel, we must not actually switch // the channel here, because that would irritate the driver when we // start replaying in Transfer Mode immediately after switching the channel: - bool NeedsTransferMode = (LiveView && IsPrimaryDevice() && !ProvidesChannel(Channel, Setup.PrimaryLimit)); + bool NeedsTransferMode = (LiveView && IsPrimaryDevice() && !ProvidesChannel(Channel, Setup.PrimaryLimit, &NeedsDetachReceivers)); eSetChannelResult Result = scrOk; @@ -615,11 +619,14 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) // use the card that actually can receive it and transfer data from there: if (NeedsTransferMode) { - cDevice *CaDevice = GetDevice(Channel, 0); + cDevice *CaDevice = GetDevice(Channel, 0, &NeedsDetachReceivers); if (CaDevice && CanReplay()) { cStatus::MsgChannelSwitch(this, 0); // only report status if we are actually going to switch the channel - if (CaDevice->SetChannel(Channel, false) == scrOk) // calling SetChannel() directly, not SwitchChannel()! + if (CaDevice->SetChannel(Channel, false) == scrOk) { // calling SetChannel() directly, not SwitchChannel()! + if (NeedsDetachReceivers) + CaDevice->DetachAllReceivers(); cControl::Launch(new cTransferControl(CaDevice, Channel->Vpid(), Channel->Apids(), Channel->Dpids(), Channel->Spids())); + } else Result = scrNoTransfer; } @@ -653,6 +660,8 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView) } #endif } + if (NeedsDetachReceivers) + DetachAllReceivers(); if (SetChannelDevice(Channel, LiveView)) { // Start section handling: if (sectionHandler) { @@ -1269,6 +1278,15 @@ void cDevice::DetachAll(int Pid) } } +void cDevice::DetachAllReceivers(void) +{ + cMutexLock MutexLock(&mutexReceiver); + for (int i = 0; i < MAXRECEIVERS; i++) { + if (receiver[i]) + Detach(receiver[i]); + } +} + // --- cTSBuffer ------------------------------------------------------------- cTSBuffer::cTSBuffer(int File, int Size, int CardIndex) diff --git a/device.h b/device.h index 88607319..327a707e 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 1.67 2005/12/29 14:51:59 kls Exp $ + * $Id: device.h 1.68 2006/01/06 13:20:25 kls Exp $ */ #ifndef __DEVICE_H @@ -520,6 +520,8 @@ public: ///< Detaches the given receiver from this device. void DetachAll(int Pid); ///< Detaches all receivers from this device for this pid. + void DetachAllReceivers(void); + ///< Detaches all receivers from this device. }; /// Derived cDevice classes that can receive channels will have to provide