summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Ehrnsperger <markus@vdr1.(none)>2011-01-23 22:20:57 +0100
committerMarkus Ehrnsperger <markus@vdr1.(none)>2011-01-23 22:20:57 +0100
commitac9d15a2a4e62971aee7932e55aa2d924f9b0261 (patch)
tree094246c234bce8f91e226d758f8437d62d095990
parent58db02442b375f5669416e6e744a8325ed363f99 (diff)
downloadvdr-patch-lnbsharing-ac9d15a2a4e62971aee7932e55aa2d924f9b0261.tar.gz
vdr-patch-lnbsharing-ac9d15a2a4e62971aee7932e55aa2d924f9b0261.tar.bz2
lnb-sharing 0.1.0lnb-sharing-0.1.0
-rw-r--r--HISTORY.LNBshare31
-rw-r--r--README.LNBshare22
-rw-r--r--config.c33
-rw-r--r--config.h10
-rw-r--r--device.c80
-rw-r--r--device.h34
-rw-r--r--dvbdevice.c77
-rw-r--r--dvbdevice.h20
-rw-r--r--eitscan.c6
-rw-r--r--menu.c21
-rw-r--r--po/de_DE.po10
-rw-r--r--po/fr_FR.po10
-rw-r--r--po/it_IT.po11
-rw-r--r--po/nl_NL.po11
-rw-r--r--po/ru_RU.po11
-rw-r--r--vdr.c14
16 files changed, 390 insertions, 11 deletions
diff --git a/HISTORY.LNBshare b/HISTORY.LNBshare
new file mode 100644
index 0000000..a0e539f
--- /dev/null
+++ b/HISTORY.LNBshare
@@ -0,0 +1,31 @@
+configurableLNBshare Revision History
+
+Version for VDR 1.4.3
+
+- configurableLNBshare-VDR_1.4.3.patch from Matthias Lötzke (http://lötzke.de/vdr.html)
+
+2010-04-10: Version for VDR 1.7.14
+
+- Created HISTORY.LNBshare
+- Created README.LNBshare
+- Fixed possible buffer overflow in cMenuSetupLNB::Setup(void)
+- Ignore all non-DVB-S devices when checking for possible conflicts.
+- Use the 'actual' device instead of the 'primary' device as device that is used as reciever for live viewing. This adds support for 'other' output devices than a FF card like xine. Based on a patch from CR7 at vdr-portal.de
+- Adept to VDR 1.7.14. Support the new diseqc feature introduced with VDR 1.7.13: 'Added device definitions to the diseqc.conf file format, so that certain satellite positions can be limited to a given list of devices'.
+
+2010-11-13:
+
+- Fix: Devices sharing same LNB don't switch channel on main channel switch (thanks to hivdr @ vdr-portal.de for reporting the bug and spockele @ vdr-portal.de and hopsi @ vdr-portal.de for testing the correction)
+- Fix: In LOG, device numbering is now as in VDR: Starting from 1, ...
+- Fix: Encoding of german umlaut in "DVB-Empfänger %d nutzt LNB Nr"
+
+2010-11-28:
+
+- Fix: Device numbering in message 'LNB or DiSEq conflict with device ...'.
+- Fix: Numbering of LNBs not using SAT
+
+2010-12-25: Version 0.1.0 for VDR version 1.7.16
+
+- Rename the patch to include patch version number (vdr-lnb-sharing-0.1.0-1.7.16.patch)
+- Write patch version number to log file (if logging is switched on).
+- Adept to VDR 1.7.16
diff --git a/README.LNBshare b/README.LNBshare
new file mode 100644
index 0000000..74c4856
--- /dev/null
+++ b/README.LNBshare
@@ -0,0 +1,22 @@
+Settings (OSD)
+In VDR, if you select Settings -> LNB and have two or more devices that can recieve SAT channels, you can set the 'LNB Nr.' for each of these devices. Note:
+- All devices with an identical 'LNB Nr.' share the same LNB
+- The patch assumes that a device has always the same number. If you have more than two devices, you must make sure to load the drivers in a given order to make sure that each of the listed devices belongs always to the same card. If during setup, for example, your first DVB-S card is device 2 and your second DVB-S card is device 4 (device 1 and 3 are, for example, DVB-T cards) you must make sure that after reboot these stay the same: your first DVB-S card is device 2 and your second DVB-S card is device 4.
+
+DISEQC Support:
+Diseqc is supported, including the feature added in VDR 1.7.13: Added device definitions to the diseqc.conf file format, so that certain satellite positions can be limited to a given list of devices
+Note: Please ensure in diseqc.conf that all devices sharing one LNB have exactly the same satellite positions. The system will not check this, but, otherwise, the patch will not work correctly. This is not a restriction: obviously, if two devices share the same LNB, they can also receive the same satellite positions.
+
+Primary limit (Setup.PrimaryLimit):
+See MANUAL for a description: 'This is mainly useful for recordings that should take place only when there is nothing else to do, but should never keep the user from viewing stuff on the primary interface'
+In unpatched VDR, this seems to work with FF cards. For other output devices (for example vdr-xine), it probably won't work.
+Not fully supported by LNB sharing: If the primary device shares an LNB with device2, device2 might start a recording with priority < Setup.PrimaryLimit and force the primary device to an other channel.
+
+TODO / Missing:
+Intelligent assigning of timers to devices.
+Example: If you have 3 DVB-S cards and 2 of them share the same LNB, you can, in principle, record 2 channels in 'high' band and one in 'low' band. But, with this patch, this is not guaranteed. The DVB-S card with an own LNB might record one of the channels in high band. So, one of the other channels will not be recorded.
+Note:
+- Such intelligent scheduling is generally missing in VDR and would be also useful for 'mixed' systems with DVB-S and DVB-T cards as well as systems in which not all DVB-S cards can receive the same satellites.
+- I don't plan to implement this feature. Any volunteers?
+
+Contact: You find me at http://www.vdr-portal.de , user MarkusE . Please create a new thread in Developer->Patches for any questions or bug reports
diff --git a/config.c b/config.c
index 73b11b1..c77d38b 100644
--- a/config.c
+++ b/config.c
@@ -399,6 +399,10 @@ cSetup::cSetup(void)
InitialVolume = -1;
ChannelsWrap = 0;
EmergencyExit = 1;
+//ML
+ VerboseLNBlog = 0;
+ for (int i = 0; i < MAXDEVICES; i++) CardUsesLnbNr[i] = i + 1;
+//ML-Ende
}
cSetup& cSetup::operator= (const cSetup &s)
@@ -591,7 +595,23 @@ bool cSetup::Parse(const char *Name, const char *Value)
else if (!strcasecmp(Name, "ChannelsWrap")) ChannelsWrap = atoi(Value);
else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = 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;
}
@@ -687,6 +707,17 @@ bool cSetup::Save(void)
Store("ChannelsWrap", ChannelsWrap);
Store("EmergencyExit", EmergencyExit);
+//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 --git a/config.h b/config.h
index 7c28d41..39498d2 100644
--- a/config.h
+++ b/config.h
@@ -291,6 +291,16 @@ public:
int InitialVolume;
int ChannelsWrap;
int EmergencyExit;
+
+//ML
+ #define LNB_SHARING_VERSION "0.1.0"
+ 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 --git a/device.c b/device.c
index 681049b..5d5f648 100644
--- a/device.c
+++ b/device.c
@@ -144,6 +144,15 @@ void cDevice::SetUseDevice(int n)
useDevice |= (1 << n);
}
+//ML
+void cDevice::SetLnbNr(void)
+{
+ for (int i = 0; i < numDevices; i++) {
+ device[i]->SetLnbNrFromSetup();
+ }
+}
+//ML-Ende
+
int cDevice::NextCardIndex(int n)
{
if (n > 0) {
@@ -283,10 +292,21 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving
imp <<= 4; imp |= GetClippedNumProvidedSystems(4, device[i]) - 1; // avoid cards which support multiple delivery systems
imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice(); // avoid the Transfer Mode receiver device
- 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)
+ // LNB - Sharing
+ int badPriority = device[i]->GetMaxBadPriority(Channel);
+ if (badPriority < 0 ) // a device receiving with lower priority would need to be stopped
+ {
+ 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)
+ } else {
+ imp <<= 8; imp |= min(max(max(device[i]->Priority(), badPriority) + MAXPRIORITY, 0), 0xFF); // use the device with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
+ }
+ // LNB - Sharing End
imp <<= 8; imp |= min(max((NumUsableSlots ? SlotPriority[j] : 0) + MAXPRIORITY, 0), 0xFF); // use the CAM slot with the lowest priority (+MAXPRIORITY to assure that values -99..99 can be used)
imp <<= 1; imp |= ndr; // avoid devices if we need to detach existing receivers
imp <<= 1; imp |= device[i]->IsPrimaryDevice(); // avoid the primary device
+ // LNB - Sharing
+ imp |= (badPriority == -1); // avoid cards where the actual device needs to be switched
+ // LNB - Sharing End
imp <<= 1; imp |= NumUsableSlots ? 0 : device[i]->HasCi(); // avoid cards with Common Interface for FTA channels
imp <<= 1; imp |= device[i]->HasDecoder(); // avoid full featured cards
imp <<= 1; imp |= NumUsableSlots ? !ChannelCamRelations.CamDecrypt(Channel->GetChannelID(), j + 1) : 0; // prefer CAMs that are known to decrypt this channel
@@ -602,7 +622,11 @@ bool cDevice::ProvidesTransponder(const cChannel *Channel) 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]->IsShareLnb(this) )
+//ML-Ende
+
return false;
}
return true;
@@ -684,6 +708,51 @@ bool cDevice::SwitchChannel(int Direction)
return result;
}
+// ML
+cDevice *cDevice::GetBadDevice(const cChannel *Channel)
+{
+ if(!cSource::IsSat(Channel->Source())) return NULL; // no conflict if the new channel is not on sat
+ if(!ProvidesSource(cSource::stSat)) return NULL; // no conflict if this device is not on sat
+ for (int i = 0; i < numDevices; i++) {
+ if (this != device[i] && device[i]->IsShareLnb(this) && device[i]->IsLnbConflict(Channel) ) {
+ // there is a conflict between device[i] and 'this' if we tune this to Channel
+ 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() + 1, i + 1);
+ }
+ return device[i];
+ }
+ }
+ if (Setup.VerboseLNBlog) {
+ isyslog("LNB %d: Device check for channel %d on device %d. OK", LnbNr(), Channel->Number(), this->DeviceNumber() + 1);
+ }
+ return NULL;
+}
+
+int cDevice::GetMaxBadPriority(const cChannel *Channel) const
+{
+ if(!cSource::IsSat(Channel->Source())) return -2; // no conflict if the new channel is not on sat
+ if(!ProvidesSource(cSource::stSat)) return -2; // no conflict if this device is not on sat
+
+ int maxBadPriority = -2;
+ for (int i = 0; i < numDevices; i++) {
+ if (this != device[i] && device[i]->IsShareLnb(this) && device[i]->IsLnbConflict(Channel) ) {
+ // there is a conflict between device[i] and 'this' if we tune this to Channel
+ if (Setup.VerboseLNBlog) {
+ isyslog("LNB %d: Conflict for device %d, priority of conflicting device: %d", LnbNr(), i + 1, device[i]->Priority());
+ }
+ if (device[i]->Receiving() && device[i]->Priority() > maxBadPriority) maxBadPriority = device[i]->Priority();
+ if (i == ActualDevice()->CardIndex() && maxBadPriority < -1 ) maxBadPriority = -1;
+ }
+ }
+
+ if (Setup.VerboseLNBlog) {
+ isyslog("LNB %d: Request for channel %d on device %d. MaxBadPriority is %d", LnbNr(), Channel->Number(), this->DeviceNumber() + 1, maxBadPriority);
+ }
+ return maxBadPriority;
+}
+// ML Ende
+
+
eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
{
if (LiveView) {
@@ -698,6 +767,13 @@ eSetChannelResult cDevice::SetChannel(const cChannel *Channel, bool LiveView)
eSetChannelResult Result = scrOk;
+//ML
+ if (Setup.VerboseLNBlog) {
+ isyslog("LNB %d: Switching device %d to channel %d", LnbNr(), this->DeviceNumber() + 1, 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:
diff --git a/device.h b/device.h
index cb3bc2c..da6d095 100644
--- a/device.h
+++ b/device.h
@@ -159,6 +159,40 @@ public:
static void Shutdown(void);
///< Closes down all devices.
///< Must be called at the end of the program.
+//ML
+public:
+ static void SetLnbNr(void);
+ ///< Called after changes in setup
+ ///< call SetLNBNrFromSetup for each device
+ virtual void SetLnbNrFromSetup(void) {};
+ ///< Called after changes in setup
+ ///< Read Setup.CardUsesLNBnr, write value to member variable of this class
+ ///< Only implemented in dvbdevice, other devices don't use LNBs
+ virtual int LnbNr(void) const { return ( cardIndex + 1 ) * -1; };
+ ///< Number of LNB. This is -cardIndex for all non-DVB devices.
+ ///< So, there will be no LNB conflicts for non-DVB devices.
+ virtual bool IsShareLnb(const cDevice *Device) { return false; };
+ ///< True if both devices differ (this != Device) and share the same LNB
+ virtual bool IsLnbConflict(const cChannel *Channel) { return false; };
+ ///< false if 'Channel' can be recieved with the same
+ ///< LNB as 'this' device is using
+ ///< Otherwise, true
+ 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) const;
+ ///< 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 'actual' device
+ ///< (device recieving live view) would be affected by switching to the requested channel.
+ ///< Returns -2 if there are no such devices and the actual device
+ ///< would not be affected by switching to the requested channel.
+//ML-Ende
+
+
private:
static int nextCardIndex;
int cardIndex;
diff --git a/dvbdevice.c b/dvbdevice.c
index f32b350..ea46b49 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -683,6 +683,14 @@ cDvbDevice::cDvbDevice(int Adapter, int Frontend)
// The DVR device (will be opened and closed as needed):
fd_dvr = -1;
+
+//ML
+ lnbState = -1;
+ SetLnbNrFromSetup();
+ lnbSource = NULL;
+//ML-Ende
+
+
// We only check the devices that must be present - the others will be checked before accessing them://XXX
@@ -934,6 +942,12 @@ bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *Ne
{
bool result = false;
bool hasPriority = Priority < 0 || Priority > this->Priority();
+ // LNB Sharing
+ if(hasPriority && GetMaxBadPriority(Channel) >= Priority) hasPriority = false;
+ if (Setup.VerboseLNBlog) {
+ isyslog("LNB %d: ProvidesChannel %d on device %d. Priority is %d, hasPriority is %d", LnbNr(), Channel->Number(), this->DeviceNumber() + 1, Priority, hasPriority);
+ }
+ // LNB Sharing END
bool needsDetachReceivers = false;
if (ProvidesTransponder(Channel)) {
@@ -982,7 +996,27 @@ bool cDvbDevice::IsTunedToTransponder(const cChannel *Channel)
bool cDvbDevice::SetChannelDevice(const cChannel *Channel, bool LiveView)
{
dvbTuner->Set(Channel);
- return true;
+ // LNB Sharing
+ cDvbTransponderParameters dtp(Channel->Parameters());
+
+ if (Channel->Frequency() >= Setup.LnbSLOF) {
+ lnbState = 1;
+ } else {
+ lnbState = 0;
+ }
+ if (dtp.Polarization() == 'v' || dtp.Polarization() == 'V') lnbState += 2;
+ lnbSource = (int*) Diseqcs.Get(CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization());
+
+ cDevice *tmpDevice;
+ if(tmpDevice = GetBadDevice(Channel)){
+ tmpDevice->DetachAllReceivers();
+ if (tmpDevice->CamSlot() && !tmpDevice->CamSlot()->IsDecrypting())
+ tmpDevice->CamSlot()->Assign(NULL);
+
+ tmpDevice->SwitchChannel(Channel, false);
+ }
+ // LNB Sharing End
+ return true;
}
bool cDvbDevice::HasLock(int TimeoutMs)
@@ -1023,6 +1057,47 @@ bool cDvbDevice::GetTSPacket(uchar *&Data)
return false;
}
+// LNB - Sharing
+void cDvbDevice::SetLnbNrFromSetup(void)
+{
+ lnbNr = Setup.CardUsesLnbNr[CardIndex()];
+ isyslog("LNB-sharing: patch version %s", LNB_SHARING_VERSION);
+ isyslog("LNB-sharing: setting device %d to use LNB %d", CardIndex() + 1, lnbNr);
+}
+
+bool cDvbDevice::IsShareLnb(const cDevice *Device)
+{
+ return this != Device && LnbNr() == Device->LnbNr();
+};
+
+
+bool cDvbDevice::IsLnbConflict(const cChannel *Channel)
+{
+ if(!cSource::IsSat(Channel->Source())) return false; // no conflict if the new channel is not on sat
+ if(!ProvidesSource(cSource::stSat)) return false; // no conflict if this device is not on sat
+//if(MaySwitchTransponder()) return false; // no conflict if this transponder may be switched
+ cDvbTransponderParameters dtp(Channel->Parameters());
+ if (Setup.DiSEqC) {
+ cDiseqc *diseqc;
+ diseqc = Diseqcs.Get(CardIndex() + 1, Channel->Source(), Channel->Frequency(), dtp.Polarization() );
+ if (LnbSource() != (int*) diseqc) return true;
+ return false;
+ } else
+ {
+ char requiredState;
+ if (Channel->Frequency() >= Setup.LnbSLOF) {
+ requiredState = 1 ;
+ } else {
+ requiredState = 0;
+ }
+ if (dtp.Polarization() == 'v' || dtp.Polarization() == 'V') requiredState += 2;
+ if(lnbState != requiredState) return true;
+ return false;
+ }
+}
+// LNB - Sharing Ende
+
+
// --- cDvbDeviceProbe -------------------------------------------------------
cList<cDvbDeviceProbe> DvbDeviceProbes;
diff --git a/dvbdevice.h b/dvbdevice.h
index ff606fd..446ea48 100644
--- a/dvbdevice.h
+++ b/dvbdevice.h
@@ -127,6 +127,26 @@ public:
virtual ~cDvbDevice();
virtual bool Ready(void);
+// LNB Sharing
+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
+// LNB Sharing-Ende
+
+public:
+ int *LnbSource(void) { return lnbSource; };
+ virtual int LnbNr(void) const { if(ProvidesSource(cSource::stSat)) return lnbNr; return CardIndex() * -1;};
+ virtual void SetLnbNrFromSetup(void);
+
+public:
+ virtual bool IsLnbConflict(const cChannel *Channel);
+ virtual bool IsShareLnb(const cDevice *Device);
+
+// LNB Sharing Ende
+
+
// Common Interface facilities:
private:
diff --git a/eitscan.c b/eitscan.c
index 2b43e71..8cf975a 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -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 || (MaySwitchTransponder || 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 --git a/menu.c b/menu.c
index 19cfabb..f507532 100644
--- a/menu.c
+++ b/menu.c
@@ -2885,6 +2885,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[40];
+ for (int i = 1; i <= cDevice::NumDevices(); i++) {
+ if (cDevice::GetDevice(i - 1)->ProvidesSource(cSource::stSat)) {
+ snprintf( tmp, 40, 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));
@@ -2901,6 +2918,10 @@ eOSState cMenuSetupLNB::ProcessKey(eKeys Key)
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;
diff --git a/po/de_DE.po b/po/de_DE.po
index 4d4f3df..4272b9d 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -1321,3 +1321,13 @@ msgstr "Taste drücken, um Neustart abzubrechen"
#, c-format
msgid "VDR will shut down in %s minutes"
msgstr "VDR wird in %s Minuten ausschalten"
+
+msgid "Channel locked by LNB!"
+msgstr "Kanal durch LNB gesperrt!"
+
+msgid "Setup.LNB$DVB device %d uses LNB No."
+msgstr "DVB-Empfänger %d nutzt LNB Nr."
+
+msgid "Setup.LNB$Log LNB usage"
+msgstr "LNB-Nutzung protokollieren"
+
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 0d4cb7c..78cae5e 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -1327,3 +1327,13 @@ msgstr "Appuyer sur une touche pour annuler le redémarrage"
#, c-format
msgid "VDR will shut down in %s minutes"
msgstr "VDR s'arrêtera dans %s minutes"
+
+msgid "Channel locked by LNB!"
+msgstr "Chaîne interdite par la LNB"
+
+msgid "Setup.LNB$DVB device %d uses LNB No."
+msgstr "La carte DVB %d utilise la LNB No."
+
+msgid "Setup.LNB$Log LNB usage"
+msgstr "Protocoller l'utilisation du LNB"
+
diff --git a/po/it_IT.po b/po/it_IT.po
index 0ca9025..71ebd86 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -1328,3 +1328,14 @@ msgstr "Premi un tasto per annullare il riavvio"
#, c-format
msgid "VDR will shut down in %s minutes"
msgstr "VDR si spegnerà tra %s minuti"
+
+msgid "Channel locked by LNB!"
+msgstr "Canale bloccato dal LNB!"
+
+msgid "Setup.LNB$DVB device %d uses LNB No."
+msgstr "La scheda DVB %d utilizza LNB No."
+
+msgid "Setup.LNB$Log LNB usage"
+msgstr "Registra utilizzo LNB"
+
+
diff --git a/po/nl_NL.po b/po/nl_NL.po
index f570337..0a365af 100644
--- a/po/nl_NL.po
+++ b/po/nl_NL.po
@@ -1325,3 +1325,14 @@ msgstr "Druk een willekeurige toets om herstarten af te breken"
#, c-format
msgid "VDR will shut down in %s minutes"
msgstr "VDR zal na %s minuten uitschakelen"
+
+msgid "Channel locked by LNB!"
+msgstr "Kanaal geblokkeerd door LNB"
+
+msgid "Setup.LNB$DVB device %d uses LNB No."
+msgstr "LNB kaart %d gebruikt LNB Nr."
+
+msgid "Setup.LNB$Log LNB usage"
+msgstr "Houd LNB gebruik bij"
+
+
diff --git a/po/ru_RU.po b/po/ru_RU.po
index 889b98b..5b9a99f 100644
--- a/po/ru_RU.po
+++ b/po/ru_RU.po
@@ -1322,3 +1322,14 @@ msgstr "½ÐÖÜØâÕ ÛîÑãî ÚÝÞßÚã ÔÛï ÞâÜÕÝë ßÕàÕ×ÐÓàã×ÚØ"
#, c-format
msgid "VDR will shut down in %s minutes"
msgstr "VDR ÒëÚÛîçØâáï çÕàÕ× %s ÜØÝãâ"
+
+msgid "Channel locked by LNB!"
+msgstr "ºÞÝÒÕàâÕà ÑÛÞÚØàãÕâ ÚÐÝÐÛ"
+
+msgid "Setup.LNB$DVB device %d uses LNB No."
+msgstr "DVB ãáâàÞÙáâÒÞ %d ØáßÞÛì×ãÕâ LNB No."
+
+msgid "Setup.LNB$Log LNB usage"
+msgstr "»ÞÓØàÞÒÐÝØÕ ØáßÞÛì×ÞÒÐÝØï LNB"
+
+
diff --git a/vdr.c b/vdr.c
index 93f586a..6825363 100644
--- a/vdr.c
+++ b/vdr.c
@@ -880,23 +880,27 @@ int main(int argc, char *argv[])
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; // only check other devices if they have been left alone for a while
+ if( d->GetMaxBadPriority(Timer->Channel()) <= 0) Device = d; // LNB Sharing
}
else if (timeout && !Device && InVpsMargin && !d->Receiving() && d->ProvidesTransponderExclusively(Timer->Channel()))
- Device = d; // use this one only if no other with less impact can be found
- }
+ // Device = d; // use this one only if no other with less impact can be found
+ if( d->GetMaxBadPriority(Timer->Channel()) <= 0) Device = d; // LNB Sharing
+ }
}
if (!Device && InVpsMargin && !DeviceAvailable) {
cDevice *d = cDevice::ActualDevice();
if (!d->Receiving() && d->ProvidesTransponder(Timer->Channel()) && Now - DeviceUsed[d->DeviceNumber()] > TIMERDEVICETIMEOUT)
- Device = d; // use the actual device as a last resort
+ // Device = d; // use the actual device as a last resort
+ if( d->GetMaxBadPriority(Timer->Channel()) <= 0) Device = d; // LNB Sharing
+
}
// Switch the device to the transponder:
if (Device) {
if (!Device->IsTunedToTransponder(Timer->Channel())) {
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());
+ dsyslog("VDR: switching device %d to channel %d", Device->DeviceNumber() + 1, Timer->Channel()->Number());
Device->SwitchChannel(Timer->Channel(), false);
DeviceUsed[Device->DeviceNumber()] = Now;
}