SourceCaps patch for VDR 1.3.31.

Message ID 431AD5B9.4000101@icem.com
State New
Headers

Commit Message

Carsten Koch Sept. 4, 2005, 11:08 a.m. UTC
  The attached patch allows a VDR system with multiple
cards to attach each card to an individual dish
pointing at a different satellite.

I have 3 DVB cards in my VDR system:

1) FF card connected to one output of LNB at a dish
    pointed at Astra 19.2E.

2) budget card connected to another output of LNB at a dish
    pointed at Astra 19.2E.

3) budget card connected to output of LNB at a dish
    pointed at Eutelsat 13.0E.

I am using the following entries for that in my setup.conf:

SourceCaps = 1 S19.2E
SourceCaps = 2 S19.2E
SourceCaps = 3 S13.0E
  

Comments

Iwan Davies Sept. 4, 2005, 2:07 p.m. UTC | #1
On Sun, 04 Sep 2005 13:08:41 +0200, Carsten Koch wrote:

> The attached patch allows a VDR system with multiple
> cards to attach each card to an individual dish
> pointing at a different satellite.
> 
> I have 3 DVB cards in my VDR system:
> 
> 1) FF card connected to one output of LNB at a dish
>     pointed at Astra 19.2E.
> 
> 2) budget card connected to another output of LNB at a dish
>     pointed at Astra 19.2E.
> 
> 3) budget card connected to output of LNB at a dish
>     pointed at Eutelsat 13.0E.
> 
> I am using the following entries for that in my setup.conf:
> 
> SourceCaps = 1 S19.2E
> SourceCaps = 2 S19.2E
> SourceCaps = 3 S13.0E


Can this be used with Diseqc? I have three DVB cards, distrbuted as follows

1) FF card connected to a Diseqc switch switching between S19.2E and S13.0E
2) budget card connected to LNB pointed at S28.2E/S28.5E
3) budget DVB-T card 

So would this config work:

SourceCaps = 1 S19.2E S13.0E
SourceCaps = 2 S28.2E S28.5E
SourceCaps = 3 T

Aside from the SourceCaps approach, wouldn't a more logical system for VDR 
be to modify the sources.conf so that you had to indicate which card(s) 
was/were used for each source, e.g.
...
S10.0E
S13.0E	1
S19.2E	1
S28.2E	2
S28.5E	2
T	3

or in Carsten's case

S13.0	3
S19.2	1,2

That would then allow the CA field in channels.conf to be used correctly, 
since the assignment between the source and the cards available for that 
source would be defined in sources.conf. It would also mean that changing 
the allocation of channels to particular cards (e.g. after adding new cards 
that then changes the order in which cards are detected) would be a lot 
simpler than at present (where you have to edit every single channel in 
channels.conf).

Iwan
  
Carsten Koch Sept. 7, 2005, 7:11 a.m. UTC | #2
Iwan Davies wrote:
...
> So would this config work:
> 
> SourceCaps = 1 S19.2E S13.0E
> SourceCaps = 2 S28.2E S28.5E
> SourceCaps = 3 T

I guess it should. Just give it a try and report back what happened.
I am not the author of the patch, though.
I have just made a few changes that Klaus requested and
I ported the patch to the latest vdr.


> Aside from the SourceCaps approach, wouldn't a more logical system for VDR 
> be to modify the sources.conf so that you had to indicate which card(s) 
> was/were used for each source, e.g.
> ...
> S10.0E
> S13.0E	1
> S19.2E	1
> S28.2E	2
> S28.5E	2
> T	3
> 
> or in Carsten's case
> 
> S13.0	3
> S19.2	1,2
> 
> That would then allow the CA field in channels.conf to be used correctly, 
> since the assignment between the source and the cards available for that 
> source would be defined in sources.conf. It would also mean that changing 
> the allocation of channels to particular cards (e.g. after adding new cards 
> that then changes the order in which cards are detected) would be a lot 
> simpler than at present (where you have to edit every single channel in 
> channels.conf).

I had to make *no* changes in channels.conf to use the SourceCaps feature.
The CA field could remain as it is.

Carsten.
  
Christian Schuld Sept. 8, 2005, 5:40 p.m. UTC | #3
Hi,

On Wednesday 07 September 2005 09:11, Carsten Koch wrote:
> Iwan Davies wrote:
> > SourceCaps = 1 S19.2E S13.0E
> > SourceCaps = 2 S28.2E S28.5E

This would be enough. SourceCaps are only valid for DVB-S at this time.

> > Aside from the SourceCaps approach, wouldn't a more logical system for
> > VDR be to modify the sources.conf so that you had to indicate which
> > card(s) was/were used for each source, e.g.
> > ...
> > S10.0E
> > S13.0E	1
> > S19.2E	1
> > S28.2E	2
> > S28.5E	2
> > T	3
> >
> > or in Carsten's case
> >
> > S13.0	3
> > S19.2	1,2

This would have the same effect but just uses another syntax ;-)
Lets Klaus decide how to implement this permanently.

> > That would then allow the CA field in channels.conf to be used correctly,
> > since the assignment between the source and the cards available for that
> > source would be defined in sources.conf. It would also mean that changing
> > the allocation of channels to particular cards (e.g. after adding new
> > cards that then changes the order in which cards are detected) would be a
> > lot simpler than at present (where you have to edit every single channel
> > in channels.conf).
>
> I had to make *no* changes in channels.conf to use the SourceCaps feature.
> The CA field could remain as it is.

Exactly, I implemented the SourceCaps functionality at avoid any fiddeling 
with a CA field.

> Carsten.

btw: Carsten, thanks for maintenance :-) I do not have much time for this at 
the moment.
  
Iwan Davies Sept. 8, 2005, 7:09 p.m. UTC | #4
On Thu, 8 Sep 2005 19:40:05 +0200, Christian Schuld wrote:

> Hi,
> 
> On Wednesday 07 September 2005 09:11, Carsten Koch wrote:
>> Iwan Davies wrote:
>>> SourceCaps = 1 S19.2E S13.0E
>>> SourceCaps = 2 S28.2E S28.5E
> 
> This would be enough. SourceCaps are only valid for DVB-S at this time.
> 
>>> S13.0	3
>>> S19.2	1,2
> 
> This would have the same effect but just uses another syntax ;-)
> Lets Klaus decide how to implement this permanently.
> 
>>
>> I had to make *no* changes in channels.conf to use the SourceCaps feature.
>> The CA field could remain as it is.
> 
> Exactly, I implemented the SourceCaps functionality at avoid any fiddeling 
> with a CA field.
> 
>> Carsten.
> 
> btw: Carsten, thanks for maintenance :-) I do not have much time for this at 
> the moment.
> 
Ah, ok - now I understand the idea of SourceCaps better - of course, my 
solution really amounts to the same as yours. I'd still vote for coupling 
the sources to resources in sources.conf rather than setup.conf though; it 
just seems more appropriate to me.

My thanks to Carsten and Christian for their efforts. Unfortunately having 
fairly limited experience in Linux I have to rely on others to do the 
complicated bits for me (viz. lirc, etc.), so I'm currently using the 
debian packages from e-tobi.net, in which the SourceCaps patch is not 
currently included. That's why I had to change the CA field when I added my 
DVB-T card.

I'll have to try to start configuring and compiling my own systems, but at 
the moment, my 3-year old and 1-year old seem more interested in grabbing 
the keyboard off me, and those Balamory recordings need to be accessible at 
all times, just in case.

Iwan
  

Patch

diff -ur vdr-1.3.31/config.c vdr-1.3.31+SourceCaps/config.c
--- vdr-1.3.31/config.c	2005-08-13 15:47:08.000000000 +0200
+++ vdr-1.3.31+SourceCaps/config.c	2005-09-04 12:52:24.050996696 +0200
@@ -14,6 +14,7 @@ 
 #include "interface.h"
 #include "plugin.h"
 #include "recording.h"
+#include "sources.h"
 
 // IMPORTANT NOTE: in the 'sscanf()' calls there is a blank after the '%d'
 // format characters in order to allow any number of blanks after a numeric
@@ -299,6 +300,8 @@ 
   MultiSpeedMode = 0;
   ShowReplayMode = 0;
   ResumeID = 0;
+  memset(SourceCaps, 0, sizeof SourceCaps);
+  SourceCapsSet = false;
   CurrentChannel = -1;
   CurrentVolume = MAXVOLUME;
   CurrentDolby = 0;
@@ -400,6 +403,49 @@ 
   return true;
 }
 
+void cSetup::StoreSourceCaps(const char *Name)
+{
+  cSetupLine *l;
+  while ((l = Get(Name)) != NULL)
+        Del(l);
+
+  for (int i = 0; i < MAXDEVICES; i++) {
+      char buffer[MAXPARSEBUFFER]={0,}, *q = buffer;
+      int j = 0;
+      while (SourceCaps[i][j] && j < MAXSOURCECAPS) {
+            if (j==0) 
+               q += snprintf(buffer, sizeof(buffer), "%i ", i+1);
+            q += snprintf(q, sizeof(buffer) - (q-buffer), "%s ", *cSource::ToString(SourceCaps[i][j++]));
+      }
+      if (*buffer)
+         Store(Name, buffer, NULL, true);
+      }
+}
+
+bool cSetup::ParseSourceCaps(const char *Value)
+{
+  char *p;
+  int d = strtol(Value, &p, 10)-1, i = 0;
+  while (p < Value+strlen(Value)) {
+     	if (*p==0) return true;
+     	if (isblank(*p)) ++p;
+     	if (isalpha(*p)) {
+	   int source = cSource::FromString(p);
+	   if (source != cSource::stNone) {
+	      SourceCaps[d][i++] = source;
+	      SourceCapsSet = true;
+	      }
+	   else
+	      return false;
+	   while (!isblank(*p) && *p)
+		 ++p;
+	   if (i>MAXSOURCECAPS) 
+	      return false;
+     	   }
+        }
+  return true;
+}
+
 bool cSetup::Parse(const char *Name, const char *Value)
 {
   if      (!strcasecmp(Name, "OSDLanguage"))         OSDLanguage        = atoi(Value);
@@ -457,6 +503,7 @@ 
   else if (!strcasecmp(Name, "MultiSpeedMode"))      MultiSpeedMode     = atoi(Value);
   else if (!strcasecmp(Name, "ShowReplayMode"))      ShowReplayMode     = atoi(Value);
   else if (!strcasecmp(Name, "ResumeID"))            ResumeID           = atoi(Value);
+  else if (!strcasecmp(Name, "SourceCaps"))          return ParseSourceCaps(Value);
   else if (!strcasecmp(Name, "CurrentChannel"))      CurrentChannel     = atoi(Value);
   else if (!strcasecmp(Name, "CurrentVolume"))       CurrentVolume      = atoi(Value);
   else if (!strcasecmp(Name, "CurrentDolby"))        CurrentDolby       = atoi(Value);
@@ -522,6 +569,7 @@ 
   Store("MultiSpeedMode",     MultiSpeedMode);
   Store("ShowReplayMode",     ShowReplayMode);
   Store("ResumeID",           ResumeID);
+  if (SourceCapsSet) StoreSourceCaps("SourceCaps");
   Store("CurrentChannel",     CurrentChannel);
   Store("CurrentVolume",      CurrentVolume);
   Store("CurrentDolby",       CurrentDolby);
diff -ur vdr-1.3.31/config.h vdr-1.3.31+SourceCaps/config.h
--- vdr-1.3.31/config.h	2005-08-26 14:28:40.000000000 +0200
+++ vdr-1.3.31+SourceCaps/config.h	2005-09-04 12:52:24.051996544 +0200
@@ -199,6 +199,8 @@ 
   void StoreLanguages(const char *Name, int *Values);
   bool ParseLanguages(const char *Value, int *Values);
   bool Parse(const char *Name, const char *Value);
+  void StoreSourceCaps(const char *Name);
+  bool ParseSourceCaps(const char *Value);
   cSetupLine *Get(const char *Name, const char *Plugin = NULL);
   void Store(const char *Name, const char *Value, const char *Plugin = NULL, bool AllowMultiple = false);
   void Store(const char *Name, int Value, const char *Plugin = NULL);
@@ -253,6 +255,8 @@ 
   int MultiSpeedMode;
   int ShowReplayMode;
   int ResumeID;
+  int SourceCaps[MAXDEVICES][MAXSOURCECAPS];
+  bool SourceCapsSet;
   int CurrentChannel;
   int CurrentVolume;
   int CurrentDolby;
diff -ur vdr-1.3.31/device.c vdr-1.3.31+SourceCaps/device.c
--- vdr-1.3.31/device.c	2005-08-27 11:01:09.000000000 +0200
+++ vdr-1.3.31+SourceCaps/device.c	2005-09-04 12:52:24.053996240 +0200
@@ -174,8 +174,10 @@ 
   for (int i = 0; i < MAXRECEIVERS; i++)
       receiver[i] = NULL;
 
-  if (numDevices < MAXDEVICES)
+  if (numDevices < MAXDEVICES) {
      device[numDevices++] = this;
+     SetSourceCaps(cardIndex);
+     }
   else
      esyslog("ERROR: too many devices!");
 }
@@ -329,6 +331,17 @@ 
   return d;
 }
 
+void cDevice::SetSourceCaps(int Index)
+{
+  for (int d = 0; d < numDevices; d++) {
+      if (Index < 0 || Index == device[d]->CardIndex()) {
+	 for (int i = 0; i < MAXSOURCECAPS; i++)
+	     device[d]->sourceCaps[i] = Setup.SourceCaps[device[d]->CardIndex()][i];
+	 }
+      }
+}
+
+
 void cDevice::Shutdown(void)
 {
   primaryDevice = NULL;
Only in vdr-1.3.31+SourceCaps: device.c.orig
diff -ur vdr-1.3.31/device.h vdr-1.3.31+SourceCaps/device.h
--- vdr-1.3.31/device.h	2005-08-21 10:52:20.000000000 +0200
+++ vdr-1.3.31+SourceCaps/device.h	2005-09-04 12:52:24.054996088 +0200
@@ -23,6 +23,7 @@ 
 #include "tools.h"
 
 #define MAXDEVICES         16 // the maximum number of devices in the system
+#define MAXSOURCECAPS     128 // the maximum number of different sources per device
 #define MAXPIDHANDLES      64 // the maximum number of different PIDs per device
 #define MAXRECEIVERS       16 // the maximum number of receivers per device
 #define MAXVOLUME         255
@@ -133,6 +134,8 @@ 
          ///< given Priority.
          ///< See ProvidesChannel() for more information on how
          ///< priorities are handled, and the meaning of NeedsDetachReceivers.
+  static void SetSourceCaps(int Index = -1);
+	 ///< Sets the SourceCaps of the given device according to the Setup data.
   static void Shutdown(void);
          ///< Closes down all devices.
          ///< Must be called at the end of the program.
@@ -140,6 +143,7 @@ 
   static int nextCardIndex;
   int cardIndex;
 protected:
+  int sourceCaps[MAXSOURCECAPS];
   cDevice(void);
   virtual ~cDevice();
   virtual bool Ready(void);
diff -ur vdr-1.3.31/dvbdevice.c vdr-1.3.31+SourceCaps/dvbdevice.c
--- vdr-1.3.31/dvbdevice.c	2005-08-21 11:17:20.000000000 +0200
+++ vdr-1.3.31+SourceCaps/dvbdevice.c	2005-09-04 12:52:24.056995784 +0200
@@ -754,10 +754,17 @@ 
 bool cDvbDevice::ProvidesSource(int Source) const
 {
   int type = Source & cSource::st_Mask;
-  return type == cSource::stNone
-      || type == cSource::stCable && frontendType == FE_QAM
-      || type == cSource::stSat   && frontendType == FE_QPSK
-      || type == cSource::stTerr  && frontendType == FE_OFDM;
+  if (Setup.SourceCapsSet && type == cSource::stSat && frontendType == FE_QPSK) {
+     for (int i = 0; i < MAXSOURCECAPS; i++)
+         if (sourceCaps[i] == Source)
+            return true;
+     return false;
+     }
+  else
+     return type == cSource::stNone				 
+    	 || type == cSource::stCable && frontendType == FE_QAM	 
+    	 || type == cSource::stSat   && frontendType == FE_QPSK  
+    	 || type == cSource::stTerr  && frontendType == FE_OFDM; 
 }
 
 bool cDvbDevice::ProvidesTransponder(const cChannel *Channel) const