Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] some patches for vdr-1.3.18 (SourceCaps, RO, timer-info) and plugins(femon, osdimage)



Hi list!

Here some patches updated to work with vdr-1.3.18 and some plugin-patches respectively.

femon: should work in regular cases (dirty hack). I've disabled the green button so it is not possible to switch audio-channel within the plugin. Furthermore I changed

#ifdef NTSC_SYSTEM
#define OSDHEIGHT 420 // in pixels
#else
#define OSDHEIGHT 480 // in pixels
#endif
#define OSDWIDTH 600 // in pixels
to
#ifdef NTSC_SYSTEM
#define OSDHEIGHT Setup.OSDHeight // in pixels
#else
#define OSDHEIGHT Setup.OSDHeight // in pixels
#endif
#define OSDWIDTH Setup.OSDWidth // in pixels

so the plugin respects the OSD-settings and shows completely on my 16:9-tv. If you have problems with that (e.g. with very low OSDHEIGHT << 400) you would have to change it back.
BTW, why are there fixed value, if it works variable also?

osdimage: just a few fixes so the plugin compiles porperly

SourceCaps: little fixes ... otherwise you will get SegFaults

RO: just one little fix

timer-info: Shows if a recoring is possible considering disc-space (see README.timer-info)

I hope everything works as expected.

Bye,
Andreas Brugger
diff -Nru femon-0.1.6_orig/femonosd.c femon-0.1.6/femonosd.c
--- femon-0.1.6_orig/femonosd.c	2004-09-11 03:20:00.000000000 +0200
+++ femon-0.1.6/femonosd.c	2005-01-10 17:33:09.000000000 +0100
@@ -32,11 +32,11 @@
 #define CHANNELINPUT_TIMEOUT     1000
 
 #ifdef NTSC_SYSTEM
-#define OSDHEIGHT                420 // in pixels
+#define OSDHEIGHT                Setup.OSDHeight // in pixels
 #else
-#define OSDHEIGHT                480 // in pixels
+#define OSDHEIGHT                Setup.OSDHeight // in pixels
 #endif
-#define OSDWIDTH                 600 // in pixels
+#define OSDWIDTH                 Setup.OSDWidth // in pixels
 #define OSDINFOHEIGHT            (m_Font->Height() * 11) // in pixels (11 rows)
 #define OSDSTATUSHEIGHT          (m_Font->Height() * 6)  // in pixels (6 rows)
 
@@ -149,9 +149,14 @@
            if (y < 0) y = 0;
            m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmDevice3, clrBlack, clrWhite);
            }
-        value = -1;
-        const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&value);
-        if (AudioTracks) {
+        //value = -1;
+		  
+		  // dirty audio-fix
+		  value = cDevice::PrimaryDevice()->GetCurrentAudioTrack() - ttAudioFirst;
+		  
+		  // original functionality
+        /*const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&value);
+        if (AudioTracks) { */
            if (value == 0) {
               x -= bmApid1.Width() + SPACING;
               y = (m_Font->Height() - bmApid1.Height()) / 2;
@@ -164,7 +169,7 @@
               if (y < 0) y = 0;
               m_Osd->DrawBitmap(x, OSDSTATUSWIN_Y(offset+y), bmApid2, clrBlack, clrWhite);
               }
-           }
+        //   }
         value = m_Receiver->VideoFormat();
         if (value == VF_PAL) {
            x -= bmPAL.Width() + SPACING;
@@ -309,14 +314,14 @@
         m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
         offset += m_Font->Height();
         m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Apid1"), clrWhite, clrBackground, m_Font);
-        value = channel->Apid2();
-        if (value) snprintf(buf, sizeof(buf), "%d, %d", channel->Apid1(), value);
-        else       snprintf(buf, sizeof(buf), "%d", channel->Apid1());
+        value = channel->Apid(1);
+        if (value) snprintf(buf, sizeof(buf), "%d, %d", channel->Apid(0), value);
+        else       snprintf(buf, sizeof(buf), "%d", channel->Apid(0));
         m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
         m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Dpid1"), clrWhite, clrBackground, m_Font);
-        value = channel->Dpid2();
-        if (value) snprintf(buf, sizeof(buf), "%d, %d", channel->Dpid1(), value);
-        else       snprintf(buf, sizeof(buf), "%d", channel->Dpid1());
+        value = channel->Dpid(1);
+        if (value) snprintf(buf, sizeof(buf), "%d, %d", channel->Dpid(0), value);
+        else       snprintf(buf, sizeof(buf), "%d", channel->Dpid(0));
         m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
         offset += m_Font->Height();
         m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("CA"), clrWhite, clrBackground, m_Font);
@@ -419,7 +424,7 @@
                snprintf(buf, sizeof(buf), "%d %s", value, tr("MHz"));
                m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
                m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Source"), clrWhite, clrBackground, m_Font);
-               snprintf(buf, sizeof(buf), "%s", cSource::ToString(channel->Source()));
+               snprintf(buf, sizeof(buf), "%s", *cSource::ToString(channel->Source()));
                m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
                offset += m_Font->Height();
                m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Srate"), clrWhite, clrBackground, m_Font);
@@ -460,7 +465,7 @@
                snprintf(buf, sizeof(buf), "%d %s", value, tr("MHz"));
                m_Osd->DrawText(OSDINFOWIN_X(2), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
                m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), tr("Source"), clrWhite, clrBackground, m_Font);
-               snprintf(buf, sizeof(buf), "%s", cSource::ToString(channel->Source()));
+               snprintf(buf, sizeof(buf), "%s", *cSource::ToString(channel->Source()));
                m_Osd->DrawText(OSDINFOWIN_X(4), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
                offset += m_Font->Height();
                m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Srate"), clrWhite, clrBackground, m_Font);
@@ -631,8 +636,13 @@
         offset += m_Font->Height();
         m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Audio Stream"), clrYellow, clrBackground, m_Font);
         value = -1;
-        cDevice::PrimaryDevice()->GetAudioTracks(&value);
-        snprintf(buf, sizeof(buf), "#%d", (value > 0 ? channel->Apid2() : channel->Apid1()));
+ 
+		  // dirty audio-fix
+		  value = cDevice::PrimaryDevice()->GetCurrentAudioTrack() - ttAudioFirst;
+		  
+		  // original functionality
+		  //cDevice::PrimaryDevice()->GetAudioTracks(&value);
+        snprintf(buf, sizeof(buf), "#%d", (value > 0 ? channel->Apid(1) : channel->Apid(0)));
         m_Osd->DrawText(OSDINFOWIN_X(3), OSDINFOWIN_Y(offset), buf, clrYellow, clrBackground, m_Font);
         offset += m_Font->Height();
         m_Osd->DrawText(OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), tr("Bitrate"), clrWhite, clrBackground, m_Font);
@@ -663,7 +673,7 @@
      else if (m_DisplayMode == modeAC3) {
         m_Osd->DrawRectangle(0, OSDINFOWIN_Y(0), OSDWIDTH, OSDINFOWIN_Y(OSDINFOHEIGHT), clrBackground);
         m_Osd->DrawRectangle(0, OSDINFOWIN_Y(offset), OSDWIDTH, OSDINFOWIN_Y(offset+m_Font->Height()-1), clrWhite);
-        snprintf(buf, sizeof(buf), "%s - %s #%d", tr("Stream Information"), tr("AC-3 Stream"), channel->Dpid1());
+        snprintf(buf, sizeof(buf), "%s - %s #%d", tr("Stream Information"), tr("AC-3 Stream"), channel->Dpid(0));
         m_Osd->DrawText( OSDINFOWIN_X(1), OSDINFOWIN_Y(offset), buf, clrBackground, clrWhite, m_Font);
         offset += m_Font->Height();
         if (m_Receiver && m_Receiver->AC3Valid()) {
@@ -816,7 +826,7 @@
         delete m_Receiver;
      if (femonConfig.analyzestream) {
         cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
-        m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), channel->Apid1(), channel->Dpid1());
+        m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), channel->Apid(0), channel->Dpid(0));
         cDevice::ActualDevice()->AttachReceiver(m_Receiver);
         }
      Start();
@@ -848,7 +858,7 @@
      delete m_Receiver;
   if (femonConfig.analyzestream) {
      cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
-     m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), channel->Apid1(), channel->Dpid1());
+     m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), channel->Apid(0), channel->Dpid(0));
      cDevice::ActualDevice()->AttachReceiver(m_Receiver);
      }
 }
@@ -872,7 +882,7 @@
                if (m_Number > 0) {
                   DrawStatusWindow();
                   cChannel *ch = Channels.GetByNumber(m_Number);
-                  m_InputTime = time_ms();
+                  m_InputTime = cTimeMs::Now();
                   // Lets see if there can be any useful further input:
                   int n = ch ? m_Number * 10 : 0;
                   while (ch && (ch = Channels.Next(ch)) != NULL) {
@@ -897,7 +907,7 @@
        case kBack:
             return osEnd;
        case kGreen:
-            {
+            /*{
             int CurrentAudioTrack = -1;
             const char **AudioTracks = cDevice::PrimaryDevice()->GetAudioTracks(&CurrentAudioTrack);
             if (AudioTracks) {
@@ -909,11 +919,11 @@
                   cChannel *channel = Channels.GetByNumber(cDevice::CurrentChannel());
                   if (m_Receiver)
                      delete m_Receiver;
-                  m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), (at - AudioTracks) ? channel->Apid2() : channel->Apid1(), channel->Dpid1());
+                  m_Receiver = new cFemonReceiver(channel->Ca(), channel->Vpid(), (at - AudioTracks) ? channel->Apid(1) : channel->Apid(0), channel->Dpid(0));
                   cDevice::ActualDevice()->AttachReceiver(m_Receiver);
                   }
                }
-            }
+            }*/
             break;
        case kRight:
        case kLeft:
@@ -948,21 +958,21 @@
             m_Number = 0;
             break;
        case kNone:
-            if (m_Number && (time_ms() - m_InputTime > CHANNELINPUT_TIMEOUT)) {
+            if (m_Number && (cTimeMs::Now() - m_InputTime > CHANNELINPUT_TIMEOUT)) {
                if (Channels.GetByNumber(m_Number)) {
                   m_OldNumber = cDevice::CurrentChannel();
                   Channels.SwitchTo(m_Number);
                   m_Number = 0;
                   }
                else {
-                  m_InputTime = time_ms();
+                  m_InputTime = cTimeMs::Now();
                   m_Number = 0;
                   }
                }
             break;
        case kOk:
             // toggle between display modes
-            if (++m_DisplayMode == modeAC3 && !Channels.GetByNumber(cDevice::CurrentChannel())->Dpid1()) m_DisplayMode++;
+            if (++m_DisplayMode == modeAC3 && !Channels.GetByNumber(cDevice::CurrentChannel())->Dpid(0)) m_DisplayMode++;
             if (m_DisplayMode >= modeMaxNumber) m_DisplayMode = 0;
             DrawInfoWindow();
             break;
diff -Nru osdimage-0.1.2_orig/bitmap.c osdimage-0.1.2/bitmap.c
--- osdimage-0.1.2_orig/bitmap.c	2004-11-02 10:07:52.000000000 +0100
+++ osdimage-0.1.2/bitmap.c	2005-01-09 16:01:19.000000000 +0100
@@ -74,7 +74,7 @@
 	int h = Height();
 	int wNew, hNew;
 #ifdef DEBUG
-	int time = time_ms(), dt;
+	int time = cTimeMs::Now(), dt;
 #endif
 
 	
@@ -109,7 +109,7 @@
 		}
 
 #ifdef DEBUG
-	dt = time_ms() - time;
+	dt = cTimeMs::Now() - time;
 	printf("\t- Resizing & quantization (using %s): %dms\n", quantizer == 0 ? "ImageMagick" : "Netpbm", dt);
 #endif
 
diff -Nru osdimage-0.1.2_orig/menu.c osdimage-0.1.2/menu.c
--- osdimage-0.1.2_orig/menu.c	2004-11-02 10:22:07.000000000 +0100
+++ osdimage-0.1.2/menu.c	2005-01-09 16:04:29.000000000 +0100
@@ -169,8 +169,9 @@
 	FILE *p;
 	char buf[256];
 	bool ret;
+	cReadLine reader;
 #ifdef DEBUG
-	int time = time_ms(), dt;
+	int time = cTimeMs::Now(), dt;
 #endif
 				
 	
@@ -200,7 +201,7 @@
 
 		if (p)
 		{
-			while ( (line = readline(p) ) !=  NULL)
+			while ( (line = reader.Read(p) ) !=  NULL)
 			{
 				if (strcmp(line, myPics->CurPath() ) > 0)
 				{
@@ -246,7 +247,7 @@
 
 	if (p)
 	{
-		while ( (line = readline(p) ) !=  NULL)
+		while ( (line = reader.Read(p) ) !=  NULL)
 		{
 			strcpy(buf, line + strlen(myPics->CurPath() ) + 1);
 			myPics->files.push_back(buf);
@@ -263,7 +264,7 @@
 	}
 
 #ifdef DEBUG
-	dt = time_ms() - time;
+	dt = cTimeMs::Now() - time;
 	printf("Generating file-list & sorting it: %dms\n", dt);
 #endif
 
diff -Nru osdimage-0.1.2_orig/viewer.c osdimage-0.1.2/viewer.c
--- osdimage-0.1.2_orig/viewer.c	2004-11-28 20:01:27.000000000 +0100
+++ osdimage-0.1.2/viewer.c	2005-01-09 16:01:19.000000000 +0100
@@ -249,7 +249,7 @@
 				break;
 			case kBlue:
 				slideShow = !slideShow;
-				slideShowTime = time_ms();
+				slideShowTime = cTimeMs::Now();
 				break;
 			case kBack:
 				slideShow = false;
@@ -261,7 +261,7 @@
 			case kNone:
 				if (slideShow)
 				{
-					slideShowDelta = (time_ms() - slideShowTime) / 1000; // [ms]->[s]
+					slideShowDelta = (cTimeMs::Now() - slideShowTime) / 1000; // [ms]->[s]
 
 					if (slideShowDelta >= OSDImageSetup.slideShowDelay)
 					{
@@ -272,7 +272,7 @@
 							ViewInfo(tr("Loading") );
 							Load();
 
-							slideShowTime = time_ms();
+							slideShowTime = cTimeMs::Now();
 							break;
 						}
 						else
@@ -311,7 +311,7 @@
 void cOSDImageViewer::Load(void)
 {
 #ifdef DEBUG
-	int time = time_ms(), dt;
+	int time = cTimeMs::Now(), dt;
 #endif
 
 
@@ -319,7 +319,7 @@
 	image.Load(myPics->CurPicPath() );
 
 #ifdef DEBUG
-	dt = time_ms() - time;
+	dt = cTimeMs::Now() - time;
 	printf("Viewing picture %d/%d: '%s'\n", myPics->curPic + 1, myPics->Size(), myPics->CurPicPath() );
 	printf("\t- Loading: %dms\n", dt);
 #endif
diff -Nru vdr-1.3.18_plain/config.c vdr-1.3.18_patched/config.c
--- vdr-1.3.18_plain/config.c	2005-01-09 13:14:58.000000000 +0100
+++ vdr-1.3.18_patched/config.c	2005-01-09 23:59:29.000000000 +0100
@@ -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
@@ -296,6 +297,7 @@
   MultiSpeedMode = 0;
   ShowReplayMode = 0;
   ResumeID = 0;
+  memset(SourceCaps, sizeof(SourceCaps), 0);
   CurrentChannel = -1;
   CurrentVolume = MAXVOLUME;
   CurrentDolby = 0;
@@ -362,6 +364,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];
@@ -451,6 +501,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);
@@ -513,6 +564,7 @@
   Store("MultiSpeedMode",     MultiSpeedMode);
   Store("ShowReplayMode",     ShowReplayMode);
   Store("ResumeID",           ResumeID);
+  StoreSourceCaps("SourceCaps");
   Store("CurrentChannel",     CurrentChannel);
   Store("CurrentVolume",      CurrentVolume);
   Store("CurrentDolby",       CurrentDolby);
diff -Nru vdr-1.3.18_plain/config.h vdr-1.3.18_patched/config.h
--- vdr-1.3.18_plain/config.h	2005-01-09 13:14:33.000000000 +0100
+++ vdr-1.3.18_patched/config.h	2005-01-09 23:58:31.000000000 +0100
@@ -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);
@@ -250,6 +252,7 @@
   int MultiSpeedMode;
   int ShowReplayMode;
   int ResumeID;
+  int SourceCaps[MAXDEVICES][MAXSOURCECAPS];
   int CurrentChannel;
   int CurrentVolume;
   int CurrentDolby;
diff -Nru vdr-1.3.18_plain/device.c vdr-1.3.18_patched/device.c
--- vdr-1.3.18_plain/device.c	2005-01-09 13:36:48.000000000 +0100
+++ vdr-1.3.18_patched/device.c	2005-01-09 23:58:31.000000000 +0100
@@ -141,8 +141,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!");
 }
@@ -279,6 +281,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)
 {
   for (int i = 0; i < numDevices; i++) {
diff -Nru vdr-1.3.18_plain/device.h vdr-1.3.18_patched/device.h
--- vdr-1.3.18_plain/device.h	2005-01-07 15:57:01.000000000 +0100
+++ vdr-1.3.18_patched/device.h	2005-01-09 23:58:31.000000000 +0100
@@ -22,6 +22,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      16 // the maximum number of different PIDs per device
 #define MAXRECEIVERS       16 // the maximum number of receivers per device
 #define MAXVOLUME         255
@@ -124,6 +125,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.
@@ -131,6 +135,8 @@
   static int nextCardIndex;
   int cardIndex;
 protected:
+  int sourceCaps[MAXSOURCECAPS];
+protected:
   cDevice(void);
   virtual ~cDevice();
   static int NextCardIndex(int n = 0);
diff -Nru vdr-1.3.18_plain/dvbdevice.c vdr-1.3.18_patched/dvbdevice.c
--- vdr-1.3.18_plain/dvbdevice.c	2005-01-09 14:04:20.000000000 +0100
+++ vdr-1.3.18_patched/dvbdevice.c	2005-01-09 23:58:31.000000000 +0100
@@ -706,9 +706,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 -Nru vdr-1.3.18_plain/sources.c vdr-1.3.18_patched/sources.c
--- vdr-1.3.18_plain/sources.c	2004-12-26 12:58:52.000000000 +0100
+++ vdr-1.3.18_patched/sources.c	2005-01-09 23:58:31.000000000 +0100
@@ -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';
diff -ub vdr-1.1.27.orig/recording.c vdr-1.1.27/recording.c
--- vdr-1.1.27.orig/recording.c	Sat Apr 12 11:51:44 2003
+++ vdr-1.1.27/recording.c	Tue Apr 15 12:59:20 2003
@@ -43,6 +43,7 @@
 // end of implementation for brain dead systems
 
 #define RESUMEFILESUFFIX  "/resume%s%s.vdr"
+#define CDCACHEPREFIX	  "/tmp/cache.vdr"
 #define SUMMARYFILESUFFIX "/summary.vdr"
 #define MARKSFILESUFFIX   "/marks.vdr"
 
@@ -151,6 +152,29 @@
 
 cResumeFile::cResumeFile(const char *FileName)
 {
+  char fn[1024];
+  int  f, l;
+
+  sprintf(fn, "%s/testfile", FileName);
+
+  f = open(fn, O_WRONLY | O_CREAT);
+  isReadOnly = ((f < 0) && (errno == EROFS));
+
+  if (isReadOnly) {
+    fileName = MALLOC(char, strlen(FileName) + strlen(RESUMEFILESUFFIX) + strlen(CDCACHEPREFIX) + 1);
+    if (fileName) {
+      l = sprintf(fileName, "%s/%s", CDCACHEPREFIX, FileName);
+      sprintf(fileName + l, RESUMEFILESUFFIX, Setup.ResumeID ? "." : "", Setup.ResumeID ? *itoa(Setup.ResumeID) : "");
+      MakeDirs(fileName, false);
+    }
+    else
+      esyslog("ERROR: can't allocate memory for resume file name");
+
+  }
+  else {
+    close(f);
+    unlink(fn);
+
   fileName = MALLOC(char, strlen(FileName) + strlen(RESUMEFILESUFFIX) + 1);
   if (fileName) {
      strcpy(fileName, FileName);
@@ -158,6 +182,7 @@
      }
   else
      esyslog("ERROR: can't allocate memory for resume file name");
+  }
 }
 
 cResumeFile::~cResumeFile()
diff -ub vdr-1.1.27.orig/recording.h vdr-1.1.27/recording.h
--- vdr-1.1.27.orig/recording.h	Sat Oct 19 17:48:52 2002
+++ vdr-1.1.27/recording.h	Tue Apr 15 12:24:05 2003
@@ -21,6 +21,7 @@
 class cResumeFile {
 private:
   char *fileName;
+  bool  isReadOnly;
 public:
   cResumeFile(const char *FileName);
   ~cResumeFile();
diff -Nru vdr-1.3.18_plain/README.timer-info vdr-1.3.18_patched/README.timer-info
--- vdr-1.3.18_plain/README.timer-info	1970-01-01 01:00:00.000000000 +0100
+++ vdr-1.3.18_patched/README.timer-info	2005-01-11 19:56:30.000000000 +0100
@@ -0,0 +1,31 @@
++------------------------------------------------------------------------------+
+|               Info about the timer-info-patch by Brougs78                    |
+|                brougs78@gmx.net / home.pages.at/brougs78                     |
++------------------------------------------------------------------------------+
+
+
+README timer-info:
+------------------
+
+Features:
+ - Shows info, if it is possible to record an event in the timer-info of vdr.
+   For calculations the free space incl. the deleted recordings is used, 
+	considering an average consumtion of 25.75 MB/min (also used by vdr itself).
+	The first column int the timer-list shows:
+	 ( + ) recording will be most probably possible (enough space)
+	 (+/-) recording may be possible
+	 ( - ) recording will most probably fail (to less space)
+	The calculations also consider repeating timers.
+
+	
+HISTORY timer-info:
+-------------------
+
+25.11.2004: v0.1
+ - Initial release
+
+11.01.2005: v0.1b
+ - Bugfixes for vdr-1.3.18
+ - In the menu the free recording-time no longer includes the space of the
+   deleted recordings, because this slowed the vdr down to much.
+	
diff -Nru vdr-1.3.18_plain/menu.c vdr-1.3.18_patched/menu.c
--- vdr-1.3.18_plain/menu.c	2005-01-09 14:04:49.000000000 +0100
+++ vdr-1.3.18_patched/menu.c	2005-01-11 19:57:40.000000000 +0100
@@ -33,6 +33,7 @@
 #define MENUTIMEOUT     120 // seconds
 #define MAXWAIT4EPGINFO   3 // seconds
 #define MODETIMEOUT       3 // seconds
+#define MB_PER_MINUTE 25.75 // this is just an estimate!
 
 #define MAXRECORDCONTROLS (MAXDEVICES * MAXRECEIVERS)
 #define MAXINSTANTRECTIME (24 * 60 - 1) // 23:59 hours
@@ -713,16 +714,19 @@
 class cMenuTimerItem : public cOsdItem {
 private:
   cTimer *timer;
+  char diskStatus;
 public:
-  cMenuTimerItem(cTimer *Timer);
+  cMenuTimerItem(cTimer *Timer, char DiskStatus = ' ');
+  void SetDiskStatus(char DiskStatus);
   virtual int Compare(const cListObject &ListObject) const;
   virtual void Set(void);
   cTimer *Timer(void) { return timer; }
   };
 
-cMenuTimerItem::cMenuTimerItem(cTimer *Timer)
+cMenuTimerItem::cMenuTimerItem(cTimer *Timer, char DiskStatus)
 {
   timer = Timer;
+  diskStatus = DiskStatus;
   Set();
 }
 
@@ -734,7 +738,8 @@
 void cMenuTimerItem::Set(void)
 {
   char *buffer = NULL;
-  asprintf(&buffer, "%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
+  asprintf(&buffer, "%c%c\t%d\t%s%s%s\t%02d:%02d\t%02d:%02d\t%s",
+  						  diskStatus,
                     !(timer->HasFlags(tfActive)) ? ' ' : timer->FirstDay() ? '!' : timer->Recording() ? '#' : '>',
                     timer->Channel()->Number(),
                     timer->IsSingleEvent() ? *WeekDayName(timer->StartTime()) : "",
@@ -748,6 +753,11 @@
   SetText(buffer, false);
 }
 
+void cMenuTimerItem::SetDiskStatus(char DiskStatus)
+{
+	diskStatus = DiskStatus;
+}
+
 // --- cMenuTimers -----------------------------------------------------------
 
 class cMenuTimers : public cOsdMenu {
@@ -759,6 +769,7 @@
   virtual void Move(int From, int To);
   eOSState Summary(void);
   cTimer *CurrentTimer(void);
+  void ActualiseDiskStatus(void);
 public:
   cMenuTimers(void);
   virtual ~cMenuTimers();
@@ -766,7 +777,7 @@
   };
 
 cMenuTimers::cMenuTimers(void)
-:cOsdMenu(tr("Timers"), 2, CHNUMWIDTH, 10, 6, 6)
+:cOsdMenu(tr("Timers"), 3, CHNUMWIDTH, 10, 6, 6)
 {
   for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer))
       Add(new cMenuTimerItem(timer));
@@ -774,6 +785,169 @@
      Sort();
   SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? tr("On/Off") : tr("Mark"));
   Timers.IncBeingEdited();
+  ActualiseDiskStatus();
+}
+
+struct sListEntry
+{
+  int key;
+  bool active;
+  time_t startTime;
+  int priority;
+  int duration;
+  bool repTimer;
+  bool isDummy;
+};
+
+static int CompareListEntry(const void *a, const void *b)
+{
+  int r = ( (sListEntry *)a)->startTime - ( (sListEntry *)b)->startTime;
+  
+  if (r == 0)
+  {
+	  r = ( (sListEntry *)b)->priority - ( (sListEntry *)a)->priority;
+  }
+  
+  return r;
+}
+
+void cMenuTimers::ActualiseDiskStatus(void)
+{
+  int nTimers = Timers.Count();
+  
+  if (!nTimers) return;
+  
+  int freeMB, freeMinutes, runshortMinutes;
+  cTimer *timer, *timerTmp;
+  int duration;
+  int nList = nTimers;
+  int nRepTimers = 0, nDays = 0;
+  time_t firstStart, latestStart = 0;
+  char status;
+  sListEntry *list = (sListEntry *)malloc(nList * sizeof(sListEntry) );
+  cMenuTimerItem *item = NULL;
+  
+  
+  VideoDiskSpaceIncDel(&freeMB);
+  freeMinutes = int(double(freeMB) * 1.1 / MB_PER_MINUTE); // overestimate by 10 percent
+  runshortMinutes = freeMinutes / 5; // 20 Percent
+  
+  // generate sorted timer-list
+  timer = Timers.First();
+  firstStart = timer->StartTime();
+  
+  for (int i = 0; i < nTimers; i++)
+  {
+	  duration = (timer->Stop()  / 100 * 60 + timer->Stop()  % 100)
+				  - (timer->Start() / 100 * 60 + timer->Start() % 100);
+	  if (duration < 0) duration += 24 * 60; 
+		  
+	  list[i].key = i;
+	  list[i].active = timer->HasFlags(tfActive);
+	  list[i].startTime = timer->StartTime();	  
+	  list[i].priority = timer->Priority();
+	  list[i].duration = duration;
+	  list[i].repTimer = !timer->IsSingleEvent();
+	  list[i].isDummy = false;
+	  
+	  if (list[i].repTimer && list[i].active) nRepTimers++;
+	  
+	  latestStart = max(list[i].startTime, latestStart);
+	  firstStart = min(list[i].startTime, firstStart);
+	  
+	  timer = Timers.Next(timer);
+  }
+  
+  nDays = (latestStart - firstStart) / (3600 * 24) + 1;
+  
+  // add the repeating dummy-timers (if there are any)
+  if (nRepTimers)
+  {
+	  // reallocate more space (estimated)
+	  list = (sListEntry *)realloc(list, (nList + nDays * nRepTimers) * sizeof(sListEntry) );
+	  
+	  for (int i = 0; i < nTimers; i++)
+	  {
+		  if (list[i].repTimer)
+		  {
+			  cTimer timerDummy;
+			  timerDummy = *(Timers.Get(list[i].key) );
+			  
+			  for (int j = 0; j < nDays; j++)
+			  {
+				  timerDummy.Skip();
+				  timerDummy.Matches(); // Actualise the timer
+
+				  if ( *(*timerDummy.PrintDay((timerDummy.Day() ), 0) + j) != '-')
+				  {
+					  if (timerDummy.StartTime() > latestStart) break;
+					  
+					  list[nList].key = 0;
+					  list[nList].active = true;
+					  list[nList].startTime = timerDummy.StartTime();	  
+					  list[nList].priority = list[i].priority;
+					  list[nList].duration = list[i].duration;
+					  list[nList].repTimer = true;
+					  list[nList].isDummy = true;	
+					  
+					  nList++;
+				  }
+			  }
+		  }
+	  }
+  }
+  
+  qsort(list, nList, sizeof(sListEntry), *CompareListEntry); 
+  
+  // set the disk-status
+  for (int i = 0; i < nList; i++)
+  {
+	  // Debugging-info:
+	  /* printf("timer %d:\t%d | %s | %s | %d -> %d\n",
+		  i + 1,
+		  list[i].startTime,
+		  list[i].active ? "aktiv " : "n.akt.",
+		  list[i].repTimer ? list[i].isDummy ? "  dummy  " : "mehrmalig" : "einmalig ",
+		  list[i].duration,
+		  freeMinutes); */
+	  
+	  if (list[i].active)
+	  {
+		  freeMinutes -= list[i].duration;
+	  
+		  status = freeMinutes > runshortMinutes ? '+' : freeMinutes > 0 ? 177 /* +/- */ : '-';
+	  }
+	  else
+	  {
+		  status = ' ';
+	  }
+	  
+	  // search corresponding timer in timer-list
+	  if (!list[i].isDummy)
+	  {
+		  timer = Timers.Get(list[i].key);
+
+		  for (int j = 0; j < nTimers; j++)
+		  {
+			  item = (cMenuTimerItem *)Get(j);
+			  
+			  if (item)
+			  {
+				  timerTmp = item->Timer();
+				  
+				  if (timer == timerTmp)
+				  {
+					  item->SetDiskStatus(status);
+					  item->Set();
+					  break;
+				  }
+			  }
+		  }
+	  }
+  }
+  
+  free(list);
+  Display();
 }
 
 cMenuTimers::~cMenuTimers()
@@ -865,6 +1039,7 @@
 
 eOSState cMenuTimers::ProcessKey(eKeys Key)
 {
+  static bool actualiseDiskStatus = false;
   int TimerNumber = HasSubMenu() ? Count() : -1;
   eOSState state = cOsdMenu::ProcessKey(Key);
 
@@ -873,20 +1048,30 @@
        case kOk:     return Summary();
        case kRed:    return Edit();
        case kGreen:  return New();
-       case kYellow: return Delete();
+       case kYellow: { actualiseDiskStatus = true; return Delete(); }
        case kBlue:   if (Setup.SortTimers)
-                        OnOff();
+		 						{ actualiseDiskStatus = true; OnOff(); }
                      else
                         Mark();
                      break;
        default: break;
        }
      }
+
   if (TimerNumber >= 0 && !HasSubMenu() && Timers.Get(TimerNumber)) {
      // a newly created timer was confirmed with Ok
      Add(new cMenuTimerItem(Timers.Get(TimerNumber)), true);
      Display();
      }
+  
+  if (TimerNumber >= 0 && !HasSubMenu() ) ActualiseDiskStatus();
+	  
+  if (actualiseDiskStatus)
+  {
+	  ActualiseDiskStatus();
+	  actualiseDiskStatus = false;
+  }
+  
   return state;
 }
 
@@ -2384,15 +2569,14 @@
   SetHasHotkeys();
 
   // Title with disk usage:
-
-#define MB_PER_MINUTE 25.75 // this is just an estimate!
-
+  // incl. size of deleted recordings (thanks to Torsten/WarEagle and Hardy/HFlor)
   char buffer[40];
   int FreeMB;
-  int Percent = VideoDiskSpace(&FreeMB);
+  int Percent = VideoDiskSpaceIncDel(&FreeMB);
   int Minutes = int(double(FreeMB) / MB_PER_MINUTE);
   int Hours = Minutes / 60;
   Minutes %= 60;
+  
   snprintf(buffer, sizeof(buffer), "%s  -  %s %d%%  -  %2d:%02d %s", tr("VDR"), tr("Disk"), Percent, Hours, Minutes, tr("free"));
   //XXX -> skin function!!!
   SetTitle(buffer);
diff -Nru vdr-1.3.18_plain/recording.c vdr-1.3.18_patched/recording.c
--- vdr-1.3.18_plain/recording.c	2004-12-26 12:55:24.000000000 +0100
+++ vdr-1.3.18_patched/recording.c	2005-01-11 20:00:57.000000000 +0100
@@ -616,6 +616,31 @@
   return RemoveVideoFile(FileName());
 }
 
+bool cRecording::GetSizeCount(long long *lSize, int *Count)
+{
+   bool bRet=false;
+   struct stat fileinfo;             /* Holds file information structure */
+   char *cmd = NULL;
+	cReadLine reader;
+   asprintf(&cmd, "find '%s' -follow -type f -name '*.*'|sort ", FileName());
+
+   FILE *p = popen(cmd, "r");
+   int ret=0;
+   if (p) {
+      char *s;
+      while ((s = reader.Read(p)) != NULL) {
+         if ((ret=stat(s, &fileinfo)) != -1) {
+            (*lSize)+=(long long)fileinfo.st_size;
+            (*Count)++;
+            }
+      }
+      bRet=true;
+   }
+   pclose(p);
+   delete cmd;
+   return bRet;
+}
+
 // --- cRecordings -----------------------------------------------------------
 
 cRecordings Recordings;
diff -Nru vdr-1.3.18_plain/recording.h vdr-1.3.18_patched/recording.h
--- vdr-1.3.18_plain/recording.h	2004-12-26 12:47:35.000000000 +0100
+++ vdr-1.3.18_patched/recording.h	2005-01-11 19:53:34.000000000 +0100
@@ -66,6 +66,9 @@
   bool Remove(void);
        // Actually removes the file from the disk
        // Returns false in case of error
+  bool GetSizeCount(long long *lSize, int *Count);
+       // Adds the number of files found in the dir to Count and their size to lSize
+       // Returns false in case of error
   };
 
 class cRecordings : public cList<cRecording> {
diff -Nru vdr-1.3.18_plain/videodir.c vdr-1.3.18_patched/videodir.c
--- vdr-1.3.18_plain/videodir.c	2004-12-26 12:52:12.000000000 +0100
+++ vdr-1.3.18_patched/videodir.c	2005-01-11 19:57:16.000000000 +0100
@@ -17,6 +17,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 #include "tools.h"
+#include "recording.h"
 
 const char *VideoDirectory = VIDEODIR;
 
@@ -197,6 +198,30 @@
   return (free + used) ? used * 100 / (free + used) : 0;
 }
 
+int VideoDiskSpaceIncDel(int *FreeMB, int *UsedMB)
+{
+  int free = 0, used = 0;
+  long long lSize = 0;
+  int countFiles = 0;
+  cRecordings recordings(true);
+  recordings.Load();
+  for (cRecording *rec = recordings.First();  rec; rec = recordings.Next(rec))
+  rec->GetSizeCount(&lSize, &countFiles);
+  recordings.Clear();
+  
+  VideoDiskSpace(&free, &used);
+  
+  int tmp = lSize / (1024 * 1024);
+  free += tmp;
+  used -= tmp;
+
+  if (FreeMB)
+     *FreeMB = free;
+  if (UsedMB)
+     *UsedMB = used;
+  return (free + used) ? used * 100 / (free + used) : 0;
+}
+
 cString PrefixVideoFileName(const char *FileName, char Prefix)
 {
   char PrefixedName[strlen(FileName) + 2];
diff -Nru vdr-1.3.18_plain/videodir.h vdr-1.3.18_patched/videodir.h
--- vdr-1.3.18_plain/videodir.h	2004-12-26 12:52:56.000000000 +0100
+++ vdr-1.3.18_patched/videodir.h	2005-01-11 19:57:59.000000000 +0100
@@ -21,6 +21,7 @@
 bool RemoveVideoFile(const char *FileName);
 bool VideoFileSpaceAvailable(int SizeMB);
 int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent
+int VideoDiskSpaceIncDel(int *FreeMB = NULL, int *UsedMB = NULL); // same as above but calculations include the deleted recordings
 cString PrefixVideoFileName(const char *FileName, char Prefix);
 void RemoveEmptyVideoDirectories(void);
 

Home | Main Index | Thread Index