diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-02-24 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-02-24 18:00:00 +0100 |
commit | fb8e7fa302ef8a73feb6958b0cb32cc54f76e677 (patch) | |
tree | 74cf9dd5cd1892aaf1c05db32796eb356d7bc860 /eit.c | |
parent | a1da0e5c5de55009716e2c327dda16c61c1dae83 (diff) | |
download | vdr-patch-lnbsharing-fb8e7fa302ef8a73feb6958b0cb32cc54f76e677.tar.gz vdr-patch-lnbsharing-fb8e7fa302ef8a73feb6958b0cb32cc54f76e677.tar.bz2 |
Version 1.0.0pre1vdr-1.0.0pre1
- Added scanning for EPG data for another 4 days on channels that support this
(thanks to Oleg Assovski).
- Removed '#define VFAT 1' from recording.c (was a leftover from testing).
- Fixed the "Low disk space!" message (thanks to Sergei Haller).
- Added the TPID to Hessen-3 in 'channels.conf' (thanks to Sergei Haller).
- Fixed a crash when replaying with DEBUG_OSD=1 (thanks to Stefan Huelswitt).
- Implemented the "First day" parameter for repeating timers. See FORMATS for
information about the enhanced 'timers.conf' file format, and MANUAL for
a description of the new item in the "Edit Timer" menu and the enhanced
functionality of the "Blue" button in the "Timers" menu.
- When deleting a recording that is currently still being recorded, the related
timer will now automatically be terminated. If this is a repeating timer, it
will receive a "First day" setting that skips the timer for this day.
- Fixed closing all unused file descriptors when opening a pipe (thanks to
Werner Fink).
- Instant recordings now take the EPG data from the point in time at 5 minutes
from the start time of the recording. In order for this to work the 'active'
parameter of a timer now uses the second bit to indicate that this is an
"instant" recording (see FORMATS for details).
- Fixed the SVDRP GRAB command in case the video device can't be opened (thanks
to Adrian Stabiszewski).
- At startup the data written into 'epg.data' is now read into the EPG data
structures. In order for this to work, the 'E' record has been extended to
(optionally) contain the 'table ID' (see FORMATS for details).
- The new SVDRP command PUTE can be used to put EPG data into the EPG list.
See FORMATS for details about the required data format.
- Taking the German umlauts 'as is' when compiled with VFAT.
- The new Setup parameter RecordDolbyDigital can be used to generally turn off
recording the Dolby Digital audio channels in case you want to save disk space
or don't have the equipment to replay Dolby Digital audio.
- Reading the 'setup.conf' file no longer terminates in case of an error, but
rather attempts to read the rest of the file.
- Removed DVD support from the core VDR source, since the current version from
Andreas Schultz is already much further developed (DVD menu navigation) and
the concept of "additional players" in VDR is going to change in version 1.1.0,
where a new "plugin" interface shall allow the easy implementation of new
players without having to patch the core VDR source. Until then, Andreas has
agreed to provide his DVD support as a completely external patch.
- The contents of the distribution archive now contains the directory name with
the current version number, as in 'vdr-1.0.0pre1/...' in order to avoid
inadvertently overwriting an existing VDR directory with a new version.
- Added a missing error message in SVDRP command LSTC in case the given channel
can't be found.
Diffstat (limited to 'eit.c')
-rw-r--r-- | eit.c | 136 |
1 files changed, 127 insertions, 9 deletions
@@ -16,7 +16,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.34 2002/02/09 14:48:43 kls Exp $ + * $Id: eit.c 1.37 2002/02/23 17:11:19 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -341,7 +341,7 @@ unsigned short cEventInfo::GetServiceID() const void cEventInfo::Dump(FILE *f, const char *Prefix) const { if (tTime + lDuration >= time(NULL)) { - fprintf(f, "%sE %u %ld %ld\n", Prefix, uEventID, tTime, lDuration); + fprintf(f, "%sE %u %ld %ld %X\n", Prefix, uEventID, tTime, lDuration, uTableID); if (!isempty(pTitle)) fprintf(f, "%sT %s\n", Prefix, pTitle); if (!isempty(pSubtitle)) @@ -352,6 +352,54 @@ void cEventInfo::Dump(FILE *f, const char *Prefix) const } } +bool cEventInfo::Read(FILE *f, cSchedule *Schedule) +{ + if (Schedule) { + cEventInfo *pEvent = NULL; + char *s; + while ((s = readline(f)) != NULL) { + char *t = skipspace(s + 1); + switch (*s) { + case 'E': if (!pEvent) { + unsigned int uEventID; + time_t tTime; + long lDuration; + unsigned int uTableID = 0; + int n = sscanf(t, "%u %ld %ld %X", &uEventID, &tTime, &lDuration, &uTableID); + if (n == 3 || n == 4) { + pEvent = (cEventInfo *)Schedule->GetEvent(uEventID, tTime); + if (!pEvent) + pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetServiceID(), uEventID)); + if (pEvent) { + pEvent->SetTableID(uTableID); + pEvent->SetTime(tTime); + pEvent->SetDuration(lDuration); + } + } + } + break; + case 'T': if (pEvent) + pEvent->SetTitle(t); + break; + case 'S': if (pEvent) + pEvent->SetSubtitle(t); + break; + case 'D': if (pEvent) + pEvent->SetExtendedDescription(t); + break; + case 'e': pEvent = NULL; + break; + case 'c': // to keep things simple we react on 'c' here + return false; + default: esyslog(LOG_ERR, "ERROR: unexpected tag while reading EPG data: %s", s); + return false; + } + } + return true; + } + return false; +} + #define MAXEPGBUGFIXSTATS 5 #define MAXEPGBUGFIXCHANS 50 struct tEpgBugFixStats { @@ -545,6 +593,13 @@ cSchedule::cSchedule(unsigned short servid) cSchedule::~cSchedule() { } + +cEventInfo *cSchedule::AddEvent(cEventInfo *EventInfo) +{ + Events.Add(EventInfo); + return EventInfo; +} + /** */ const cEventInfo * cSchedule::GetPresentEvent() const { @@ -689,6 +744,31 @@ void cSchedule::Dump(FILE *f, const char *Prefix) const } } +bool cSchedule::Read(FILE *f, cSchedules *Schedules) +{ + if (Schedules) { + char *s; + while ((s = readline(f)) != NULL) { + if (*s == 'C') { + unsigned int uServiceID; + if (1 == sscanf(s + 1, "%u", &uServiceID)) { + cSchedule *p = (cSchedule *)Schedules->SetCurrentServiceID(uServiceID); + if (p) { + while (cEventInfo::Read(f, p)) + ; // loop stops after having read the closing 'c' + } + } + } + else { + esyslog(LOG_ERR, "ERROR: unexpected tag while reading EPG data: %s", s); + return false; + } + } + return true; + } + return false; +} + // --- cSchedules ------------------------------------------------------------ cSchedules::cSchedules() @@ -701,7 +781,7 @@ cSchedules::~cSchedules() { } /** */ -bool cSchedules::SetCurrentServiceID(unsigned short servid) +const cSchedule *cSchedules::SetCurrentServiceID(unsigned short servid) { pCurrentSchedule = GetSchedule(servid); if (pCurrentSchedule == NULL) @@ -709,12 +789,12 @@ bool cSchedules::SetCurrentServiceID(unsigned short servid) Add(new cSchedule(servid)); pCurrentSchedule = GetSchedule(servid); if (pCurrentSchedule == NULL) - return false; + return NULL; } uCurrentServiceID = servid; - return true; + return pCurrentSchedule; } /** */ const cSchedule * cSchedules::GetSchedule() const @@ -757,6 +837,13 @@ void cSchedules::Dump(FILE *f, const char *Prefix) const p->Dump(f, Prefix); } +/** */ +bool cSchedules::Read(FILE *f) +{ + cMutexLock MutexLock; + return cSchedule::Read(f, (cSchedules *)cSIProcessor::Schedules(MutexLock)); +} + // --- cEIT ------------------------------------------------------------------ class cEIT { @@ -822,17 +909,20 @@ int cEIT::ProcessEIT(unsigned char *buffer) if (!pEvent) { // If we don't have that event ID yet, we create a new one. // Otherwise we copy the information into the existing event anyway, because the data might have changed. - pSchedule->Events.Add(new cEventInfo(VdrProgramInfo->ServiceID, VdrProgramInfo->EventID)); - pEvent = (cEventInfo *)pSchedule->GetEvent((unsigned short)VdrProgramInfo->EventID); + pEvent = pSchedule->AddEvent(new cEventInfo(VdrProgramInfo->ServiceID, VdrProgramInfo->EventID)); if (!pEvent) break; pEvent->SetTableID(tid); } else { // We have found an existing event, either through its event ID or its start time. + // If the existing event has a zero table ID it was defined externally and shall + // not be overwritten. + if (pEvent->GetTableID() == 0x00) + continue; // If the new event comes from a table that belongs to an "other TS" and the existing - // one comes from a "actual TS" table, lets skip it. - if ((tid == 0x4F || tid == 0x60) && (pEvent->GetTableID() == 0x4E || pEvent->GetTableID() == 0x50)) + // one comes from an "actual TS" table, lets skip it. + if ((tid == 0x4F || tid == 0x60 || tid == 0x61) && (pEvent->GetTableID() == 0x4E || pEvent->GetTableID() == 0x50 || pEvent->GetTableID() == 0x51)) continue; } if (rEvent) { @@ -913,6 +1003,32 @@ cSIProcessor::~cSIProcessor() delete fileName; } +const cSchedules *cSIProcessor::Schedules(cMutexLock &MutexLock) +{ + if (MutexLock.Lock(&schedulesMutex)) + return schedules; + return NULL; +} + +bool cSIProcessor::Read(FILE *f) +{ + bool OwnFile = f == NULL; + if (OwnFile) { + const char *FileName = GetEpgDataFileName(); + if (access(FileName, R_OK) == 0) { + dsyslog(LOG_INFO, "reading EPG data from %s", FileName); + if ((f = fopen(FileName, "r")) == NULL) { + LOG_ERROR; + return false; + } + } + } + bool result = cSchedules::Read(f); + if (OwnFile) + fclose(f); + return result; +} + void cSIProcessor::SetEpgDataFileName(const char *FileName) { epgDataFileName = NULL; @@ -940,6 +1056,8 @@ void cSIProcessor::SetStatus(bool On) AddFilter(0x12, 0x4f); // event info, other TS, present/following AddFilter(0x12, 0x50); // event info, actual TS, schedule AddFilter(0x12, 0x60); // event info, other TS, schedule + AddFilter(0x12, 0x51); // event info, actual TS, schedule for another 4 days + AddFilter(0x12, 0x61); // event info, other TS, schedule for another 4 days } schedulesMutex.Unlock(); } |