Hi,
Reinhard Nissl schrieb:
>> Well, I was in contact with Marco already and attached you'll
>> find a minimalistic change which reports "channel not available".
>> Now VDR should already be able to kick a low priority DVB-S
>> recording (or transfer thread) from a DVB-S2 device.
>
> The previous patch was wrong. Only DVB-S2 devices "could" provide
> channels. The revised patch works now as expected.
>
>> Still missing is to prefer DVB-S devices for DVB-S recordings so
>> that DVB-S2 devices remain available for DVB-S2 recordings of
>> same priority.
>
> Still to do.
The attached version implements this behavior now. You may want
to experiment a bit with the decision logic as explained below.
The decision is based on the number of modulation systems a card
provides. For example, my NOVA-S provides one (DVB-S) and my
SkyStar HD provides three (DVB-S, DVB-DSS, DVB-S2).
The decision logic is implemented in cDevice::GetDevice(), so
have a look into device.c. After applying the patch, you'll find
two lines in that function marked with comments like /*1*/ and
/*2*/, and the latter one was disabled by a line comment.
In my scenario with just the above cards and vdr-xine as software
device, watching a channel requires VDR to operate in transfer
mode. Therefore it selects a device which provides for example a
DVB-S channel. The patched version will choose the NOVA-S with
either implementation /*1*/ or /*2*/.
Let's then start a DVB-S recording on a different transponder.
When implementation /*2*/ would be active, VDR would choose the
SkyStar HD, as the NOVA-S is claimed by transfer mode. Then, try
to switch to a DVB-S2 channel. It wouldn't work, as the SkyStar
HD would be claimed by a DVB-S recording.
That's why I've chosen implementation /*1*/ as default. For the
above scenario, starting a DVB-S recording on a different
transponder will choose the NOVA-S and kick off transfer mode.
Then VDR will look for a card to set up transfer mode again and
it will choose the only remaining card, the SkyStar HD. If you
then try to switch to a DVB-S2 channel, it will work as the
SkyStar HD is not claimed by a recording.
>> The patch is incremental to the original dvbs2 patch from
>> yesterday, i. e. you can simply apply it to your already patched VDR.
Bye.
--
Dipl.-Inform. (FH) Reinhard Nissl
mailto:[EMAIL PROTECTED]
--- ../vdr-1.5.12-dvbs2-other/device.c 2008-01-01 22:55:18.000000000 +0100
+++ device.c 2008-01-05 18:06:15.000000000 +0100
@@ -359,6 +359,21 @@ cDevice *cDevice::GetDevice(int Index)
return (0 <= Index && Index < numDevices) ? device[Index] : NULL;
}
+inline int GetClippedModulationSystemCount(int AvailableBits, cDevice *Device)
+{
+ int ModulationSystemCount = Device->ModulationSystemCount();
+ int MaxModulationSystemCount = 1 << AvailableBits;
+ if (ModulationSystemCount > MaxModulationSystemCount) {
+ esyslog("ERROR: device %d supports %d modulation systems but cDevice::GetDevice() currently only supports %d modulation systems which should be fixed", Device->CardIndex() + 1, ModulationSystemCount, MaxModulationSystemCount);
+ ModulationSystemCount = MaxModulationSystemCount;
+ }
+ else if (ModulationSystemCount <= 0) {
+ esyslog("ERROR: device %d reported an invalid number (%d) of supported modulation systems. The device should be fixed to return at least 1", Device->CardIndex() + 1, ModulationSystemCount);
+ ModulationSystemCount = 1;
+ }
+ return ModulationSystemCount;
+}
+
cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView)
{
// Collect the current priorities of all CAM slots that can decrypt the channel:
@@ -408,11 +423,13 @@ cDevice *cDevice::GetDevice(const cChann
imp <<= 1; imp |= LiveView ? !device[i]->IsPrimaryDevice() || ndr : 0; // prefer the primary device for live viewing if we don't need to detach existing receivers
imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode
imp <<= 1; imp |= device[i]->Receiving(); // avoid devices that are receiving
+/*1*/ imp <<= 2; imp |= GetClippedModulationSystemCount(2, device[i]) - 1; // avoid cards which support multiple modulation 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)
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
+///*2*/ imp <<= 2; imp |= GetClippedModulationSystemCount(2, device[i]) - 1; // avoid cards which support multiple modulation systems
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
--- ../vdr-1.5.12-dvbs2-other/device.h 2007-10-21 11:21:52.000000000 +0200
+++ device.h 2008-01-05 17:22:25.000000000 +0100
@@ -224,6 +224,10 @@ public:
///< function itself actually returns true.
///< The default implementation always returns false, so a derived cDevice
///< class that can provide channels must implement this function.
+ virtual int ModulationSystemCount() const { return 0; }
+ ///< Returns the number of modulation systems the device supports.
+ ///< The default implementation always returns 0, so a derived cDevice
+ ///< class that can provide channels must implement this function.
virtual bool IsTunedToTransponder(const cChannel *Channel);
///< Returns true if this device is currently tuned to the given Channel's
///< transponder.
--- ../vdr-1.5.12-dvbs2-other/dvbdevice.c 2008-01-01 22:55:18.000000000 +0100
+++ dvbdevice.c 2008-01-05 17:36:36.000000000 +0100
@@ -406,6 +406,7 @@ cDvbDevice::cDvbDevice(int n)
{
ciAdapter = NULL;
dvbTuner = NULL;
+ modulationSystemCount = 0;
frontendType = DVBFE_DELSYS_DUMMY;
spuDecoder = NULL;
digitalAudio = false;
@@ -468,8 +469,14 @@ cDvbDevice::cDvbDevice(int n)
// We only check the devices that must be present - the others will be checked before accessing them://XXX
if (fd_frontend >= 0) {
- if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0)
+ if (ioctl(fd_frontend, DVBFE_GET_DELSYS, &frontendType) >= 0) {
+ // determine number of supported modulation systems by counting the bits
+ for (int i = 0; i < 32; i++) {
+ if (frontendType & (1u << i))
+ modulationSystemCount++;
+ }
dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType);
+ }
else
LOG_ERROR;
}
@@ -798,7 +805,13 @@ bool cDvbDevice::ProvidesSource(int Sour
bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const
{
- return ProvidesSource(Channel->Source()) && (!cSource::IsSat(Channel->Source()) || !Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization()));
+ if (!ProvidesSource(Channel->Source()))
+ return false; // doesn't provide source
+ if (!cSource::IsSat(Channel->Source()))
+ return true; // source is sufficient for non sat
+ if (!(frontendType & Channel->ModulationSystem()))
+ return false; // requires modulation system which frontend doesn't provide
+ return !Setup.DiSEqC || Diseqcs.Get(Channel->Source(), Channel->Frequency(), Channel->Polarization());
}
bool cDvbDevice::ProvidesChannel(const cChannel *Channel, int Priority, bool *NeedsDetachReceivers) const
@@ -807,7 +820,7 @@ bool cDvbDevice::ProvidesChannel(const c
bool hasPriority = Priority < 0 || Priority > this->Priority();
bool needsDetachReceivers = false;
- if (ProvidesSource(Channel->Source())) {
+ if (ProvidesTransponder(Channel)) {
result = hasPriority;
if (Priority >= 0 && Receiving(true)) {
if (dvbTuner->IsTunedTo(Channel)) {
--- ../vdr-1.5.12-dvbs2-other/dvbdevice.h 2008-01-01 22:55:18.000000000 +0100
+++ dvbdevice.h 2008-01-05 17:29:49.000000000 +0100
@@ -35,6 +35,7 @@ public:
///< Must be called before accessing any DVB functions.
///< \return True if any devices are available.
private:
+ int modulationSystemCount;
dvbfe_delsys frontendType;
int fd_osd, fd_audio, fd_video, fd_dvr, fd_stc, fd_ca;
protected:
@@ -66,6 +67,7 @@ public:
virtual bool ProvidesSource(int Source) const;
virtual bool ProvidesTransponder(const cChannel *Channel) const;
virtual bool ProvidesChannel(const cChannel *Channel, int Priority = -1, bool *NeedsDetachReceivers = NULL) const;
+ virtual int ModulationSystemCount() const { return modulationSystemCount; }
virtual bool IsTunedToTransponder(const cChannel *Channel);
protected:
virtual bool SetChannelDevice(const cChannel *Channel, bool LiveView);
_______________________________________________
vdr mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr