summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTORS12
-rw-r--r--HISTORY32
-rw-r--r--README.vps6
-rw-r--r--channels.conf26
-rw-r--r--config.c2
-rw-r--r--config.h6
-rw-r--r--device.h4
-rw-r--r--dvbdevice.c3
-rw-r--r--eit.c22
-rw-r--r--eitscan.c2
-rw-r--r--eitscan.h2
-rw-r--r--epg.c52
-rw-r--r--epg.h13
-rw-r--r--i18n.c28
-rw-r--r--libsi/descriptor.c156
-rw-r--r--libsi/descriptor.h27
-rw-r--r--libsi/si.c83
-rw-r--r--libsi/si.h63
-rw-r--r--menu.c32
-rw-r--r--menu.h2
-rw-r--r--menuitems.c2
-rw-r--r--menuitems.h2
-rw-r--r--osd.c36
-rw-r--r--pat.c18
-rw-r--r--pat.h7
-rw-r--r--recorder.c4
-rw-r--r--ringbuffer.c17
-rw-r--r--ringbuffer.h6
-rw-r--r--sdt.c27
-rw-r--r--svdrp.c2
-rw-r--r--timers.c42
-rw-r--r--timers.h2
-rw-r--r--transfer.c4
-rw-r--r--vdr.52
-rw-r--r--vdr.c16
35 files changed, 544 insertions, 216 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 438d827..1f72231 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -514,6 +514,8 @@ Oliver Endriss <o.endriss@gmx.de>
for suggesting to add 'repeat' function keys '7' and '9'
for fixing handling rc key learning in case cRemote::Initialize() returns 'false'
for suggesting to change the default "Lifetime" to 99
+ for pointing out that the LNB power needs to be explicitly turned on at startup,
+ because newer drivers don't do this any more
Reinhard Walter Buchner <rw.buchner@freenet.de>
for adding some satellites to 'sources.conf'
@@ -943,3 +945,13 @@ Thomas Bergwinkl <Thomas.Bergwinkl@t-online.de>
Stéphane Esté-Gracias <sestegra@free.fr>
for fixing a typo in libsi/si.h
+ for fixing some descriptor handling in 'libsi'
+ for pointing out a problem with "itemized" texts in EPG data
+ for pointing out a problem with taking the Sid into account when detecting version
+ changes in processing the PMT
+
+Marc Hoppe <MarcHoppe@gmx.de>
+ for fixing handling the current menu item
+
+Michael Pennewiß <M.Pennewiss@ARD-Digital.de>
+ for pointing out that an empty EPG event means there is currently no running event
diff --git a/HISTORY b/HISTORY
index e995005..1371dc9 100644
--- a/HISTORY
+++ b/HISTORY
@@ -2713,3 +2713,35 @@ Video Disk Recorder Revision History
whether an event has a VPS time that's different than its start time, and
whether an event is currently running (see MANUAL under "The "Schedule" Menu"
for details).
+
+2004-03-14: Version 1.3.6
+
+- Completed the Finnish OSD texts (thanks to Rolf Ahrenberg).
+- Fixed some descriptor handling in 'libsi' (thanks to Stéphane Esté-Gracias).
+- Fixed handling the current menu item (thanks to Marc Hoppe).
+- Fixed assigning events to timers (they no longer get "stuck").
+- Added log entries whenever the running status of an event changes (currently
+ only logging the first 30 channels).
+- Fixed handling timers in VPS margin if the EPG scan is turned on (the EPG scan
+ switched the device away from the channel, so it wouldn't see the change of
+ the running status).
+- Fixed handling "itemized" texts in EPG data (thanks to Stéphane Esté-Gracias
+ for pointing out this problem, and Marcel Wiesweg for improving 'libsi').
+- Fixed handling VPS times at year boundaries.
+- Avoiding too many consecutive "ring buffer overflow" messages (which only
+ slowed down performance even more).
+- Taking the Sid into account when detecting version changes in processing the
+ PMT (thanks to Stéphane Esté-Gracias for pointing out this problem).
+- Completed the Russian OSD texts (thanks to Vyacheslav Dikonov).
+- Any newline characters in the 'description' of EPG events are now preserved
+ to allow texts to be displayed the way the tv stations have formatted them.
+ This was also necessary to better display itemized texts.
+- Fixed detecting the running status in case an empty EPG event is broadcast (thanks
+ to Michael Pennewiß for pointing this out).
+- Improved performance when paging through very long menu lists.
+- Removed cSchedule::GetEventNumber() and cSchedule::NumEvents(). There is now
+ cSchedule::Events() that returns the list of events directly.
+- Avoiding occasional bad responsiveness to user interaction caused by assigning
+ events to timers.
+- Now explicitly turning on the LNB power at startup, because newer drivers don't
+ do this any more (thanks to Oliver Endriss for pointing this out).
diff --git a/README.vps b/README.vps
index 2aa19ce..d81f5d1 100644
--- a/README.vps
+++ b/README.vps
@@ -128,3 +128,9 @@ stations:
information to control recording would not see the end of that programme.
... more following as it comes up...
+
+Contact:
+--------
+
+ARD Digital: http://www.ard-digital.de/home/index.php?id=16&languageid=1
+ZDF vision: http://www.zdf.de/ZDFde/inhalt/1/0,1872,1021601,00.html (select "zdfvision")
diff --git a/channels.conf b/channels.conf
index f36c5f3..ca0b6fc 100644
--- a/channels.conf
+++ b/channels.conf
@@ -24,9 +24,10 @@ VOX:12187:hC34:S19.2E:27500:167:136=deu:71:0:12060:1:1089:0
KABEL1:12480:vC34:S19.2E:27500:511:512:33:0:899:133:33:0
NEUN LIVE,NEUN LIVE Television:12480:vC34:S19.2E:27500:767:768:35:0:897:133:33:0
DSF:12480:vC34:S19.2E:27500:1023:1024=deu:0:0:900:133:33:0
-HSEurope,Home Shopping Europe:12480:vC34:S19.2E:27500:1279:1280:37:0:40:133:33:0
+HSE24:12480:vC34:S19.2E:27500:1279:1280:37:0:40:133:33:0
Bloomberg TV Germany:12551:vC56:S19.2E:22000:162:99=deu:0:0:12160:1:1108:0
EURONEWS:11817:vC34:S19.2E:27500:163:92=fra,93=eng,94=ita,95=esl,91=rus,98=por,99=deu:0:0:8004:1:1070:0
+rbb Brandenburg:12109:hC34:S19.2E:27500:501:502=deu:504:0:28205:1:1073:0
Sky News Intl:11597:vC56:S19.2E:22000:305+131:306=eng:0:0:28707:1:1026:0
Veronica/FoxKids:12574:hC56:S19.2E:22000:518+8190:92=dut:38:622,602,100:5020:53:1109:0
BVN:12574:hC56:S19.2E:22000:515+8190:96=dut:36:0:5025:53:1109:0
@@ -38,20 +39,19 @@ Eurosport:11953:hC34:S19.2E:27500:410:420=deu:430:0:28009:1:1079:0
EinsExtra:12109:hC34:S19.2E:27500:101:102=deu:0:0:28201:1:1073:0
EinsFestival:12109:hC34:S19.2E:27500:201:202=deu:0:0:28202:1:1073:0
EinsMuXx:12109:hC34:S19.2E:27500:301:302=deu:0:0:28203:1:1073:0
-ZDFtheaterkanal:11953:hC34:S19.2E:27500:1110:1120:130:0:28016:1:1079:0
+ZDFtheaterkanal:11953:hC34:S19.2E:27500:1110:1120=deu:130:0:28016:1:1079:0
ZDFdokukanal:11953:hC34:S19.2E:27500:660:670=deu:130:0:28014:1:1079:0
MDR FERNSEHEN:12109:hC34:S19.2E:27500:401:402=deu:404:0:28204:1:1073:0
-RBB Brandenburg:12109:hC34:S19.2E:27500:501:502=deu:504:0:28205:1:1073:0
-RBB Berlin:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0
+rbb Berlin:12109:hC34:S19.2E:27500:601:602=deu:604:0:28206:1:1073:0
:Premiere World
-START,PREMIERE START:11797:hC34:S19.2E:27500:255:256=deu:32:1702,1722,1801:8:133:2:0
-PREM 1,PREMIERE 1:11797:hC34:S19.2E:27500:511:512=deu,513=deu;515=deu:0:1702,1722,1801:10:133:2:0
+START,PREMIERE START:11797:hC34:S19.2E:27500:255:256=deu:32:1722,1801,1702:8:133:2:0
+PREM 1,PREMIERE 1:11797:hC34:S19.2E:27500:511:512=deu;515=deu:0:1702,1801,1722:10:133:2:0
PREM 2,PREMIERE 2:11797:hC34:S19.2E:27500:1791:1792=deu,1793=deu;1795=deu:0:1702,1722,1801:11:133:2:0
-PREM 3,PREMIERE 3:11797:hC34:S19.2E:27500:2303:2304=deu:0:1702,1722,1801:43:133:2:0
-PREM 4,PREMIERE 4:11797:hC34:S19.2E:27500:767:768=deu:0:1702,1722,1801:9:133:2:0
-PREM 5,PREMIERE 5:11797:hC34:S19.2E:27500:1279:1280=deu,1281=deu:0:1702,1722,1801:29:133:2:0
-PREM 6,PREMIERE 6:11797:hC34:S19.2E:27500:1535:1536=deu:0:1702,1722,1801:41:133:2:0
-PREM 7,PREMIERE 7:11797:hC34:S19.2E:27500:1023:1024=deu:0:1702,1722,1801:20:133:2:0
+PREM 3,PREMIERE 3:11797:hC34:S19.2E:27500:2303:2304=deu:0:1722,1702,1801:43:133:2:0
+PREM 4,PREMIERE 4:11797:hC34:S19.2E:27500:767:768=deu:0:1801,1722,1702:9:133:2:0
+PREM 5,PREMIERE 5:11797:hC34:S19.2E:27500:1279:1280=deu:0:1801,1702,1722:29:133:2:0
+PREM 6,PREMIERE 6:11797:hC34:S19.2E:27500:1535:1536=deu:0:1722,1801,1702:41:133:2:0
+PREM 7,PREMIERE 7:11797:hC34:S19.2E:27500:1023:1024=deu:0:1722,1702,1801:20:133:2:0
DISNEY,DISNEY CHANNEL:11758:hC34:S19.2E:27500:2559:2560=deu:0:1702,1722,1801:34:133:17:0
:Premiere Direkt
DIREKT,PREMIERE DIREKT:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0:0:18:133:4:0
@@ -59,7 +59,7 @@ DIREKT,PREMIERE DIREKT:12031:hC34:S19.2E:27500:2815:2816=deu,2817=deu;2819=deu:0
B-UHSE,BEATE-UHSE.TV:12070:hC34:S19.2E:27500:1023:1024=deu:0:1702,1722,1801:21:133:1:0
EROTIK,PREMIERE EROTIK:12031:hC34:S19.2E:27500:1279:0:0:1702,1722,1801:513:133:4:0
:Sportsworld
-Konferenz:11719:hC34:S19.2E:27500:255:256=deu:0:1702,1722,1801:17:133:3:0
+SPORT 1,PREMIERE SPORT 1:11719:hC34:S19.2E:27500:255:256=deu,257=deu:0:1702,1722,1801:17:133:3:0
SPORT 2,PREMIERE SPORT 2:12031:hC34:S19.2E:27500:3839:3840=deu,3841=deu:0:1702,1722,1801:27:133:4:0
:Beta Digital
N24:12480:vC34:S19.2E:27500:2047:2048:36:0:47:133:33:0
@@ -114,6 +114,6 @@ Animal Plnt+:12070:hC23:S28.2E:27500:2315+2307:2316=eng:0:960,961:50002:2:2019:0
S1T:12285:vC23:S28.2E:27500:2311+2304:2312=eng,2313=NAR:2307:960,961:4409:2:2030:0
CNN:12051:vC23:S28.2E:27500:2309:2311=eng:2310:0:7140:2:2018:0
BBC PARL'MNT:12129:vC23:S28.2E:27500:2306:2308=eng,2309=eng:2307:0:7300:2:2022:0
-AL HAYAT:11200:vC56:S13.0E:27500:413:414:0:0:4733:318:13400:0
+AL HAYAT:11200:vC56:S13.0E:27500:413:414=eng:0:0:4733:318:13400:0
EURO1080:12168:vC34:S19.2E:27500:308:256:0:FF:21100:1:1088:0
:@1000 New channels
diff --git a/config.c b/config.c
index 6183eed..aaf376a 100644
--- a/config.c
+++ b/config.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.c 1.124 2004/02/21 15:05:40 kls Exp kls $
+ * $Id: config.c 1.125 2004/02/28 11:12:20 kls Exp $
*/
#include "config.h"
diff --git a/config.h b/config.h
index cc1edf2..d2afdee 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.188 2004/02/21 15:04:53 kls Exp kls $
+ * $Id: config.h 1.190 2004/03/05 14:35:15 kls Exp $
*/
#ifndef __CONFIG_H
@@ -20,8 +20,8 @@
#include "i18n.h"
#include "tools.h"
-#define VDRVERSION "1.3.5"
-#define VDRVERSNUM 10305 // Version * 10000 + Major * 100 + Minor
+#define VDRVERSION "1.3.6"
+#define VDRVERSNUM 10306 // Version * 10000 + Major * 100 + Minor
#define MAXPRIORITY 99
#define MAXLIFETIME 99
diff --git a/device.h b/device.h
index af6c85f..5815aca 100644
--- a/device.h
+++ b/device.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: device.h 1.40 2004/02/14 11:29:57 kls Exp $
+ * $Id: device.h 1.41 2004/03/14 10:47:01 kls Exp $
*/
#ifndef __DEVICE_H
@@ -382,7 +382,7 @@ public:
virtual int PlayVideo(const uchar *Data, int Length);
///< Actually plays the given data block as video. The data must be
///< part of a PES (Packetized Elementary Stream) which can contain
- ///< one video and one audio strem.
+ ///< one video and one audio stream.
virtual void PlayAudio(const uchar *Data, int Length);
///< Plays additional audio streams, like Dolby Digital.
///< A derived class must call the base class function to make sure data
diff --git a/dvbdevice.c b/dvbdevice.c
index 8ed62e1..6e1d7f9 100644
--- a/dvbdevice.c
+++ b/dvbdevice.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: dvbdevice.c 1.82 2004/02/24 10:12:13 kls Exp $
+ * $Id: dvbdevice.c 1.83 2004/03/14 14:47:46 kls Exp $
*/
#include "dvbdevice.h"
@@ -101,6 +101,7 @@ cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCi
useCa = false;
tunerStatus = tsIdle;
startTime = time(NULL);
+ CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); // must explicitly turn on LNB power
SetDescription("tuner on device %d", cardIndex + 1);
Start();
}
diff --git a/eit.c b/eit.c
index 85f051e..a426477 100644
--- a/eit.c
+++ b/eit.c
@@ -8,7 +8,7 @@
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
* Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg <marcel.wiesweg@gmx.de>.
*
- * $Id: eit.c 1.89 2004/02/22 13:17:52 kls Exp kls $
+ * $Id: eit.c 1.93 2004/03/13 13:54:20 kls Exp $
*/
#include "eit.h"
@@ -43,10 +43,12 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
Schedules->Add(pSchedule);
}
+ bool Empty = true;
bool Modified = false;
SI::EIT::Event SiEitEvent;
for (SI::Loop::Iterator it; eventLoop.hasNext(it); ) {
+ Empty = false;
SiEitEvent = eventLoop.getNext(it);
cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), SiEitEvent.getStartTime());
@@ -82,10 +84,6 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
pEvent->SetVersion(getVersionNumber());
pEvent->SetStartTime(SiEitEvent.getStartTime());
pEvent->SetDuration(SiEitEvent.getDuration());
- if (isPresentFollowing()) {
- if (SiEitEvent.getRunningStatus() > SI::RunningStatusNotRunning)
- pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus());
- }
int LanguagePreferenceShort = -1;
int LanguagePreferenceExt = -1;
@@ -130,11 +128,16 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
struct tm tm_r;
struct tm t = *localtime_r(&now, &tm_r); // this initializes the time zone in 't'
t.tm_isdst = -1; // makes sure mktime() will determine the correct DST setting
+ int month = t.tm_mon;
t.tm_mon = pd->getMonth() - 1;
t.tm_mday = pd->getDay();
t.tm_hour = pd->getHour();
t.tm_min = pd->getMinute();
t.tm_sec = 0;
+ if (month == 11 && t.tm_mon == 0) // current month is dec, but event is in jan
+ t.tm_year++;
+ else if (month == 0 && t.tm_mon == 11) // current month is jan, but event is in dec
+ t.tm_year--;
time_t vps = mktime(&t);
pEvent->SetVps(vps);
}
@@ -195,7 +198,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
}
if (ExtendedEventDescriptors) {
char buffer[ExtendedEventDescriptors->getMaximumTextLength()];
- pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer));
+ pEvent->SetDescription(ExtendedEventDescriptors->getText(buffer, ": "));
}
}
delete ExtendedEventDescriptors;
@@ -205,8 +208,15 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data)
if (LinkChannels)
channel->SetLinkChannels(LinkChannels);
+ if (Tid == 0x4E) { // we trust only the present/following info on the actual TS
+ if (SiEitEvent.getRunningStatus() >= SI::RunningStatusNotRunning)
+ pSchedule->SetRunningStatus(pEvent, SiEitEvent.getRunningStatus(), channel);
+ }
Modified = true;
}
+ if (Empty && Tid == 0x4E && getSectionNumber() == 0)
+ // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running
+ pSchedule->ClrRunningStatus(channel);
if (Modified)
pSchedule->Sort();
}
diff --git a/eitscan.c b/eitscan.c
index 54b579b..191a00e 100644
--- a/eitscan.c
+++ b/eitscan.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.c 1.21 2004/02/14 13:44:31 kls Exp kls $
+ * $Id: eitscan.c 1.21 2004/02/14 13:44:31 kls Exp $
*/
#include "eitscan.h"
diff --git a/eitscan.h b/eitscan.h
index c2ed7fb..c5116cb 100644
--- a/eitscan.h
+++ b/eitscan.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: eitscan.h 1.8 2004/01/17 15:36:24 kls Exp kls $
+ * $Id: eitscan.h 1.8 2004/01/17 15:36:24 kls Exp $
*/
#ifndef __EITSCAN_H
diff --git a/epg.c b/epg.c
index 88d9ee3..28d8c1d 100644
--- a/epg.c
+++ b/epg.c
@@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
*
- * $Id: epg.c 1.13 2004/02/22 14:41:37 kls Exp kls $
+ * $Id: epg.c 1.18 2004/03/13 15:01:05 kls Exp $
*/
#include "epg.h"
@@ -61,8 +61,11 @@ void cEvent::SetVersion(uchar Version)
version = Version;
}
-void cEvent::SetRunningStatus(int RunningStatus)
+void cEvent::SetRunningStatus(int RunningStatus, cChannel *Channel)
{
+ if (Channel && runningStatus != RunningStatus && (RunningStatus > SI::RunningStatusNotRunning || runningStatus > SI::RunningStatusUndefined))
+ if (Channel->Number() <= 30)//XXX maybe log only those that have timers???
+ isyslog("channel %d (%s) event %s '%s' status %d", Channel->Number(), Channel->Name(), GetTimeString(), Title(), RunningStatus);
runningStatus = RunningStatus;
}
@@ -105,6 +108,11 @@ bool cEvent::HasTimer(void) const
return false;
}
+bool cEvent::IsRunning(bool OrAboutToStart) const
+{
+ return runningStatus >= (OrAboutToStart ? SI::RunningStatusStartsInAFewSeconds : SI::RunningStatusPausing);
+}
+
const char *cEvent::GetDateString(void) const
{
static char buf[25];
@@ -146,8 +154,11 @@ void cEvent::Dump(FILE *f, const char *Prefix) const
fprintf(f, "%sT %s\n", Prefix, title);
if (!isempty(shortText))
fprintf(f, "%sS %s\n", Prefix, shortText);
- if (!isempty(description))
+ if (!isempty(description)) {
+ strreplace(description, '\n', '|');
fprintf(f, "%sD %s\n", Prefix, description);
+ strreplace(description, '|', '\n');
+ }
if (vps)
fprintf(f, "%sV %ld\n", Prefix, vps);
fprintf(f, "%se\n", Prefix);
@@ -186,8 +197,10 @@ bool cEvent::Read(FILE *f, cSchedule *Schedule)
case 'S': if (Event)
Event->SetShortText(t);
break;
- case 'D': if (Event)
+ case 'D': if (Event) {
+ strreplace(t, '|', '\n');
Event->SetDescription(t);
+ }
break;
case 'V': if (Event)
Event->SetVps(atoi(t));
@@ -282,11 +295,10 @@ void ReportEpgBugFixStats(bool Reset)
void cEvent::FixEpgBugs(void)
{
- // VDR can't usefully handle newline characters in the EPG data, so let's
- // always convert them to blanks (independent of the setting of EPGBugfixLevel):
+ // VDR can't usefully handle newline characters in the title and shortText of EPG
+ // data, so let's always convert them to blanks (independent of the setting of EPGBugfixLevel):
strreplace(title, '\n', ' ');
strreplace(shortText, '\n', ' ');
- strreplace(description, '\n', ' ');
// Same for control characters:
strreplace(title, '\x86', ' ');
strreplace(title, '\x87', ' ');
@@ -462,6 +474,7 @@ void cEvent::FixEpgBugs(void)
cSchedule::cSchedule(tChannelID ChannelID)
{
channelID = ChannelID;
+ hasRunning = false;;
}
cEvent *cSchedule::AddEvent(cEvent *Event)
@@ -475,7 +488,7 @@ const cEvent *cSchedule::GetPresentEvent(bool CheckRunningStatus) const
const cEvent *pe = NULL;
time_t now = time(NULL);
for (cEvent *p = events.First(); p; p = events.Next(p)) {
- if (p->StartTime() <= now && now < p->StartTime() + p->Duration()) {
+ if (p->StartTime() <= now && now < p->EndTime()) {
pe = p;
if (!CheckRunningStatus)
break;
@@ -514,7 +527,7 @@ const cEvent *cSchedule::GetEventAround(time_t Time) const
time_t delta = INT_MAX;
for (cEvent *p = events.First(); p; p = events.Next(p)) {
time_t dt = Time - p->StartTime();
- if (dt >= 0 && dt < delta && p->StartTime() + p->Duration() >= Time) {
+ if (dt >= 0 && dt < delta && p->EndTime() >= Time) {
delta = dt;
pe = p;
}
@@ -522,14 +535,29 @@ const cEvent *cSchedule::GetEventAround(time_t Time) const
return pe;
}
-void cSchedule::SetRunningStatus(cEvent *Event, int RunningStatus)
+void cSchedule::SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel)
{
for (cEvent *p = events.First(); p; p = events.Next(p)) {
if (p == Event)
- p->SetRunningStatus(RunningStatus);
+ p->SetRunningStatus(RunningStatus, Channel);
else if (RunningStatus >= SI::RunningStatusPausing && p->RunningStatus() > SI::RunningStatusNotRunning)
p->SetRunningStatus(SI::RunningStatusNotRunning);
}
+ if (RunningStatus >= SI::RunningStatusPausing)
+ hasRunning = true;
+}
+
+void cSchedule::ClrRunningStatus(cChannel *Channel)
+{
+ if (hasRunning) {
+ for (cEvent *p = events.First(); p; p = events.Next(p)) {
+ if (p->RunningStatus() >= SI::RunningStatusPausing) {
+ p->SetRunningStatus(SI::RunningStatusNotRunning, Channel);
+ hasRunning = false;
+ break;
+ }
+ }
+ }
}
void cSchedule::ResetVersions(void)
@@ -555,7 +583,7 @@ void cSchedule::Cleanup(time_t Time)
Event = events.Get(a);
if (!Event)
break;
- if (!Event->HasTimer() && Event->StartTime() + Event->Duration() + Setup.EPGLinger * 60 + 3600 < Time) { // adding one hour for safety
+ if (!Event->HasTimer() && Event->EndTime() + Setup.EPGLinger * 60 + 3600 < Time) { // adding one hour for safety
events.Del(Event);
a--;
}
diff --git a/epg.h b/epg.h
index 4b209b5..9a6547e 100644
--- a/epg.h
+++ b/epg.h
@@ -7,7 +7,7 @@
* Original version (as used in VDR before 1.3.0) written by
* Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
*
- * $Id: epg.h 1.10 2004/02/22 14:34:04 kls Exp kls $
+ * $Id: epg.h 1.15 2004/03/14 13:25:39 kls Exp $
*/
#ifndef __EPG_H
@@ -49,9 +49,11 @@ public:
const char *ShortText(void) const { return shortText; }
const char *Description(void) const { return description; }
time_t StartTime(void) const { return startTime; }
+ time_t EndTime(void) const { return startTime + duration; }
int Duration(void) const { return duration; }
time_t Vps(void) const { return vps; }
bool HasTimer(void) const;
+ bool IsRunning(bool OrAboutToStart = false) const;
const char *GetDateString(void) const;
const char *GetTimeString(void) const;
const char *GetEndTimeString(void) const;
@@ -59,7 +61,7 @@ public:
void SetEventID(u_int16_t EventID);
void SetTableID(uchar TableID);
void SetVersion(uchar Version);
- void SetRunningStatus(int RunningStatus);
+ void SetRunningStatus(int RunningStatus, cChannel *Channel = NULL);
void SetTitle(const char *Title);
void SetShortText(const char *ShortText);
void SetDescription(const char *Description);
@@ -77,21 +79,22 @@ class cSchedule : public cListObject {
private:
tChannelID channelID;
cList<cEvent> events;
+ bool hasRunning;
public:
cSchedule(tChannelID ChannelID);
tChannelID ChannelID(void) const { return channelID; }
- void SetRunningStatus(cEvent *Event, int RunningStatus);
+ void SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel = NULL);
+ void ClrRunningStatus(cChannel *Channel = NULL);
void ResetVersions(void);
void Sort(void);
void Cleanup(time_t Time);
void Cleanup(void);
cEvent *AddEvent(cEvent *Event);
+ const cList<cEvent> *Events(void) const { return &events; }
const cEvent *GetPresentEvent(bool CheckRunningStatus = false) const;
const cEvent *GetFollowingEvent(bool CheckRunningStatus = false) const;
const cEvent *GetEvent(u_int16_t EventID, time_t StartTime = 0) const;
const cEvent *GetEventAround(time_t Time) const;
- const cEvent *GetEventNumber(int n) const { return events.Get(n); }
- int NumEvents(void) const { return events.Count(); }
void Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0) const;
static bool Read(FILE *f, cSchedules *Schedules);
};
diff --git a/i18n.c b/i18n.c
index 8983d6f..17cc2a4 100644
--- a/i18n.c
+++ b/i18n.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: i18n.c 1.148 2004/02/21 15:14:36 kls Exp kls $
+ * $Id: i18n.c 1.152 2004/03/13 10:59:23 kls Exp $
*
* Translations provided by:
*
@@ -1550,6 +1550,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "VPS",
"",// TODO
"",// TODO
"",// TODO
@@ -1557,8 +1558,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
- "",// TODO
+ "VPS ßÞßàÐÒÚÐ",
},
{ "Priority",
"Priorität",
@@ -1839,9 +1839,9 @@ const tI18nPhrase Phrases[] = {
"",//TODO
"Pas de marques d'édition définies!",
"",//TODO
- "",//TODO
+ "Muokkausmerkinnät puuttuvat!",
"Brak znakow montazowych!",
- "Muokkausmerkinnät puuttuvat",
+ "",//TODO
"ÄÝí Ý÷ïõí ïñéóôåß óçìåßá åðåîåñãáóßáò",
"Det finns inga redigeringsmärken",//TODO
"",//TODO
@@ -2389,7 +2389,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
+ "ÅàÐÝÕÝØÕ ãáâÐàÕÒèØå ÔÐÝÝëå (ÜØÝ)",
},
{ "Setup.EPG$Set system time",
"Systemzeit stellen",
@@ -2777,7 +2777,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"Priorité des pauses",
"",// TODO
- "Keskeytyksen prioriteetti",
+ "Taukotallenteen prioriteetti",
"Priorytet przerwy",
"",// TODO
"Ðñïôåñáéüôçôá äéáëåßììáôïò",
@@ -2795,7 +2795,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"Durée de vie des pauses (j)",
"",// TODO
- "Keskeytyksen elinikä (d)",
+ "Taukotallenteen elinikä (d)",
"Okres trwania przerwy (d)",
"",// TODO
"ÄéÜñêåéá äéáëåßìáôïò",
@@ -2831,6 +2831,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "Käytä VPS-toimintoa",
"",// TODO
"",// TODO
"",// TODO
@@ -2838,8 +2839,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
- "",// TODO
+ "¸áßÞÛì×ÞÒÐâì áØÓÝÐÛë VPS",
},
{ "Setup.Recording$VPS margin (s)",
"Zeitpuffer bei VPS (s)",
@@ -2849,6 +2849,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
+ "VPS-toiminnon aloitusmarginaali (s)",
"",// TODO
"",// TODO
"",// TODO
@@ -2856,8 +2857,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"",// TODO
"",// TODO
- "",// TODO
- "",// TODO
+ "±ãäÕàÝÞÕ ÒàÕÜï VPS (áÕÚ)",
},
{ "Setup.Recording$Mark instant recording",
"Direktaufzeichnung markieren",
@@ -3627,7 +3627,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"Pause",
"",// TODO
- "Keskeytä",
+ "Tauko",
"Przerwa",
"Pausa",
"ÄéÜëåéììá",
@@ -4186,7 +4186,7 @@ const tI18nPhrase Phrases[] = {
"",// TODO
"Pause de l'émission en direct...",
"",// TODO
- "Keskeytetään lähetys...",
+ "Pysäytetään lähetys...",
"Zatrzymany program biezacy...",
"Emisión en directo parada...",
"ÄéÜëåéììá æùíôáíïý óÞìáôïò",
diff --git a/libsi/descriptor.c b/libsi/descriptor.c
index 0b0019f..82e2a8f 100644
--- a/libsi/descriptor.c
+++ b/libsi/descriptor.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: descriptor.c 1.6 2004/02/22 11:11:36 kls Exp $
+ * $Id: descriptor.c 1.10 2004/03/13 15:08:12 kls Exp $
* *
***************************************************************************/
@@ -60,13 +60,13 @@ void ExtendedEventDescriptor::Item::Parse() {
item.setData(data+offset, mid->item_length);
}
-int ExtendedEventDescriptors::getTextLength() {
+/*int ExtendedEventDescriptors::getTextLength() {
int ret=0;
for (int i=0;i<length;i++) {
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
if (!d)
continue;
- ret+=d->text.getLength()+1; //plus a blank
+ ret+=d->text.getLength();
ExtendedEventDescriptor::Item item;
for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
item=d->itemLoop.getNext(it);
@@ -76,28 +76,84 @@ int ExtendedEventDescriptors::getTextLength() {
}
}
return ret;
-}
+}*/
-//is there a case where this function does not return the same as getTextLength?
int ExtendedEventDescriptors::getMaximumTextLength() {
+ return getMaximumTextPlainLength()+getMaximumTextItemizedLength();
+}
+
+char *ExtendedEventDescriptors::getText(const char *separation1, const char *separation2) {
+ char *text=new char[getMaximumTextLength()+strlen(separation1)+strlen(separation2)];
+ return getText(text, separation1, separation2);
+}
+
+char *ExtendedEventDescriptors::getText(char *buffer, const char *separation1, const char *separation2) {
+ int index=0, len;
+ char tempbuf[256];
+ for (int i=0;i<length;i++) {
+ ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
+ if (!d)
+ continue;
+ d->text.getText(tempbuf);
+ len=strlen(tempbuf);
+ if (len) {
+ memcpy(buffer+index, tempbuf, len);
+ index+=len;
+ }
+ }
+
+ for (int i=0;i<length;i++) {
+ ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
+ if (!d)
+ continue;
+
+ strcpy(buffer+index, separation2); // let's have a separator between the long text and the items
+ index += strlen(separation2);
+ ExtendedEventDescriptor::Item item;
+ for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
+ item=d->itemLoop.getNext(it);
+
+ item.itemDescription.getText(tempbuf);
+ len=strlen(tempbuf);
+ if (len) {
+ memcpy(buffer+index, tempbuf, len);
+ index+=len;
+ }
+ strcpy(buffer+index, separation1);
+ index += strlen(separation1);
+
+ item.item.getText(tempbuf);
+ len=strlen(tempbuf);
+ if (len) {
+ memcpy(buffer+index, tempbuf, len);
+ index+=len;
+ }
+ strcpy(buffer+index, separation2);
+ index += strlen(separation2);
+ }
+ }
+
+ buffer[index]='\0';
+ return buffer;
+}
+
+int ExtendedEventDescriptors::getMaximumTextPlainLength() {
int ret=0;
for (int i=0;i<length;i++) {
ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
if (!d)
continue;
- ret+=d->text.getLength()+1; //plus a blank
- ret+=d->itemLoop.getLength();
+ ret+=d->text.getLength();
}
return ret;
}
-char *ExtendedEventDescriptors::getText() {
- char *text=new char[getMaximumTextLength()];
- return getText(text);
+char *ExtendedEventDescriptors::getTextPlain() {
+ char *text=new char[getMaximumTextPlainLength()];
+ return getTextPlain(text);
}
-//appends the Strings of every Descriptor in the group
-char *ExtendedEventDescriptors::getText(char *buffer) {
+char *ExtendedEventDescriptors::getTextPlain(char *buffer) {
int index=0, len;
char tempbuf[256];
for (int i=0;i<length;i++) {
@@ -110,30 +166,98 @@ char *ExtendedEventDescriptors::getText(char *buffer) {
memcpy(buffer+index, tempbuf, len);
index+=len;
}
+ }
+ buffer[index]='\0';
+ return buffer;
+}
+
+int ExtendedEventDescriptors::getMaximumTextItemizedLength() {
+ int ret=0;
+ for (int i=0;i<length;i++) {
+ ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
+ if (!d)
+ continue;
+ //the size for the two separating characters is included ;-)
+ ret+=d->itemLoop.getLength();
+ }
+ return ret;
+}
+
+char *ExtendedEventDescriptors::getTextItemized(const char *separation1, const char *separation2) {
+ char *text=new char[getMaximumTextItemizedLength()+strlen(separation1)+strlen(separation2)];
+ return getTextItemized(text, separation1, separation2);
+}
+
+char *ExtendedEventDescriptors::getTextItemized(char *buffer, const char *separation1, const char *separation2) {
+ int index=0, len;
+ char tempbuf[256];
+ for (int i=0;i<length;i++) {
+ ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[i];
+ if (!d)
+ continue;
ExtendedEventDescriptor::Item item;
for (Loop::Iterator it; d->itemLoop.hasNext(it); ) {
item=d->itemLoop.getNext(it);
- item.item.getText(tempbuf);
+ item.itemDescription.getText(tempbuf);
len=strlen(tempbuf);
if (len) {
memcpy(buffer+index, tempbuf, len);
index+=len;
}
+ strcpy(buffer+index, separation1);
+ index += strlen(separation1);
- item.itemDescription.getText(tempbuf);
+ item.item.getText(tempbuf);
len=strlen(tempbuf);
if (len) {
memcpy(buffer+index, tempbuf, len);
index+=len;
}
+ strcpy(buffer+index, separation2);
+ index += strlen(separation2);
}
}
buffer[index]='\0';
return buffer;
}
+//returns the itemized text pair by pair. Maximum length for buffers is 256.
+//Return value is false if and only if the end of the list is reached.
+bool ExtendedEventDescriptors::getTextItemized(Loop::Iterator &it, bool &valid, char *itemDescription, char *itemText) {
+ //The iterator has to store two values: The descriptor index (4bit)
+ //and the item loop index (max overall length 256, min item length 16 => max number 128 => 7bit)
+ valid=false;
+
+ int index=(it.i & 0x780) >> 7; // 0x780 == 1111 000 0000
+ it.i &= 0x7F; //0x7F == 111 1111
+
+ for (;index<length;index++) {
+ ExtendedEventDescriptor *d=(ExtendedEventDescriptor *)array[index];
+ if (!d)
+ continue;
+
+ ExtendedEventDescriptor::Item item;
+ if (d->itemLoop.hasNext(it)) {
+ item=d->itemLoop.getNext(it);
+
+ item.item.getText(itemDescription);
+ item.itemDescription.getText(itemText);
+ valid=true;
+ break;
+ } else {
+ it.reset();
+ continue;
+ }
+ }
+
+ it.i &= 0x7F;
+ it.i |= (index & 0xF) << 7; //0xF == 1111
+
+ return index<length;
+}
+
int TimeShiftedEventDescriptor::getReferenceServiceId() const {
return HILO(s->reference_service_id);
}
@@ -148,7 +272,7 @@ void TimeShiftedEventDescriptor::Parse() {
void ContentDescriptor::Parse() {
//this descriptor is only a header and a loop
- nibbleLoop.setData(data+sizeof(SectionHeader), getLength()-sizeof(SectionHeader));
+ nibbleLoop.setData(data+sizeof(descr_content), getLength()-sizeof(descr_content));
}
int ContentDescriptor::Nibble::getContentNibbleLevel1() const {
@@ -173,7 +297,7 @@ void ContentDescriptor::Nibble::Parse() {
void ParentalRatingDescriptor::Parse() {
//this descriptor is only a header and a loop
- ratingLoop.setData(data+sizeof(SectionHeader), getLength()-sizeof(SectionHeader));
+ ratingLoop.setData(data+sizeof(descr_parental_rating), getLength()-sizeof(descr_parental_rating));
}
int ParentalRatingDescriptor::Rating::getRating() const {
diff --git a/libsi/descriptor.h b/libsi/descriptor.h
index 17c81eb..3368b0a 100644
--- a/libsi/descriptor.h
+++ b/libsi/descriptor.h
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: descriptor.h 1.6 2004/02/22 10:16:47 kls Exp $
+ * $Id: descriptor.h 1.7 2004/03/07 11:13:54 kls Exp $
* *
***************************************************************************/
@@ -50,14 +50,29 @@ private:
class ExtendedEventDescriptors : public DescriptorGroup {
public:
- //don't use
- int getTextLength();
- //really fast
int getMaximumTextLength();
+ //Returns a concatenated version of first the non-itemized and then the itemized text
//same semantics as with SI::String
- char *getText();
+ char *getText(const char *separation1="\t", const char *separation2="\n");
//buffer must at least be getTextLength(), getMaximumTextLength() is a good choice
- char *getText(char *buffer);
+ char *getText(char *buffer, const char *separation1="\t", const char *separation2="\n");
+
+ //these only return the non-itemized text fields in concatenated form
+ int getMaximumTextPlainLength();
+ char *getTextPlain();
+ char *getTextPlain(char *buffer);
+
+ //these only return the itemized text fields in concatenated form.
+ //Between the description and the text the separation1 character is used,
+ //separation2 used between two pairs. Example:
+ //Director\tSteven Spielberg\nActor\tMichael Mendl\n
+ int getMaximumTextItemizedLength();
+ char *getTextItemized(const char *separation1="\t", const char *separation2="\n");
+ char *getTextItemized(char *buffer, const char *separation1="\t", const char *separation2="\n");
+ //returns the itemized text pair by pair. Maximum length for buffers is 256.
+ //Return value is false if and only if the end of the list is reached.
+ //The argument valid indicates whether the buffers contain valid content.
+ bool getTextItemized(Loop::Iterator &it, bool &valid, char *itemDescription, char *itemText);
};
class TimeShiftedEventDescriptor : public Descriptor {
diff --git a/libsi/si.c b/libsi/si.c
index ee64802..9ce46f0 100644
--- a/libsi/si.c
+++ b/libsi/si.c
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: si.c 1.8 2004/02/22 10:14:12 kls Exp $
+ * $Id: si.c 1.9 2004/03/07 10:50:09 kls Exp $
* *
***************************************************************************/
@@ -103,7 +103,7 @@ DescriptorTag Descriptor::getDescriptorTag(const unsigned char *d) {
Descriptor *DescriptorLoop::getNext(Iterator &it) {
if (it.i<getLength()) {
- return createDescriptor(it.i);
+ return createDescriptor(it.i, true);
}
return 0;
}
@@ -115,19 +115,18 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag tag, bool return
const unsigned char *end=p+getLength();
while (p < end) {
if (Descriptor::getDescriptorTag(p) == tag) {
- d=createDescriptor(it.i);
- break;
+ d=createDescriptor(it.i, returnUnimplemetedDescriptor);
+ if (d)
+ break;
}
it.i+=Descriptor::getLength(p);
p+=Descriptor::getLength(p);
}
}
- if (d && d->getDescriptorTag()==UnimplementedDescriptorTag)
- return returnUnimplemetedDescriptor ? d : 0;
return d;
}
-Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor) {
+Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplementedDescriptor) {
Descriptor *d=0;
if (it.i<getLength()) {
const unsigned char *p=data.getData(it.i);
@@ -135,27 +134,38 @@ Descriptor *DescriptorLoop::getNext(Iterator &it, DescriptorTag *tags, int array
while (p < end) {
for (int u=0; u<arrayLength;u++)
if (Descriptor::getDescriptorTag(p) == tags[u]) {
- d=createDescriptor(it.i);
+ d=createDescriptor(it.i, returnUnimplementedDescriptor);
break;
}
if (d)
- break;
+ break; //length is added to it.i by createDescriptor, break here
it.i+=Descriptor::getLength(p);
p+=Descriptor::getLength(p);
}
}
- if (d && d->getDescriptorTag()==UnimplementedDescriptorTag)
- return returnUnimplemetedDescriptor ? d : 0;
return d;
}
-Descriptor *DescriptorLoop::createDescriptor(int &i) {
- Descriptor *d=Descriptor::getDescriptor(data+i, domain);
+Descriptor *DescriptorLoop::createDescriptor(int &i, bool returnUnimplemetedDescriptor) {
+ Descriptor *d=Descriptor::getDescriptor(data+i, domain, returnUnimplemetedDescriptor);
+ if (!d)
+ return 0;
i+=d->getLength();
d->CheckParse();
return d;
}
+int DescriptorLoop::getNumberOfDescriptors() {
+ const unsigned char *p=data.getData();
+ const unsigned char *end=p+getLength();
+ int count=0;
+ while (p < end) {
+ count++;
+ p+=Descriptor::getLength(p);
+ }
+ return count;
+}
+
DescriptorGroup::DescriptorGroup(bool del) {
array=0;
length=0;
@@ -211,6 +221,16 @@ char *String::getText(char *buffer) {
return buffer;
}
+//taken from VDR, Copyright Klaus Schmidinger <kls@cadsoft.de>
+char *String::getText(char *buffer, char *shortVersion) {
+ if (getLength() < 0 || getLength() >4095) {
+ strncpy(buffer, "text error", getLength()+1);
+ return buffer;
+ }
+ decodeText(buffer, shortVersion);
+ return buffer;
+}
+
//taken from libdtv, Copyright Rolf Hakenes <hakenes@hippomi.de>
void String::decodeText(char *buffer) {
const unsigned char *from=data.getData(0);
@@ -228,18 +248,47 @@ void String::decodeText(char *buffer) {
if ( ((' ' <= *from) && (*from <= '~'))
|| (*from == '\n')
|| (0xA0 <= *from)
+ || (*from == 0x86 || *from == 0x87)
)
*to++ = *from;
else if (*from == 0x8A)
*to++ = '\n';
- else if (*from == 0x86 || *from == 0x87) //&& !(GDT_NAME_DESCRIPTOR & type))
+ from++;
+ }
+ *to = '\0';
+}
+
+void String::decodeText(char *buffer, char *shortVersion) {
+ const unsigned char *from=data.getData(0);
+ char *to=buffer;
+ char *toShort=shortVersion;
+ int IsShortName=0;
+
+ for (int i = 0; i < getLength(); i++) {
+ if (*from == 0)
+ break;
+ if ( ((' ' <= *from) && (*from <= '~'))
+ || (*from == '\n')
+ || (0xA0 <= *from)
+ )
+ {
*to++ = *from;
+ if (IsShortName)
+ *toShort++ = *from;
+ }
+ else if (*from == 0x8A)
+ *to++ = '\n';
+ else if (*from == 0x86)
+ IsShortName++;
+ else if (*from == 0x87)
+ IsShortName--;
from++;
}
*to = '\0';
+ *toShort = '\0';
}
-Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain) {
+Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor) {
Descriptor *d=0;
switch (domain) {
case SI:
@@ -383,6 +432,8 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain)
case AdaptationFieldDataDescriptorTag:
case TransportStreamDescriptorTag:
default:
+ if (!returnUnimplemetedDescriptor)
+ return 0;
d=new UnimplementedDescriptor();
break;
}
@@ -417,6 +468,8 @@ Descriptor *Descriptor::getDescriptor(CharArray da, DescriptorTagDomain domain)
case MHP_DelegatedApplicationDescriptorTag:
case MHP_ApplicationStorageDescriptorTag:
default:
+ if (!returnUnimplemetedDescriptor)
+ return 0;
d=new UnimplementedDescriptor();
break;
}
diff --git a/libsi/si.h b/libsi/si.h
index befff85..195830d 100644
--- a/libsi/si.h
+++ b/libsi/si.h
@@ -6,7 +6,7 @@
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
- * $Id: si.h 1.8 2004/02/23 17:02:33 kls Exp $
+ * $Id: si.h 1.9 2004/03/07 10:09:49 kls Exp $
* *
***************************************************************************/
@@ -252,8 +252,11 @@ protected:
//returns a subclass of descriptor according to the data given.
//The object is allocated with new and must be delete'd.
//setData() will have been called, CheckParse() not.
- //Never returns null - maybe the UnimplementedDescriptor.
- static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain);
+ //if returnUnimplemetedDescriptor==true:
+ // Never returns null - maybe the UnimplementedDescriptor.
+ //if returnUnimplemetedDescriptor==false:
+ // Never returns the UnimplementedDescriptor - maybe null
+ static Descriptor *getDescriptor(CharArray d, DescriptorTagDomain domain, bool returnUnimplemetedDescriptor);
};
class Loop : public VariableLengthPart {
@@ -266,6 +269,7 @@ public:
template <class T> friend class StructureLoop;
friend class DescriptorLoop;
template <class T> friend class TypeLoop;
+ friend class ExtendedEventDescriptors;
int i;
};
protected:
@@ -311,14 +315,46 @@ public:
//returns null if no more descriptors available
Descriptor *getNext(Iterator &it);
//return the next descriptor with given tag, or 0 if not available.
- //if the descriptor found is not implemented,
- // an UnimplementedDescriptor will be returned if returnUnimplemetedDescriptor==true,
- // 0 will be returned if returnUnimplemetedDescriptor==false
+ //if returnUnimplemetedDescriptor==true:
+ // an UnimplementedDescriptor may be returned if the next matching descriptor is unimplemented,
+ // 0 will be returned if and only if no matching descriptor is found.
+ //if returnUnimplemetedDescriptor==false:
+ // if 0 is returned, either no descriptor with the given tag was found,
+ // or descriptors were found, but the descriptor type is not implemented
+ //In either case, a return value of 0 indicates that no further calls to this method
+ //with the iterator shall be made.
Descriptor *getNext(Iterator &it, DescriptorTag tag, bool returnUnimplemetedDescriptor=false);
//return the next descriptor with one of the given tags, or 0 if not available.
+ //if returnUnimplemetedDescriptor==true:
+ // returns 0 if and only if no descriptor with one of the given tags was found.
+ // The UnimplementedDescriptor may be returned.
+ //if returnUnimplemetedDescriptor==false:
+ // if 0 is returned, either no descriptor with one of the given tags was found,
+ // or descriptors were found, but none of them are implemented.
+ // The UnimplementedDescriptor will never be returned.
+ //In either case, a return value of 0 indicates that no further calls to this method
+ //with the iterator shall be made.
Descriptor *getNext(Iterator &it, DescriptorTag *tags, int arrayLength, bool returnUnimplemetedDescriptor=false);
+ //returns the number of descriptors in this loop
+ int getNumberOfDescriptors();
+ //writes the tags of the descriptors in this loop in the array,
+ // which must at least have the size getNumberOfDescriptors().
+ //The number of descriptors, i.e. getNumberOfDescriptors(), is returned.
+ // You can specify the array type (Descriptor tags are 8 Bit,
+ // you might e.g. choose a char, short, int or DescriptorTag array)
+ template <typename T> int getDescriptorTags(T *tags)
+ {
+ const unsigned char *p=data.getData();
+ const unsigned char *end=p+getLength();
+ int count=0;
+ while (p < end) {
+ tags[count++]=(T)Descriptor::getDescriptorTag(p);
+ p+=Descriptor::getLength(p);
+ }
+ return count;
+ }
protected:
- Descriptor *createDescriptor(int &i);
+ Descriptor *createDescriptor(int &i, bool returnUnimplemetedDescriptor);
DescriptorTagDomain domain;
};
@@ -385,7 +421,7 @@ class String : public VariableLengthPart {
public:
//A note to the length: getLength() returns the length of the raw data.
//The text may be shorter. Its length can be obtained with one of the
- //above functions and strlen.
+ //getText functions and strlen.
//returns text. Data is allocated with new and must be delete'd by the user.
char *getText();
@@ -394,10 +430,19 @@ public:
//In most descriptors the string length is an 8-bit field,
//so the maximum there is 256.
//returns the given buffer for convenience.
- char * getText(char *buffer);
+ //The emphasis marks 0x86 and 0x87 are still available.
+ char *getText(char *buffer);
+ //The same semantics as for getText(char*) apply.
+ //The short version of the text according to ETSI TR 101 211 (chapter 4.6)
+ //will be written into the shortVersion buffer (which should, therefore, have the same
+ //length as buffer). If no shortVersion is available, shortVersion will contain
+ //an empty string.
+ //The emphasis marks 0x86 and 0x87 are still available in buffer, but not in shortVersion.
+ char *getText(char *buffer, char *shortVersion);
protected:
virtual void Parse() {}
void decodeText(char *buffer);
+ void decodeText(char *buffer, char *shortVersion);
};
} //end of namespace
diff --git a/menu.c b/menu.c
index c153151..4fdb994 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.292 2004/02/22 14:14:55 kls Exp kls $
+ * $Id: menu.c 1.297 2004/03/14 13:24:02 kls Exp $
*/
#include "menu.h"
@@ -18,7 +18,6 @@
#include "cutter.h"
#include "eitscan.h"
#include "i18n.h"
-#include "libsi/si.h"
#include "menuitems.h"
#include "plugin.h"
#include "recording.h"
@@ -1009,13 +1008,8 @@ public:
cMenuTimers::cMenuTimers(void)
:cOsdMenu(tr("Timers"), 2, CHNUMWIDTH, 10, 6, 6)
{
- int i = 0;
- cTimer *timer;
-
- while ((timer = Timers.Get(i)) != NULL) {
- Add(new cMenuTimerItem(timer));
- i++;
- }
+ for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer))
+ Add(new cMenuTimerItem(timer));
if (Setup.SortTimers)
Sort();
SetHelp(tr("Edit"), tr("New"), tr("Delete"), Setup.SortTimers ? tr("On/Off") : tr("Mark"));
@@ -1216,7 +1210,7 @@ cMenuWhatsOnItem::cMenuWhatsOnItem(const cEvent *Event, cChannel *Channel)
int TimerMatch;
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
- char r = event->RunningStatus() > SI::RunningStatusNotRunning ? '*' : ' ';
+ char r = event->IsRunning() ? '*' : ' ';
asprintf(&buffer, "%d\t%.*s\t%.*s\t%c%c%c\t%s", channel->Number(), 6, channel->Name(), 5, event->GetTimeString(), t, v, r, event->Title());
SetText(buffer, false);
}
@@ -1334,7 +1328,7 @@ cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event)
int TimerMatch;
char t = Timers.GetMatch(Event, &TimerMatch) ? (TimerMatch == tmFull) ? 'T' : 't' : ' ';
char v = event->Vps() && (event->Vps() - event->StartTime()) ? 'V' : ' ';
- char r = event->RunningStatus() > SI::RunningStatusNotRunning ? '*' : ' ';
+ char r = event->IsRunning() ? '*' : ' ';
asprintf(&buffer, "%.*s\t%.*s\t%c%c%c\t%s", 5, event->GetDateString(), 5, event->GetTimeString(), t, v, r, event->Title());
SetText(buffer, false);
}
@@ -1386,11 +1380,9 @@ void cMenuSchedule::PrepareSchedule(cChannel *Channel)
const cSchedule *Schedule = schedules->GetSchedule(Channel->GetChannelID());
if (Schedule) {
const cEvent *PresentEvent = Schedule->GetPresentEvent(Channel->Number() == cDevice::CurrentChannel());
- int num = Schedule->NumEvents();
time_t now = time(NULL) - Setup.EPGLinger * 60;
- for (int a = 0; a < num; a++) {
- const cEvent *Event = Schedule->GetEventNumber(a);
- if (Event->StartTime() + Event->Duration() > now || Event == PresentEvent)
+ for (const cEvent *Event = Schedule->Events()->First(); Event; Event = Schedule->Events()->Next(Event)) {
+ if (Event->EndTime() > now || Event == PresentEvent)
Add(new cMenuScheduleItem(Event), Event == PresentEvent);
}
}
@@ -1494,13 +1486,8 @@ cMenuCommands::cMenuCommands(const char *Title, cCommands *Commands, const char
SetHasHotkeys();
commands = Commands;
parameters = Parameters ? strdup(Parameters) : NULL;
- int i = 0;
- cCommand *command;
-
- while ((command = commands->Get(i)) != NULL) {
- Add(new cOsdItem(hk(command->Title())));
- i++;
- }
+ for (cCommand *command = commands->First(); command; command = commands->Next(command))
+ Add(new cOsdItem(hk(command->Title())));
}
cMenuCommands::~cMenuCommands()
@@ -3196,6 +3183,7 @@ bool cRecordControls::Start(cTimer *Timer, bool Pause)
if (device == cTransferControl::ReceiverDevice())
cControl::Shutdown(); // in case this device was used for Transfer Mode
}
+ dsyslog("switching device %d to channel %d", device->DeviceNumber() + 1, channel->Number());
if (!device->SwitchChannel(channel, false)) {
cThread::EmergencyExit(true);
return false;
diff --git a/menu.h b/menu.h
index a03d3a0..6fe9540 100644
--- a/menu.h
+++ b/menu.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.h 1.60 2004/02/15 14:11:28 kls Exp kls $
+ * $Id: menu.h 1.60 2004/02/15 14:11:28 kls Exp $
*/
#ifndef __MENU_H
diff --git a/menuitems.c b/menuitems.c
index e3c99a5..49874f1 100644
--- a/menuitems.c
+++ b/menuitems.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menuitems.c 1.14 2004/01/25 15:40:55 kls Exp kls $
+ * $Id: menuitems.c 1.15 2004/02/24 12:38:43 kls Exp $
*/
#include "menuitems.h"
diff --git a/menuitems.h b/menuitems.h
index 72a2418..7091740 100644
--- a/menuitems.h
+++ b/menuitems.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menuitems.h 1.5 2003/01/12 15:06:23 kls Exp kls $
+ * $Id: menuitems.h 1.6 2004/02/24 11:55:14 kls Exp $
*/
#ifndef __MENUITEMS_H
diff --git a/osd.c b/osd.c
index 8f3343b..7ede001 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.43 2003/06/04 16:13:00 kls Exp $
+ * $Id: osd.c 1.45 2004/03/14 10:33:20 kls Exp $
*/
#include "osd.h"
@@ -429,30 +429,27 @@ void cOsdMenu::Display(void)
Interface->Help(helpRed, helpGreen, helpYellow, helpBlue);
int count = Count();
if (count > 0) {
- for (int i = 0; i < count; i++) {
- cOsdItem *item = Get(i);
- if (item)
- cStatus::MsgOsdItem(item->Text(), i);
- }
+ int ni = 0;
+ for (cOsdItem *item = First(); item; item = Next(item))
+ cStatus::MsgOsdItem(item->Text(), ni++);
if (current < 0)
current = 0; // just for safety - there HAS to be a current item!
- int n = 0;
- if (current - first >= MAXOSDITEMS) {
+ if (current - first >= MAXOSDITEMS || current < first) {
first = current - MAXOSDITEMS / 2;
if (first + MAXOSDITEMS > count)
first = count - MAXOSDITEMS;
if (first < 0)
first = 0;
}
- for (int i = first; i < count; i++) {
- cOsdItem *item = Get(i);
- if (item) {
- item->Display(i - first, i == current ? clrBlack : clrWhite, i == current ? clrCyan : clrBackground);
- if (i == current)
- cStatus::MsgOsdCurrentItem(item->Text());
- }
+ int i = first;
+ int n = 0;
+ for (cOsdItem *item = Get(first); item; item = Next(item)) {
+ item->Display(i - first, i == current ? clrBlack : clrWhite, i == current ? clrCyan : clrBackground);
+ if (i == current)
+ cStatus::MsgOsdCurrentItem(item->Text());
if (++n == MAXOSDITEMS) //TODO get this from Interface!!!
break;
+ i++;
}
}
if (!isempty(status))
@@ -562,12 +559,13 @@ void cOsdMenu::PageDown(void)
{
current += MAXOSDITEMS;
first += MAXOSDITEMS;
- if (current > Count() - 1) {
- current = Count() - 1;
- first = max(0, Count() - MAXOSDITEMS);
+ int count = Count();
+ if (current > count - 1) {
+ current = count - 1;
+ first = max(0, count - MAXOSDITEMS);
}
if (SpecialItem(current)) {
- current += (current < Count() - 1) ? 1 : -1;
+ current += (current < count - 1) ? 1 : -1;
first = max(first, current - MAXOSDITEMS);
}
Display();
diff --git a/pat.c b/pat.c
index 9b27bda..b9fc0e6 100644
--- a/pat.c
+++ b/pat.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: pat.c 1.7 2004/01/25 15:12:53 kls Exp $
+ * $Id: pat.c 1.8 2004/03/07 16:59:00 kls Exp $
*/
#include "pat.h"
@@ -250,19 +250,21 @@ void cPatFilter::Trigger(void)
numPmtEntries = 0;
}
-bool cPatFilter::PmtVersionChanged(int PmtPid, int Version)
+bool cPatFilter::PmtVersionChanged(int PmtPid, int Sid, int Version)
{
- Version <<= 16;
+ uint64_t v = Version;
+ v <<= 32;
+ uint64_t id = (PmtPid | (Sid << 16)) & 0x00000000FFFFFFFFLL;
for (int i = 0; i < numPmtEntries; i++) {
- if ((pmtVersion[i] & 0x0000FFFF) == PmtPid) {
- bool Changed = (pmtVersion[i] & 0x00FF0000) != Version;
+ if ((pmtVersion[i] & 0x00000000FFFFFFFFLL) == id) {
+ bool Changed = (pmtVersion[i] & 0x000000FF00000000LL) != v;
if (Changed)
- pmtVersion[i] = PmtPid | Version;
+ pmtVersion[i] = id | v;
return Changed;
}
}
if (numPmtEntries < MAXPMTENTRIES)
- pmtVersion[numPmtEntries++] = PmtPid | Version;
+ pmtVersion[numPmtEntries++] = id | v;
return true;
}
@@ -301,7 +303,7 @@ void cPatFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
SI::PMT pmt(Data, false);
if (!pmt.CheckCRCAndParse())
return;
- if (!PmtVersionChanged(pmtPid, pmt.getVersionNumber())) {
+ if (!PmtVersionChanged(pmtPid, pmt.getTableIdExtension(), pmt.getVersionNumber())) {
lastPmtScan = 0; // this triggers the next scan
return;
}
diff --git a/pat.h b/pat.h
index dd1a1fe..a7f4635 100644
--- a/pat.h
+++ b/pat.h
@@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: pat.h 1.3 2004/01/03 13:47:54 kls Exp $
+ * $Id: pat.h 1.4 2004/03/07 16:22:01 kls Exp $
*/
#ifndef __PAT_H
#define __PAT_H
#include "filter.h"
+#include <stdint.h>
#define MAXPMTENTRIES 64
@@ -19,9 +20,9 @@ private:
time_t lastPmtScan;
int pmtIndex;
int pmtPid;
- int pmtVersion[MAXPMTENTRIES];
+ uint64_t pmtVersion[MAXPMTENTRIES];
int numPmtEntries;
- bool PmtVersionChanged(int PmtPid, int Version);
+ bool PmtVersionChanged(int PmtPid, int Sid, int Version);
protected:
virtual void Process(u_short Pid, u_char Tid, const u_char *Data, int Length);
public:
diff --git a/recorder.c b/recorder.c
index c46c565..b6b9a24 100644
--- a/recorder.c
+++ b/recorder.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: recorder.c 1.8 2003/10/18 11:35:02 kls Exp $
+ * $Id: recorder.c 1.9 2004/03/07 14:39:25 kls Exp $
*/
#include <stdarg.h>
@@ -102,7 +102,7 @@ void cRecorder::Receive(uchar *Data, int Length)
{
int p = ringBuffer->Put(Data, Length);
if (p != Length && active)
- esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length - p);
+ ringBuffer->ReportOverflow(Length - p);
}
void cRecorder::Action(void)
diff --git a/ringbuffer.c b/ringbuffer.c
index c92b75f..6f26748 100644
--- a/ringbuffer.c
+++ b/ringbuffer.c
@@ -7,7 +7,7 @@
* Parts of this file were inspired by the 'ringbuffy.c' from the
* LinuxDVB driver (see linuxtv.org).
*
- * $Id: ringbuffer.c 1.18 2003/10/12 14:25:09 kls Exp $
+ * $Id: ringbuffer.c 1.19 2004/03/07 13:46:51 kls Exp $
*/
#include "ringbuffer.h"
@@ -17,6 +17,8 @@
// --- cRingBuffer -----------------------------------------------------------
+#define OVERFLOWREPORTDELTA 5 // seconds between reports
+
cRingBuffer::cRingBuffer(int Size, bool Statistics)
{
size = Size;
@@ -24,6 +26,8 @@ cRingBuffer::cRingBuffer(int Size, bool Statistics)
maxFill = 0;
lastPercent = 0;
putTimeout = getTimeout = 0;
+ lastOverflowReport = 0;
+ overflowCount = overflowBytes = 0;
}
cRingBuffer::~cRingBuffer()
@@ -68,6 +72,17 @@ void cRingBuffer::SetTimeouts(int PutTimeout, int GetTimeout)
getTimeout = GetTimeout;
}
+void cRingBuffer::ReportOverflow(int Bytes)
+{
+ overflowCount++;
+ overflowBytes += Bytes;
+ if (time(NULL) - lastOverflowReport > OVERFLOWREPORTDELTA) {
+ esyslog("ERROR: %d ring buffer overflow%s (%d bytes dropped)", overflowCount, overflowCount > 1 ? "s" : "", overflowBytes);
+ overflowCount = overflowBytes = 0;
+ lastOverflowReport = time(NULL);
+ }
+}
+
// --- cRingBufferLinear -----------------------------------------------------
cRingBufferLinear::cRingBufferLinear(int Size, int Margin, bool Statistics)
diff --git a/ringbuffer.h b/ringbuffer.h
index 0680df4..349096f 100644
--- a/ringbuffer.h
+++ b/ringbuffer.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: ringbuffer.h 1.13 2003/10/12 13:57:56 kls Exp $
+ * $Id: ringbuffer.h 1.14 2004/03/07 13:40:45 kls Exp $
*/
#ifndef __RINGBUFFER_H
@@ -21,6 +21,9 @@ private:
int putTimeout;
int getTimeout;
int size;
+ time_t lastOverflowReport;
+ int overflowCount;
+ int overflowBytes;
protected:
int maxFill;//XXX
int lastPercent;
@@ -39,6 +42,7 @@ public:
cRingBuffer(int Size, bool Statistics = false);
virtual ~cRingBuffer();
void SetTimeouts(int PutTimeout, int GetTimeout);
+ void ReportOverflow(int Bytes);
};
class cRingBufferLinear : public cRingBuffer {
diff --git a/sdt.c b/sdt.c
index 6fd3314..5ac6b41 100644
--- a/sdt.c
+++ b/sdt.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: sdt.c 1.7 2004/01/17 17:27:49 kls Exp $
+ * $Id: sdt.c 1.8 2004/03/07 10:46:08 kls Exp $
*/
#include "sdt.h"
@@ -57,34 +57,17 @@ void cSdtFilter::Process(u_short Pid, u_char Tid, const u_char *Data, int Length
//XXX TODO case 0x04: // NVOD reference service
//XXX TODO case 0x05: // NVOD time-shifted service
{
- char buffer[1024];
- char *p = sd->serviceName.getText(buffer);
char NameBuf[1024];
char ShortNameBuf[1024];
- char *pn = NameBuf;
- char *ps = ShortNameBuf;
- int IsShortName = 0;
- while (*p) {
- if ((uchar)*p == 0x86)
- IsShortName++;
- else if ((uchar)*p == 0x87)
- IsShortName--;
- else {
- *pn++ = *p;
- if (IsShortName)
- *ps++ = *p;
- }
- p++;
- }
- *pn = *ps = 0;
- pn = NameBuf;
+ sd->serviceName.getText(NameBuf, ShortNameBuf);
+ char *pn = compactspace(NameBuf);
+ char *ps = compactspace(ShortNameBuf);
if (*NameBuf && *ShortNameBuf && strcmp(NameBuf, ShortNameBuf) != 0) {
+ ps = ShortNameBuf + strlen(ShortNameBuf);
*ps++ = ',';
strcpy(ps, NameBuf);
pn = ShortNameBuf;
}
- pn = compactspace(pn);
- ps = compactspace(ps);
if (channel) {
channel->SetId(sdt.getOriginalNetworkId(), sdt.getTransportStreamId(), SiSdtService.getServiceId());
if (Setup.UpdateChannels >= 1)
diff --git a/svdrp.c b/svdrp.c
index b73d211..5d35eae 100644
--- a/svdrp.c
+++ b/svdrp.c
@@ -10,7 +10,7 @@
* and interact with the Video Disk Recorder - or write a full featured
* graphical interface that sits on top of an SVDRP connection.
*
- * $Id: svdrp.c 1.60 2004/02/22 15:31:23 kls Exp kls $
+ * $Id: svdrp.c 1.61 2004/02/24 12:24:43 kls Exp $
*/
#include "svdrp.h"
diff --git a/timers.c b/timers.c
index b29d6c8..6969365 100644
--- a/timers.c
+++ b/timers.c
@@ -4,14 +4,13 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.c 1.9 2004/02/13 15:37:49 kls Exp kls $
+ * $Id: timers.c 1.12 2004/03/14 13:27:57 kls Exp $
*/
#include "timers.h"
#include <ctype.h>
#include "channels.h"
#include "i18n.h"
-#include "libsi/si.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
@@ -333,8 +332,8 @@ bool cTimer::Matches(time_t t, bool Directly)
if (HasFlags(tfActive)) {
if (HasFlags(tfVps) && !Directly && event && event->Vps()) {
startTime = event->StartTime();
- stopTime = startTime + event->Duration();
- return event->RunningStatus() > SI::RunningStatusNotRunning;
+ stopTime = event->EndTime();
+ return event->IsRunning(true);
}
return startTime <= t && t < stopTime; // must stop *before* stopTime to allow adjacent timers
}
@@ -350,9 +349,14 @@ int cTimer::Matches(const cEvent *Event)
bool m1 = Matches(t1, true);
bool m2 = UseVps ? m1 : Matches(t2, true);
startTime = stopTime = 0;
- if (m1 && m2)
+ if (m1 && m2) {
+ if (UseVps && Event->IsRunning(true))
+ return tmFull;
+ if (time(NULL) > Event->EndTime())
+ return tmNone;
return tmFull;
- if (m1 || m2)
+ }
+ if ((m1 || m2) && time(NULL) <= Event->EndTime())
return tmPartial;
}
return tmNone;
@@ -381,6 +385,8 @@ void cTimer::SetEvent(const cEvent *Event)
sprintf(vpsbuf, "(VPS: %s) ", Event->GetVpsString());
isyslog("timer %d (%d %04d-%04d '%s') set to event %s %s-%s %s'%s'", Index() + 1, Channel()->Number(), start, stop, file, Event->GetDateString(), Event->GetTimeString(), Event->GetEndTimeString(), vpsbuf, Event->Title());
}
+ else
+ isyslog("timer %d (%d %04d-%04d '%s') set to no event", Index() + 1, Channel()->Number(), start, stop, file);
event = Event;
}
}
@@ -500,7 +506,7 @@ cTimer *cTimers::GetNextActiveTimer(void)
void cTimers::SetEvents(void)
{
- cSchedulesLock SchedulesLock;
+ cSchedulesLock SchedulesLock(false, 100);
const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock);
if (Schedules) {
for (cTimer *ti = First(); ti; ti = Next(ti)) {
@@ -508,19 +514,17 @@ void cTimers::SetEvents(void)
const cEvent *Event = NULL;
if (Schedule) {
//XXX what if the Schedule doesn't have any VPS???
- const cEvent *e;
int Match = tmNone;
- int i = 0;
- while ((e = Schedule->GetEventNumber(i++)) != NULL) {
- int m = ti->Matches(e);
- if (m > Match) {
- Match = m;
- Event = e;
- if (Match == tmFull)
- break;
- //XXX what if there's another event with the same VPS time???
- }
- }
+ for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) {
+ int m = ti->Matches(e);
+ if (m > Match) {
+ Match = m;
+ Event = e;
+ if (Match == tmFull)
+ break;
+ //XXX what if there's another event with the same VPS time???
+ }
+ }
}
ti->SetEvent(Event);
}
diff --git a/timers.h b/timers.h
index 11fc0b2..ce4bff6 100644
--- a/timers.h
+++ b/timers.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.h 1.6 2003/12/13 13:04:21 kls Exp kls $
+ * $Id: timers.h 1.7 2004/02/29 14:18:17 kls Exp $
*/
#ifndef __TIMERS_H
diff --git a/transfer.c b/transfer.c
index 1209dfc..c709928 100644
--- a/transfer.c
+++ b/transfer.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: transfer.c 1.15 2003/10/18 11:36:03 kls Exp $
+ * $Id: transfer.c 1.16 2004/03/07 14:40:15 kls Exp $
*/
#include "transfer.h"
@@ -55,7 +55,7 @@ void cTransfer::Receive(uchar *Data, int Length)
int i = 0;
while (active && Length > 0) {
if (i++ > 10) {
- esyslog("ERROR: ring buffer overflow (%d bytes dropped)", Length);
+ ringBuffer->ReportOverflow(Length);
break;
}
int p = ringBuffer->Put(Data, Length);
diff --git a/vdr.5 b/vdr.5
index 2947e94..e54c9f8 100644
--- a/vdr.5
+++ b/vdr.5
@@ -8,7 +8,7 @@
.\" License as specified in the file COPYING that comes with the
.\" vdr distribution.
.\"
-.\" $Id: vdr.5 1.25 2004/02/22 13:18:48 kls Exp kls $
+.\" $Id: vdr.5 1.26 2004/02/24 12:36:35 kls Exp $
.\"
.TH vdr 5 "1 Jun 2003" "1.2.0" "Video Disk Recorder Files"
.SH NAME
diff --git a/vdr.c b/vdr.c
index 5d43874..af95f37 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/vdr
*
- * $Id: vdr.c 1.177 2004/02/15 14:29:30 kls Exp kls $
+ * $Id: vdr.c 1.180 2004/03/14 14:25:02 kls Exp $
*/
#include <getopt.h>
@@ -549,10 +549,13 @@ int main(int argc, char *argv[])
PreviousChannel[PreviousChannelIndex ^= 1] = LastChannel;
// Timers and Recordings:
if (!Timers.BeingEdited()) {
- static time_t LastSetEvents = 0;//XXX trigger by actual EPG data modification???
- if (!Menu && time(NULL) - LastSetEvents > 5) {
- Timers.SetEvents();
- LastSetEvents = time(NULL);
+ // Assign events to timers:
+ if (time(NULL) - LastActivity > 10) {
+ static time_t LastSetEvents = 0;//XXX trigger by actual EPG data modification???
+ if (time(NULL) - LastSetEvents > 5) {
+ Timers.SetEvents();
+ LastSetEvents = time(NULL);
+ }
}
time_t Now = time(NULL); // must do all following calls with the exact same time!
// Process ongoing recordings:
@@ -571,7 +574,6 @@ int main(int argc, char *argv[])
if (Timer->HasFlags(tfActive | tfVps) && !Timer->Recording() && !Timer->Pending() && Timer->Matches(Now + Setup.VpsMargin, true)) {
if (!Timer->InVpsMargin()) {
Timer->SetInVpsMargin(true);
- TimerInVpsMargin = true;
//XXX if not primary device has TP???
LastTimerChannel = Timer->Channel()->Number();
cRecordControls::Start(Timer); // will only switch the device
@@ -579,6 +581,8 @@ int main(int argc, char *argv[])
}
else
Timer->SetInVpsMargin(false);
+ if (Timer->InVpsMargin())
+ TimerInVpsMargin = true;
}
}
// CAM control: