diff options
author | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-11-10 18:00:00 +0100 |
---|---|---|
committer | Klaus Schmidinger <kls (at) cadsoft (dot) de> | 2002-11-10 18:00:00 +0100 |
commit | 8b5d4040832f9a11119002fef5144a7d6705f19c (patch) | |
tree | d0b31418030bfefc8a2ce0d72e269e19ab2aa8d0 /eit.c | |
parent | 1a8a081629b736572a8f6489428975cf54448e67 (diff) | |
download | vdr-patch-lnbsharing-8b5d4040832f9a11119002fef5144a7d6705f19c.tar.gz vdr-patch-lnbsharing-8b5d4040832f9a11119002fef5144a7d6705f19c.tar.bz2 |
Version 1.1.16vdr-1.1.16
- Fixed saving the polarization parameter of channels that have a number in the
'source' parameter (thanks to Peter Seyringer for reporting this one).
- Updated 'channels.conf.terr' (thanks to Andy Carter).
- Updated 'channels.conf.cable' (thanks to Achim Lange).
- First step towards a "unique channel ID". The channel ID is a human readable
string, made up from several parameters of the channel's definition in the file
'channels.conf' (see man vdr(5) for details).
In order for the "unique channel ID" to work, all channel definitions now must
be unique with respect to the combination of their Source, Frequency and SID
parameters. You may have to fix your 'channels.conf' manually if there are error
messages in the log file when loading it. BE SURE TO MAKE A BACKUP COPY OF YOUR
'channels.conf' AND 'timers.conf' FILE BEFORE SWITCHING TO THIS VERSION, AND CHECK
VERY CAREFULLY WHETHER YOUR TIMERS ARE STILL SET TO THE RIGHT CHANNELS!
When reading an existing 'timers.conf', the channels will be identified as before
by their numbers. As soon as this file is written back, the channel numbers will
be replaced by the channel IDs. After that it is possible to manually edit the
'channels.conf' file and rearrange the channels without breaking the timers.
Note that you can still define new timers manually by using the channel number.
VDR will correctly identify the 'channel' parameter in a timer definition and
use it as a channel number or a channel ID, respectively. Also, the SVDRP commands
that return timer definitions will list them with channel numbers in order to
stay compatible with existing applications.
The channel ID is also used in the 'epg.data' file to allow EPG information from
different sources to be stored, which would previously have been mixed up in case
they were using the same 'service ID'. Note that the contents of an existing
'epg.data' file from a previous version will be silently ignored, since it doesn't
contain the new channel IDs. When inserting EPG data into VDR via SVDRP you now also
need to use the channel IDs.
Currently the EPG data received from the DVB data stream only uses the 'Source'
and 'Service ID' part of the channel ID. This makes it work for channels with
the same service IDs on different sources (like satellites, cable or terrestrial).
However, it doesn't work yet if the service IDs are not unique within a specific
source. This will be fixed later.
- Added missing SID parameters to 'channels.conf'. Some channels have been removed
since they are apparently no longer broadcasted.
- Removed dropping EPG events from "other" streams that have a duration of 86400
seconds or more (was introduced in version 1.1.10). This has become obsolete by
the modification in version 1.1.13, which fixed fetching the current/next information
to handle cases where the duration of an event is set wrongly and would last beyond
the start time of the next event. Besides, the change in 1.1.10 broke handling EPG
data for NVOD channels.
- Fixed a compiler warning regarding cMenuChannels::Del() and MenuTimers::Del() hiding
the base class virtual functions.
Diffstat (limited to 'eit.c')
-rw-r--r-- | eit.c | 128 |
1 files changed, 71 insertions, 57 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.59 2002/11/02 12:46:53 kls Exp $ + * $Id: eit.c 1.60 2002/11/10 15:50:21 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -180,7 +180,7 @@ bool cTDT::SetSystemTime() // --- cEventInfo ------------------------------------------------------------ -cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid) +cEventInfo::cEventInfo(uint64 channelid, unsigned short eventid) { pTitle = NULL; pSubtitle = NULL; @@ -190,7 +190,7 @@ cEventInfo::cEventInfo(unsigned short serviceid, unsigned short eventid) tTime = 0; uTableID = 0; uEventID = eventid; - uServiceID = serviceid; + uChannelID = channelid; nChannelNumber = 0; } @@ -325,15 +325,15 @@ void cEventInfo::SetEventID(unsigned short evid) uEventID = evid; } /** */ -void cEventInfo::SetServiceID(unsigned short servid) +void cEventInfo::SetChannelID(uint64 channelid) { - uServiceID = servid; + uChannelID = channelid; } /** */ -unsigned short cEventInfo::GetServiceID() const +uint64 cEventInfo::GetChannelID() const { - return uServiceID; + return uChannelID; } /** */ @@ -368,7 +368,7 @@ bool cEventInfo::Read(FILE *f, cSchedule *Schedule) if (n == 3 || n == 4) { pEvent = (cEventInfo *)Schedule->GetEvent(uEventID, tTime); if (!pEvent) - pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetServiceID(), uEventID)); + pEvent = Schedule->AddEvent(new cEventInfo(Schedule->GetChannelID(), uEventID)); if (pEvent) { pEvent->SetTableID(uTableID); pEvent->SetTime(tTime); @@ -404,24 +404,24 @@ bool cEventInfo::Read(FILE *f, cSchedule *Schedule) struct tEpgBugFixStats { int hits; int n; - unsigned short serviceIDs[MAXEPGBUGFIXCHANS]; + uint64 channelIDs[MAXEPGBUGFIXCHANS]; tEpgBugFixStats(void) { hits = n = 0; } }; tEpgBugFixStats EpgBugFixStats[MAXEPGBUGFIXSTATS]; -static void EpgBugFixStat(int Number, unsigned int ServiceID) +static void EpgBugFixStat(int Number, uint64 ChannelID) { if (0 <= Number && Number < MAXEPGBUGFIXSTATS) { tEpgBugFixStats *p = &EpgBugFixStats[Number]; p->hits++; int i = 0; for (; i < p->n; i++) { - if (p->serviceIDs[i] == ServiceID) + if (p->channelIDs[i] == ChannelID) break; } if (i == p->n && p->n < MAXEPGBUGFIXCHANS) - p->serviceIDs[p->n++] = ServiceID; + p->channelIDs[p->n++] = ChannelID; } } @@ -448,7 +448,7 @@ static void ReportEpgBugFixStats(bool Reset = false) char *q = buffer; q += snprintf(q, sizeof(buffer) - (q - buffer), "%d\t%d", i, p->hits); for (int c = 0; c < p->n; c++) { - cChannel *channel = Channels.GetByServiceID(p->serviceIDs[c]); + cChannel *channel = Channels.GetByChannelID(p->channelIDs[c]); if (channel) { q += snprintf(q, sizeof(buffer) - (q - buffer), "%s%s", delim, channel->Name()); delim = ", "; @@ -499,7 +499,7 @@ void cEventInfo::FixEpgBugs(void) char *s = e ? strdup(e) : NULL; free(pSubtitle); pSubtitle = s; - EpgBugFixStat(0, GetServiceID()); + EpgBugFixStat(0, GetChannelID()); // now the fixes #1 and #2 below will handle the rest } } @@ -524,7 +524,7 @@ void cEventInfo::FixEpgBugs(void) free(pExtendedDescription); pSubtitle = s; pExtendedDescription = d; - EpgBugFixStat(1, GetServiceID()); + EpgBugFixStat(1, GetChannelID()); } } } @@ -541,7 +541,7 @@ void cEventInfo::FixEpgBugs(void) memmove(pSubtitle, pSubtitle + 1, strlen(pSubtitle)); pExtendedDescription = pSubtitle; pSubtitle = NULL; - EpgBugFixStat(2, GetServiceID()); + EpgBugFixStat(2, GetChannelID()); } } @@ -553,7 +553,7 @@ void cEventInfo::FixEpgBugs(void) if (pSubtitle && strcmp(pTitle, pSubtitle) == 0) { free(pSubtitle); pSubtitle = NULL; - EpgBugFixStat(3, GetServiceID()); + EpgBugFixStat(3, GetChannelID()); } // ZDF.info puts the Subtitle between double quotes, which is nothing @@ -569,7 +569,7 @@ void cEventInfo::FixEpgBugs(void) char *p = strrchr(pSubtitle, '"'); if (p) *p = 0; - EpgBugFixStat(4, GetServiceID()); + EpgBugFixStat(4, GetChannelID()); } } @@ -590,7 +590,7 @@ void cEventInfo::FixEpgBugs(void) if (*p == '-' && *(p + 1) == ' ' && *(p + 2) && islower(*(p - 1)) && islower(*(p + 2))) { if (!startswith(p + 2, "und ")) { // special case in German, as in "Lach- und Sachgeschichten" memmove(p, p + 2, strlen(p + 2) + 1); - EpgBugFixStat(5, GetServiceID()); + EpgBugFixStat(5, GetChannelID()); } } p++; @@ -608,10 +608,10 @@ void cEventInfo::FixEpgBugs(void) // --- cSchedule ------------------------------------------------------------- -cSchedule::cSchedule(unsigned short servid) +cSchedule::cSchedule(uint64 channelid) { pPresent = pFollowing = NULL; - uServiceID = servid; + uChannelID = channelid; } @@ -645,14 +645,14 @@ const cEventInfo *cSchedule::GetFollowingEvent(void) const return pe; } -void cSchedule::SetServiceID(unsigned short servid) +void cSchedule::SetChannelID(uint64 channelid) { - uServiceID = servid; + uChannelID = channelid; } /** */ -unsigned short cSchedule::GetServiceID() const +uint64 cSchedule::GetChannelID() const { - return uServiceID; + return uChannelID; } /** */ const cEventInfo * cSchedule::GetEvent(unsigned short uEventID, time_t tTime) const @@ -735,10 +735,10 @@ void cSchedule::Cleanup(time_t tTime) /** */ void cSchedule::Dump(FILE *f, const char *Prefix) const { - cChannel *channel = Channels.GetByServiceID(uServiceID); + cChannel *channel = Channels.GetByChannelID(uChannelID); if (channel) { - fprintf(f, "%sC %u %s\n", Prefix, uServiceID, channel->Name()); + fprintf(f, "%sC %s %s\n", Prefix, channel->GetChannelIDStr(), channel->Name()); for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) p->Dump(f, Prefix); fprintf(f, "%sc\n", Prefix); @@ -751,12 +751,22 @@ bool cSchedule::Read(FILE *f, cSchedules *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->AddServiceID(uServiceID); - if (p) { - if (!cEventInfo::Read(f, p)) - return false; + s = skipspace(s + 1); + char *p = strchr(s, ' '); + if (p) + *p = 0; // strips optional channel name + if (*s) { + uint64 uChannelID = cChannel::StringToChannelID(s); + if (uChannelID) { + cSchedule *p = (cSchedule *)Schedules->AddChannelID(uChannelID); + if (p) { + if (!cEventInfo::Read(f, p)) + return false; + } + } + else { + esyslog("ERROR: illegal channel ID: %s", s); + return false; } } } @@ -775,28 +785,28 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules) cSchedules::cSchedules() { pCurrentSchedule = NULL; - uCurrentServiceID = 0; + uCurrentChannelID = 0; } cSchedules::~cSchedules() { } /** */ -const cSchedule *cSchedules::AddServiceID(unsigned short servid) +const cSchedule *cSchedules::AddChannelID(uint64 channelid) { - const cSchedule *p = GetSchedule(servid); + const cSchedule *p = GetSchedule(channelid); if (!p) { - Add(new cSchedule(servid)); - p = GetSchedule(servid); + Add(new cSchedule(channelid)); + p = GetSchedule(channelid); } return p; } /** */ -const cSchedule *cSchedules::SetCurrentServiceID(unsigned short servid) +const cSchedule *cSchedules::SetCurrentChannelID(uint64 channelid) { - pCurrentSchedule = AddServiceID(servid); + pCurrentSchedule = AddChannelID(channelid); if (pCurrentSchedule) - uCurrentServiceID = servid; + uCurrentChannelID = channelid; return pCurrentSchedule; } /** */ @@ -805,14 +815,14 @@ const cSchedule * cSchedules::GetSchedule() const return pCurrentSchedule; } /** */ -const cSchedule * cSchedules::GetSchedule(unsigned short servid) const +const cSchedule * cSchedules::GetSchedule(uint64 channelid) const { cSchedule *p; p = First(); while (p != NULL) { - if (p->GetServiceID() == servid) + if (p->GetChannelID() == channelid) return p; p = Next(p); } @@ -856,7 +866,7 @@ public: cEIT(unsigned char *buf, int length, cSchedules *Schedules); ~cEIT(); /** */ - int ProcessEIT(unsigned char *buffer); + int ProcessEIT(unsigned char *buffer, int CurrentSource); protected: // Protected methods /** returns true if this EIT covers a @@ -879,7 +889,7 @@ cEIT::~cEIT() } /** */ -int cEIT::ProcessEIT(unsigned char *buffer) +int cEIT::ProcessEIT(unsigned char *buffer, int CurrentSource) { cEventInfo *pEvent, *rEvent = NULL; cSchedule *pSchedule, *rSchedule = NULL; @@ -893,18 +903,19 @@ int cEIT::ProcessEIT(unsigned char *buffer) if (VdrProgramInfos) { for (VdrProgramInfo = (struct VdrProgramInfo *) VdrProgramInfos->Head; VdrProgramInfo; VdrProgramInfo = (struct VdrProgramInfo *) xSucc (VdrProgramInfo)) { - // Drop events that belong to an "other TS" and are very long (some stations broadcast bogus data for "other" channels): - if (VdrProgramInfo->Duration >= 86400 && (tid == 0x4F || tid == 0x60 || tid == 0x61)) - continue; - pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID); + //XXX TODO use complete channel ID + cChannel *channel = Channels.GetByServiceID(CurrentSource, VdrProgramInfo->ServiceID); + uint64 channelID = channel ? channel->GetChannelID() : (uint64(CurrentSource) << 48) | VdrProgramInfo->ServiceID; + //XXX + pSchedule = (cSchedule *)schedules->GetSchedule(channelID); if (!pSchedule) { - schedules->Add(new cSchedule(VdrProgramInfo->ServiceID)); - pSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ServiceID); + schedules->Add(new cSchedule(channelID)); + pSchedule = (cSchedule *)schedules->GetSchedule(channelID); if (!pSchedule) break; } if (VdrProgramInfo->ReferenceServiceID) { - rSchedule = (cSchedule *)schedules->GetSchedule(VdrProgramInfo->ReferenceServiceID); + rSchedule = (cSchedule *)schedules->GetSchedule((uint64(CurrentSource) << 48) | VdrProgramInfo->ReferenceServiceID); if (!rSchedule) break; rEvent = (cEventInfo *)rSchedule->GetEvent((unsigned short)VdrProgramInfo->ReferenceEventID); @@ -915,7 +926,7 @@ 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. - pEvent = pSchedule->AddEvent(new cEventInfo(VdrProgramInfo->ServiceID, VdrProgramInfo->EventID)); + pEvent = pSchedule->AddEvent(new cEventInfo(channelID, VdrProgramInfo->EventID)); if (!pEvent) break; pEvent->SetTableID(tid); @@ -988,6 +999,8 @@ cSIProcessor::cSIProcessor(const char *FileName) { fileName = strdup(FileName); masterSIProcessor = numSIProcessors == 0; // the first one becomes the 'master' + currentSource = 0; + currentTransponder = 0; filters = NULL; if (!numSIProcessors++) // the first one creates it schedules = new cSchedules; @@ -1167,7 +1180,7 @@ void cSIProcessor::Action() { cMutexLock MutexLock(&schedulesMutex); cEIT ceit(buf, seclen, schedules); - ceit.ProcessEIT(buf); + ceit.ProcessEIT(buf, currentSource); } else dsyslog("Received stuffing section in EIT\n"); @@ -1250,16 +1263,17 @@ bool cSIProcessor::ShutDownFilters(void) } /** */ -void cSIProcessor::SetCurrentTransponder(int CurrentTransponder) +void cSIProcessor::SetCurrentTransponder(int CurrentSource, int CurrentTransponder) { + currentSource = CurrentSource; currentTransponder = CurrentTransponder; } /** */ -bool cSIProcessor::SetCurrentServiceID(unsigned short servid) +bool cSIProcessor::SetCurrentChannelID(uint64 channelid) { cMutexLock MutexLock(&schedulesMutex); - return schedules ? schedules->SetCurrentServiceID(servid) : false; + return schedules ? schedules->SetCurrentChannelID(channelid) : false; } void cSIProcessor::TriggerDump(void) |