diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/config.c vdr-1.4.1-lnb/config.c --- vdr-1.4.1/config.c 2006-08-23 19:34:19.000000000 +0300 +++ vdr-1.4.1-lnb/config.c 2006-08-23 19:34:54.000000000 +0300 @@ -281,6 +281,12 @@ cSetup::cSetup(void) ShowRecLength = 0; ShowProgressBar = 0; MenuCmdPosition = 0; + +//ML + VerboseLNBlog = 0; + for (int i = 0; i < MAXDEVICES; i++) CardUsesLNBnr[i] = i + 1; +//ML-Ende + } cSetup& cSetup::operator= (const cSetup &s) @@ -449,7 +455,23 @@ bool cSetup::Parse(const char *Name, con else if (!strcasecmp(Name, "ShowProgressBar")) ShowProgressBar = atoi(Value); else if (!strcasecmp(Name, "MenuCmdPosition")) MenuCmdPosition = atoi(Value); else - return false; + +//ML + if (!strcasecmp(Name, "VerboseLNBlog")) VerboseLNBlog = atoi(Value); + else { + char tmp[20]; + bool result = false; + for (int i = 1; i <= MAXDEVICES; i++) { + sprintf(tmp, "Card%dusesLNBnr", i); + if (!strcasecmp(Name, tmp)) { + CardUsesLNBnr[i - 1] = atoi(Value); + result = true; + } + } + return result; + } +//ML-Ende + return true; } @@ -523,6 +545,17 @@ bool cSetup::Save(void) Store("ShowProgressBar", ShowProgressBar); Store("MenuCmdPosition", MenuCmdPosition); +//ML + Store("VerboseLNBlog", VerboseLNBlog); + char tmp[20]; + if (cDevice::NumDevices() > 1) { + for (int i = 1; i <= cDevice::NumDevices(); i++) { + sprintf(tmp, "Card%dusesLNBnr", i); + Store(tmp, CardUsesLNBnr[i - 1]); + } + } +//ML-Ende + Sort(); if (cConfig<cSetupLine>::Save()) { diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/config.h vdr-1.4.1-lnb/config.h --- vdr-1.4.1/config.h 2006-08-23 19:34:19.000000000 +0300 +++ vdr-1.4.1-lnb/config.h 2006-08-23 19:34:54.000000000 +0300 @@ -256,6 +256,15 @@ public: int InitialChannel; int InitialVolume; int ShowRecDate, ShowRecTime, ShowRecLength, ShowProgressBar, MenuCmdPosition; + +//ML + int VerboseLNBlog; + #define MAXDEVICES 16 // Since VDR 1.3.32 we can not #include "device.h" for MAXDEVICES anymore. + // With this workaround a warning will be shown during compilation if + // MAXDEVICES changes in device.h. + int CardUsesLNBnr[MAXDEVICES]; +//ML-Ende + int __EndData__; cSetup(void); cSetup& operator= (const cSetup &s); diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/device.c vdr-1.4.1-lnb/device.c --- vdr-1.4.1/device.c 2006-08-23 19:34:19.000000000 +0300 +++ vdr-1.4.1-lnb/device.c 2006-08-23 19:36:23.000000000 +0300 @@ -19,6 +19,10 @@ #include "status.h" #include "transfer.h" +//ML +#include "diseqc.h" +//ML-Ende + // --- cPesAssembler --------------------------------------------------------- class cPesAssembler { @@ -155,6 +159,12 @@ cDevice::cDevice(void) SetVideoFormat(Setup.VideoFormat); +//ML + LNBstate = -1; + LNBnr = Setup.CardUsesLNBnr[cardIndex]; + LNBsource = NULL; +//ML-Ende + mute = false; volume = Setup.CurrentVolume; @@ -214,6 +224,16 @@ void cDevice::SetUseDevice(int n) useDevice |= (1 << n); } +//ML +void cDevice::SetLNBnr(void) +{ + for (int i = 0; i < numDevices; i++) { + device[i]->LNBnr = Setup.CardUsesLNBnr[i]; + isyslog("LNB-sharing: setting device %d to use LNB %d", i, device[i]->LNBnr); + } +} +//ML-Ende + int cDevice::NextCardIndex(int n) { if (n > 0) { @@ -273,6 +293,98 @@ cDevice *cDevice::ActualDevice(void) return d; } +//ML +cDevice *cDevice::GetBadDevice(const cChannel *Channel) +{ + if(!cSource::IsSat(Channel->Source())) return NULL; + if (Setup.DiSEqC) { + cDiseqc *diseqc; + diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); + + for (int i = 0; i < numDevices; i++) { + if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBsource() != (int*) diseqc) { + if (Setup.VerboseLNBlog) { + isyslog("LNB %d: Device check for channel %d on device %d. LNB or DiSEq conflict with device %d", LNBnr, Channel->Number(), this->DeviceNumber(), i); + } + return device[i]; + } + } + if (Setup.VerboseLNBlog) { + isyslog("LNB %d: Device check for for channel %d on device %d. OK", LNBnr, Channel->Number(), this->DeviceNumber()); + } + } else { + char requiredState; + if (Channel->Frequency() >= Setup.LnbSLOF) { + requiredState = 1 ; + } else { + requiredState = 0; + } + if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') requiredState += 2; + + for (int i = 0; i < numDevices; i++) { + if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBconf() != requiredState) { + if (Setup.VerboseLNBlog) { + isyslog("LNB %d: Device check for channel %d, LNBstate %d on device %d, current LNBstate %d. Conflict with device %d, LNBstate %d", LNBnr, Channel->Number(), requiredState, this->DeviceNumber(), LNBstate, i, device[i]->GetLNBconf()); + } + return device[i]; + } + } + if (Setup.VerboseLNBlog) { + isyslog("LNB %d: Device check for channel %d, LNBstate %d on device %d, current LNBstate %d. No other devices affected", LNBnr, Channel->Number(), requiredState, this->DeviceNumber(), LNBstate); + } + } + return NULL; +} + +int cDevice::GetMaxBadPriority(const cChannel *Channel) +{ + if(!cSource::IsSat(Channel->Source())) return -2; + bool PrimaryIsBad = false; + int maxBadPriority = -2; + if (Setup.DiSEqC) { + cDiseqc *diseqc; + diseqc = Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); + + for (int i = 0; i < numDevices; i++) { + if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBsource() != (int*) diseqc) { + if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) { + maxBadPriority = device[i]->Priority(); + } + if (device[i]->IsPrimaryDevice()) { + PrimaryIsBad = true; + } + } + } + } else { + char requiredState; + if (Channel->Frequency() >= Setup.LnbSLOF) { + requiredState = 1 ; + } else { + requiredState = 0; + } + if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') requiredState += 2; + + for (int i = 0; i < numDevices; i++) { + if (this != device[i] && device[i]->GetLNBnr() == LNBnr && device[i]->GetLNBconf() != requiredState) { + if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) { + maxBadPriority = device[i]->Priority(); + } + if (device[i]->IsPrimaryDevice()) { + PrimaryIsBad = true; + } + } + } + } + if (PrimaryIsBad && maxBadPriority == -2) { + maxBadPriority = -1; + } + if (Setup.VerboseLNBlog) { + isyslog("LNB %d: Request for channel %d on device %d. MaxBadPriority is %d", LNBnr, Channel->Number(), this->DeviceNumber(), maxBadPriority); + } + return maxBadPriority; +} +//ML-Ende + cDevice *cDevice::GetDevice(int Index) { return (0 <= Index && Index < numDevices) ? device[Index] : NULL; @@ -282,6 +394,12 @@ cDevice *cDevice::GetDevice(const cChann { cDevice *d = NULL; uint Impact = 0xFFFFFFFF; // we're looking for a device with the least impact + +//ML + int badPriority; + uint imp2; +//ML-Ende + for (int i = 0; i < numDevices; i++) { bool ndr; if (device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basicly able to do the job @@ -299,7 +417,30 @@ cDevice *cDevice::GetDevice(const cChann imp <<= 8; imp |= min(max(device[i]->ProvidesCa(Channel), 0), 0xFF); // use the device that provides the lowest number of conditional access methods imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards - if (imp < Impact) { + + //ML + badPriority = device[i]->GetMaxBadPriority(Channel); + if (badPriority >= Priority || (badPriority == -1 && Priority < Setup.PrimaryLimit)) { + // channel is not available for the requested prioity + imp = 0xFFFFFFFF; + } else { + switch (badPriority) { + case -2: // not affected by LNB-sharing + imp2 = 0; + break; + case -1: // the primary device would need a channel switch + imp += 1 << 17; + imp2 = 0xFFFFFFFF | 1 << 17; + break; + default: // a device receiving with lower priority would need to be stopped + imp += badPriority << 8; + imp2 = 0xFFFFFFFF | badPriority << 8; + break; + } + } + if (imp < Impact && imp2 < Impact) { + //ML-Ende + // This device has less impact than any previous one, so we take it. Impact = imp; d = device[i]; @@ -534,7 +675,11 @@ bool cDevice::ProvidesTransponder(const bool cDevice::ProvidesTransponderExclusively(const cChannel *Channel) const { for (int i = 0; i < numDevices; i++) { - if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel)) + +//ML + if (device[i] && device[i] != this && device[i]->ProvidesTransponder(Channel) && device[i]->GetLNBnr() != LNBnr) +//ML-Ende + return false; } return true; @@ -557,6 +702,26 @@ bool cDevice::MaySwitchTransponder(void) bool cDevice::SwitchChannel(const cChannel *Channel, bool LiveView) { + +//ML + cDevice *tmpDevice; + if (this->GetMaxBadPriority(Channel) >= 0) { + Skins.Message(mtInfo, tr("Channel locked by LNB!")); + return false; + } + while ((tmpDevice = GetBadDevice(Channel)) != NULL) { + if (tmpDevice->IsPrimaryDevice() && LiveView) + tmpDevice->SwitchChannelForced(Channel, true); + else + tmpDevice->SwitchChannelForced(Channel, false); + } + return SwitchChannelForced(Channel, LiveView); +} + +bool cDevice::SwitchChannelForced(const cChannel *Channel, bool LiveView) +//ML-Ende + +{ if (LiveView) isyslog("switching to channel %d", Channel->Number()); for (int i = 3; i--;) { @@ -582,11 +747,14 @@ bool cDevice::SwitchChannel(int Directio int first = n; cChannel *channel; while ((channel = Channels.GetByNumber(n, Direction)) != NULL) { - // try only channels which are currently available - if (PrimaryDevice()->ProvidesChannel(channel, Setup.PrimaryLimit) || PrimaryDevice()->CanReplay() && GetDevice(channel, 0)) - break; - n = channel->Number() + Direction; - } + // try only channels which are currently available + +//ML + if (PrimaryDevice()->GetMaxBadPriority(channel) < 0 && (PrimaryDevice()->ProvidesChannel(channel, Setup.PrimaryLimit) || PrimaryDevice()->CanReplay() && GetDevice(channel, 0))) +//ML-Ende + + n = channel->Number() + Direction; + } if (channel) { int d = n - first; if (abs(d) == 1) @@ -618,12 +786,40 @@ eSetChannelResult cDevice::SetChannel(co eSetChannelResult Result = scrOk; +//ML + char requiredState; + if (Channel->Frequency() >= Setup.LnbSLOF) { + requiredState = 1; + } else { + requiredState = 0; + } + if (Channel->Polarization() == 'v' || Channel->Polarization() == 'V') requiredState += 2; + if (Setup.VerboseLNBlog) { + isyslog("LNB %d: Switching device %d to channel %d", LNBnr, this->DeviceNumber(), Channel->Number()); + } +//ML-Ende + // If this DVB card can't receive this channel, let's see if we can // use the card that actually can receive it and transfer data from there: if (NeedsTransferMode) { cDevice *CaDevice = GetDevice(Channel, 0, &NeedsDetachReceivers); if (CaDevice && CanReplay()) { + +//ML + if (CaDevice->GetLNBnr() == LNBnr) { + if (LNBstate != requiredState || (Setup.DiSEqC && LNBsource != (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization())) ) { + if (IsPrimaryDevice()) { + SetChannelDevice(Channel, true); + } else { + SetChannelDevice(Channel, false); + } + LNBstate = requiredState; + LNBsource = (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); + } + } +//ML-Ende + 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 (NeedsDetachReceivers) @@ -644,6 +840,12 @@ eSetChannelResult cDevice::SetChannel(co sectionHandler->SetStatus(false); sectionHandler->SetChannel(NULL); } + +//ML + LNBstate = requiredState; + LNBsource = (int*) Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()); +//ML-Ende + // Tell the ciHandler about the channel switch and add all PIDs of this // channel to it, for possible later decryption: if (ciHandler) { diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/device.c.rej vdr-1.4.1-lnb/device.c.rej --- vdr-1.4.1/device.c.rej 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.4.1-lnb/device.c.rej 2006-08-23 19:34:54.000000000 +0300 @@ -0,0 +1,40 @@ +*************** +*** 293,299 **** + imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards + imp <<= 8; imp |= min(max(device[i]->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) + imp <<= 8; imp |= min(max(device[i]->ProvidesCa(Channel), 0), 0xFF); // use the device that provides the lowest number of conditional access methods +- if (imp < Impact) { + // This device has less impact than any previous one, so we take it. + Impact = imp; + d = device[i]; +--- 411,440 ---- + imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards + imp <<= 8; imp |= min(max(device[i]->Priority() + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used) + imp <<= 8; imp |= min(max(device[i]->ProvidesCa(Channel), 0), 0xFF); // use the device that provides the lowest number of conditional access methods ++ ++ //ML ++ badPriority = device[i]->GetMaxBadPriority(Channel); ++ if (badPriority >= Priority || (badPriority == -1 && Priority < Setup.PrimaryLimit)) { ++ // channel is not available for the requested prioity ++ imp = 0xFFFFFFFF; ++ } else { ++ switch (badPriority) { ++ case -2: // not affected by LNB-sharing ++ imp2 = 0; ++ break; ++ case -1: // the primary device would need a channel switch ++ imp += 1 << 17; ++ imp2 = 0xFFFFFFFF | 1 << 17; ++ break; ++ default: // a device receiving with lower priority would need to be stopped ++ imp += badPriority << 8; ++ imp2 = 0xFFFFFFFF | badPriority << 8; ++ break; ++ } ++ } ++ if (imp < Impact && imp2 < Impact) { ++ //ML-Ende ++ + // This device has less impact than any previous one, so we take it. + Impact = imp; + d = device[i]; diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/device.h vdr-1.4.1-lnb/device.h --- vdr-1.4.1/device.h 2006-08-23 19:34:19.000000000 +0300 +++ vdr-1.4.1-lnb/device.h 2006-08-23 19:34:54.000000000 +0300 @@ -134,6 +134,33 @@ public: ///< live viewing. ///< See ProvidesChannel() for more information on how ///< priorities are handled, and the meaning of NeedsDetachReceivers. + +//ML +private: + char LNBstate; // Current frequency band and polarization of the DVB-tuner +// cDiseqc *LNBsource; // can not #include "diseqc.h". A workaround follows: + int *LNBsource; // [DiSEqC] DiSEqC-Source + int LNBnr; // Number of LNB used +public: + char GetLNBconf(void) { return LNBstate; } + int *GetLNBsource(void) { return LNBsource; } + int GetLNBnr(void) { return LNBnr; } + static void SetLNBnr(void); + cDevice *GetBadDevice(const cChannel *Channel); + ///< Returns NULL if there is no device which uses the same LNB or if + ///< all of those devices are tuned to the same frequency band and + ///< polarization as of the requested channel. + ///< Otherwise returns the first device found. + int GetMaxBadPriority(const cChannel *Channel); + ///< Returns the highest priority of all receiving devices which use + ///< the same LNB and are tuned to a different frequency band or + ///< polarization as of the requested channel. + ///< Returns -1 if there are no such devices, but the primary device + ///< would be affected by switching to the requested channel. + ///< Returns -2 if there are no such devices and the primary device + ///< would not be affected by switching to the requested channel. +//ML-Ende + static void Shutdown(void); ///< Closes down all devices. ///< Must be called at the end of the program. @@ -227,6 +254,13 @@ public: bool SwitchChannel(const cChannel *Channel, bool LiveView); ///< Switches the device to the given Channel, initiating transfer mode ///< if necessary. + +//ML + bool SwitchChannelForced(const cChannel *Channel, bool LiveView); + ///< Switches the device to the given channel, initiating transfer mode + ///< if necessary. Forces the switch without taking care of the LNB configuration. +//ML-Ende + static bool SwitchChannel(int Direction); ///< Switches the primary device to the next available channel in the given ///< Direction (only the sign of Direction is evaluated, positive values diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/eitscan.c vdr-1.4.1-lnb/eitscan.c --- vdr-1.4.1/eitscan.c 2006-01-07 16:10:17.000000000 +0200 +++ vdr-1.4.1-lnb/eitscan.c 2006-08-23 19:34:54.000000000 +0300 @@ -151,9 +151,11 @@ void cEITScanner::Process(void) if (Device->ProvidesTransponder(Channel)) { if (!Device->Receiving()) { bool MaySwitchTransponder = Device->MaySwitchTransponder(); - if (MaySwitchTransponder || Device->ProvidesTransponderExclusively(Channel) && now - lastActivity > Setup.EPGScanTimeout * 3600) { +//ML + if (MaySwitchTransponder && Device->GetMaxBadPriority(Channel) == -2 || Device->ProvidesTransponderExclusively(Channel) && Device->GetMaxBadPriority(Channel) <= -1 && now - lastActivity > Setup.EPGScanTimeout * 3600) { if (!MaySwitchTransponder) { - if (Device == cDevice::ActualDevice() && !currentChannel) { + if ((Device == cDevice::ActualDevice() || Device->GetMaxBadPriority(Channel) == -1) && !currentChannel) { +//ML-Ende cDevice::PrimaryDevice()->StopReplay(); // stop transfer mode currentChannel = Device->CurrentChannel(); Skins.Message(mtInfo, tr("Starting EPG scan")); diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/i18n.c vdr-1.4.1-lnb/i18n.c --- vdr-1.4.1/i18n.c 2006-08-23 19:34:19.000000000 +0300 +++ vdr-1.4.1-lnb/i18n.c 2006-08-23 19:34:54.000000000 +0300 @@ -6390,6 +6390,76 @@ const tI18nPhrase Phrases[] = { "",//TODO "",//TODO }, + +//ML + { "Channel locked by LNB!", + "Kanal durch LNB gesperrt!", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "Chaîne interdite par la LNB", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, + { "Setup.LNB$DVB device %d uses LNB No.", + "DVB-Empfänger %d nutzt LNB Nr.", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "La carte DVB %d utilise la LNB No.", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, + { "Setup.LNB$Log LNB usage", + "LNB-Nutzung protokollieren", + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + "",// TODO + }, +//ML + { NULL } }; diff -Nurp -x '*.orig' -x '*.reg' -x '*~' vdr-1.4.1/menu.c vdr-1.4.1-lnb/menu.c --- vdr-1.4.1/menu.c 2006-08-23 19:34:19.000000000 +0300 +++ vdr-1.4.1-lnb/menu.c 2006-08-23 19:34:54.000000000 +0300 @@ -2616,6 +2616,23 @@ void cMenuSetupLNB::Setup(void) Clear(); +//ML + int numSatDevices = 0; + for (int i = 0; i < cDevice::NumDevices(); i++) { + if (cDevice::GetDevice(i)->ProvidesSource(cSource::stSat)) numSatDevices++; + } + if (numSatDevices > 1) { + char tmp[30]; + for (int i = 1; i <= cDevice::NumDevices(); i++) { + if (cDevice::GetDevice(i - 1)->ProvidesSource(cSource::stSat)) { + sprintf( tmp, tr("Setup.LNB$DVB device %d uses LNB No."), i); + Add(new cMenuEditIntItem( tmp, &data.CardUsesLNBnr[i - 1], 1, numSatDevices )); + } + } + } + Add(new cMenuEditBoolItem(tr("Setup.LNB$Log LNB usage"), &data.VerboseLNBlog)); +//ML-Ende + Add(new cMenuEditBoolItem(tr("Setup.LNB$Use DiSEqC"), &data.DiSEqC)); if (!data.DiSEqC) { Add(new cMenuEditIntItem( tr("Setup.LNB$SLOF (MHz)"), &data.LnbSLOF)); @@ -2632,6 +2649,10 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys int oldDiSEqC = data.DiSEqC; eOSState state = cMenuSetupBase::ProcessKey(Key); +//ML + if (Key == kOk) cDevice::SetLNBnr(); +//ML-Ende + if (Key != kNone && data.DiSEqC != oldDiSEqC) Setup(); return state; @@ -3315,7 +3336,10 @@ cChannel *cDisplayChannel::NextAvailable if (Direction) { while (Channel) { Channel = Direction > 0 ? Channels.Next(Channel) : Channels.Prev(Channel); - if (Channel && !Channel->GroupSep() && (cDevice::PrimaryDevice()->ProvidesChannel(Channel, Setup.PrimaryLimit) || cDevice::GetDevice(Channel, 0))) + +//ML + if (Channel && !Channel->GroupSep() && ((cDevice::PrimaryDevice()->ProvidesChannel(Channel, Setup.PrimaryLimit) && cDevice::PrimaryDevice()->GetMaxBadPriority(Channel) < 0) || cDevice::GetDevice(Channel, 0) ) ) +//ML-Ende return Channel; } } @@ -3841,6 +3865,21 @@ bool cRecordControls::Start(cTimer *Time int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority; cDevice *device = cDevice::GetDevice(channel, Priority, &NeedsDetachReceivers); if (device) { + +//ML + cDevice *tmpDevice; + while ((tmpDevice = device->GetBadDevice(channel))) { + if (tmpDevice->Replaying() == false) { + Stop(tmpDevice); + if (tmpDevice->IsPrimaryDevice() ) + tmpDevice->SwitchChannelForced(channel, true); + else + tmpDevice->SwitchChannelForced(channel, false); + } else + tmpDevice->SwitchChannelForced(channel, false); + } +//ML-Ende + if (NeedsDetachReceivers) { Stop(device); if (device == cTransferControl::ReceiverDevice())