diff --git a/CONTRIBUTORS b/CONTRIBUTORS index a9c61d2c..15a605e3 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -2302,6 +2302,7 @@ Tobias Bratfisch for optimizing cMenuEditChrItem::Set() for optimizing cNitFilter::Process() for reducing the number of time(NULL) calls in vdr.c's main loop to a single call + for improving efficiency of cEIT::cEIT() Bruno Roussel for translating OSD texts to the French language diff --git a/HISTORY b/HISTORY index 71780fc2..086c92af 100644 --- a/HISTORY +++ b/HISTORY @@ -5979,7 +5979,7 @@ Video Disk Recorder Revision History cDevice class reimplements PlayTs() or PlayPes(), it also needs to make sure this new function works as expected. -2009-04-10: Version 1.7.5 +2009-04-12: Version 1.7.5 - Fixed a hangup when replaying a TS recording with subtitles activated (reported by Timo Helkio). @@ -6029,3 +6029,4 @@ Video Disk Recorder Revision History Endriss). - No longer writing the video type into channels.conf if VPID is 0 (thanks to Oliver Endriss for reporting this). +- Improved efficiency of cEIT::cEIT() (thanks to Tobias Bratfisch). diff --git a/eit.c b/eit.c index 774b6671..b78c1179 100644 --- a/eit.c +++ b/eit.c @@ -8,7 +8,7 @@ * Robert Schneider and Rolf Hakenes . * Adapted to 'libsi' for VDR 1.3.0 by Marcel Wiesweg . * - * $Id: eit.c 2.2 2008/05/01 15:33:27 kls Exp $ + * $Id: eit.c 2.3 2009/04/11 10:03:24 kls Exp $ */ #include "eit.h" @@ -42,20 +42,25 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo bool HasExternalData = false; time_t SegmentStart = 0; time_t SegmentEnd = 0; + time_t Now = time(NULL); + struct tm tm_r; + struct tm t = *localtime_r(&Now, &tm_r); // this initializes the time zone in 't' SI::EIT::Event SiEitEvent; for (SI::Loop::Iterator it; eventLoop.getNext(SiEitEvent, it); ) { bool ExternalData = false; + int StartTime = SiEitEvent.getStartTime(); + int Duration = SiEitEvent.getDuration(); // Drop bogus events - but keep NVOD reference events, where all bits of the start time field are set to 1, resulting in a negative number. - if (SiEitEvent.getStartTime() == 0 || SiEitEvent.getStartTime() > 0 && SiEitEvent.getDuration() == 0) + if (StartTime == 0 || StartTime > 0 && Duration == 0) continue; Empty = false; if (!SegmentStart) - SegmentStart = SiEitEvent.getStartTime(); - SegmentEnd = SiEitEvent.getStartTime() + SiEitEvent.getDuration(); + SegmentStart = StartTime; + SegmentEnd = StartTime + Duration; cEvent *newEvent = NULL; cEvent *rEvent = NULL; - cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), SiEitEvent.getStartTime()); + cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), StartTime); if (!pEvent) { if (OnlyRunningStatus) continue; @@ -70,14 +75,15 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo pEvent->SetSeen(); // If the existing event has a zero table ID it was defined externally and shall // not be overwritten. - if (pEvent->TableID() == 0x00) { + uchar TableID = pEvent->TableID(); + if (TableID == 0x00) { if (pEvent->Version() == getVersionNumber()) continue; HasExternalData = ExternalData = true; } // If the new event has a higher table ID, let's skip it. // The lower the table ID, the more "current" the information. - else if (Tid > pEvent->TableID()) + else if (Tid > TableID) continue; // If the new event comes from the same table and has the same version number // as the existing one, let's skip it to avoid unnecessary work. @@ -85,14 +91,14 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo // the actual Premiere transponder and the Sat.1/Pro7 transponder), but use different version numbers on // each of them :-( So if one DVB card is tuned to the Premiere transponder, while an other one is tuned // to the Sat.1/Pro7 transponder, events will keep toggling because of the bogus version numbers. - else if (Tid == pEvent->TableID() && pEvent->Version() == getVersionNumber()) + else if (Tid == TableID && pEvent->Version() == getVersionNumber()) continue; } if (!ExternalData) { pEvent->SetEventID(SiEitEvent.getEventId()); // unfortunately some stations use different event ids for the same event in different tables :-( pEvent->SetTableID(Tid); - pEvent->SetStartTime(SiEitEvent.getStartTime()); - pEvent->SetDuration(SiEitEvent.getDuration()); + pEvent->SetStartTime(StartTime); + pEvent->SetDuration(Duration); } if (newEvent) pSchedule->AddEvent(newEvent); @@ -148,9 +154,6 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo break; case SI::PDCDescriptorTag: { SI::PDCDescriptor *pd = (SI::PDCDescriptor *)d; - time_t now = time(NULL); - 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; @@ -183,8 +186,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo SI::LinkageDescriptor *ld = (SI::LinkageDescriptor *)d; tChannelID linkID(Source, ld->getOriginalNetworkId(), ld->getTransportStreamId(), ld->getServiceId()); if (ld->getLinkageType() == 0xB0) { // Premiere World - time_t now = time(NULL); - bool hit = SiEitEvent.getStartTime() <= now && now < SiEitEvent.getStartTime() + SiEitEvent.getDuration(); + bool hit = StartTime <= Now && Now < StartTime + Duration; if (hit) { char linkName[ld->privateData.getLength() + 1]; strn0cpy(linkName, (const char *)ld->privateData.getData(), sizeof(linkName)); @@ -260,11 +262,12 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data, bo channel->SetLinkChannels(LinkChannels); 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 (Tid == 0x4E) + if (Tid == 0x4E) { + if (Empty && getSectionNumber() == 0) + // ETR 211: an empty entry in section 0 of table 0x4E means there is currently no event running + pSchedule->ClrRunningStatus(channel); pSchedule->SetPresentSeen(); + } if (OnlyRunningStatus) return; if (Modified) {