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