Latest version of SourceCaps patch?

Message ID 4253F541.9070809@icem.com
State New
Headers

Commit Message

Carsten Koch April 6, 2005, 2:42 p.m. UTC
  Hi Christian,

Christian Schuld wrote:
...
> you'll need the SourceCaps patch. VDR by itself doesn't know which cards are 
> capable of receiving which sources. VDR assumes every DVB-S card can receive 
> all satellite sources. SourceCaps patch binds sources to cards.

Thanks!

I have taken the version you posted on December 12th,
fixed some bugs in it and applied it to VDR 1.3.23.
The result is attached.
Works fine! Thank you very much!
It may require a little more cleanup like removing the
erg variable, etc.

A few questions remain:

* Are you planning to implement a setup OSD?
* Should MAXSOURCECAPS be reduced to save memory?
* Is Klaus still planning to put a feature like this into standard VDR?

Carsten.
  

Patch

diff -ru /hetis/home/cko/VDR/config.c VDR/config.c
--- /hetis/home/cko/VDR/config.c	2005-02-20 13:52:59.000000000 +0100
+++ VDR/config.c	2005-04-05 22:14:09.953996256 +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
@@ -298,6 +299,7 @@ 
   MultiSpeedMode = 0;
   ShowReplayMode = 0;
   ResumeID = 0;
+  memset(SourceCaps, 0, sizeof(SourceCaps));
   CurrentChannel = -1;
   CurrentVolume = MAXVOLUME;
   CurrentDolby = 0;
@@ -364,6 +366,54 @@ 
   return false;
 }
 
+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)
+{
+  bool erg = true;
+  char *p;
+  int d = strtol(Value, &p, 10), i = 0;
+  d--;
+  while(p<Value+strlen(Value))
+  {
+     if(*p==0) return erg;
+     if(isblank(*p)) ++p;
+     if(isalpha(*p))
+     {
+        int source = cSource::FromString(p);
+        if(source != cSource::stNone)
+            SourceCaps[d][i++] = source;
+        else
+            return false;
+        //printf("SourceCaps[%i][%i] = %i ... p = %s\n", d, i-1, SourceCaps[d][i-1], p);
+        while(!isblank(*p) && *p)
+            ++p;
+        if(i>MAXSOURCECAPS) return false;
+     }
+  }
+  return true;
+}
+
 void cSetup::StoreLanguages(const char *Name, int *Values)
 {
   char buffer[I18nNumLanguages * 4];
@@ -455,6 +505,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);
@@ -519,6 +570,7 @@ 
   Store("MultiSpeedMode",     MultiSpeedMode);
   Store("ShowReplayMode",     ShowReplayMode);
   Store("ResumeID",           ResumeID);
+  StoreSourceCaps("SourceCaps");
   Store("CurrentChannel",     CurrentChannel);
   Store("CurrentVolume",      CurrentVolume);
   Store("CurrentDolby",       CurrentDolby);
diff -ru /hetis/home/cko/VDR/config.h VDR/config.h
--- /hetis/home/cko/VDR/config.h	2005-03-05 16:44:35.000000000 +0100
+++ VDR/config.h	2005-04-05 22:12:55.379333328 +0200
@@ -198,6 +198,8 @@ 
 private:
   void StoreLanguages(const char *Name, int *Values);
   bool ParseLanguages(const char *Value, int *Values);
+  void StoreSourceCaps(const char *Name);
+  bool ParseSourceCaps(const char *Value);
   bool Parse(const char *Name, 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);
@@ -252,6 +254,7 @@ 
   int MultiSpeedMode;
   int ShowReplayMode;
   int ResumeID;
+  int SourceCaps[MAXDEVICES][MAXSOURCECAPS];
   int CurrentChannel;
   int CurrentVolume;
   int CurrentDolby;
diff -ru /hetis/home/cko/VDR/device.c VDR/device.c
--- /hetis/home/cko/VDR/device.c	2005-02-27 14:55:15.000000000 +0100
+++ VDR/device.c	2005-04-05 22:31:42.398392904 +0200
@@ -175,8 +175,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!");
 }
@@ -314,6 +316,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;
diff -ru /hetis/home/cko/VDR/device.h VDR/device.h
--- /hetis/home/cko/VDR/device.h	2005-02-20 15:06:28.000000000 +0100
+++ VDR/device.h	2005-04-05 22:12:55.387332112 +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
@@ -127,6 +128,9 @@ 
          ///< 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.
+         ///< By default the SourceCaps of all devices are set.         
   static void Shutdown(void);
          ///< Closes down all devices.
          ///< Must be called at the end of the program.
@@ -134,6 +138,8 @@ 
   static int nextCardIndex;
   int cardIndex;
 protected:
+  int sourceCaps[MAXSOURCECAPS];
+protected:
   cDevice(void);
   virtual ~cDevice();
   static int NextCardIndex(int n = 0);
diff -ru /hetis/home/cko/VDR/dvbdevice.c VDR/dvbdevice.c
--- /hetis/home/cko/VDR/dvbdevice.c	2005-03-21 17:19:21.857154000 +0100
+++ VDR/dvbdevice.c	2005-04-05 22:12:55.404329528 +0200
@@ -766,9 +766,16 @@ 
 bool cDvbDevice::ProvidesSource(int Source) const
 {
   int type = Source & cSource::st_Mask;
+  if(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;
   return true;
 }
diff -ru /hetis/home/cko/VDR/sources.c VDR/sources.c
--- /hetis/home/cko/VDR/sources.c	2004-12-26 12:58:52.000000000 +0100
+++ VDR/sources.c	2005-04-05 22:12:55.421326944 +0200
@@ -68,7 +68,7 @@ 
      int pos = 0;
      bool dot = false;
      bool neg = false;
-     while (*++s) {
+     while (*++s && !isblank(*s)) {
            switch (toupper(*s)) {
              case '0' ... '9': pos *= 10;
                                pos += *s - '0';