On Sat, Jan 05, 2008 at 06:53:48PM +0100, Reinhard Nissl wrote: Hello, with the last patch, VDR refuse to tune to any DVB-S2 channels. I guess that VDR thinks all my card are only DVB-S ones. I get "Channel not available!" on all DVB-S2 channels. Any maybe not directly interesting, but with this patch, graphlcd make vdr segault at start. Thanks, > 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:rnissl@xxxxxx > --- ../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 > vdr@xxxxxxxxxxx > http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr -- Grégoire FAVRE http://gregoire.favre.googlepages.com http://www.gnupg.org http://picasaweb.google.com/Gregoire.Favre _______________________________________________ vdr mailing list vdr@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr