Improved efficiency of cEIT::cEIT()

This commit is contained in:
Klaus Schmidinger 2009-04-12 09:09:47 +02:00
parent af89f39e82
commit ffc0f49c12
3 changed files with 25 additions and 20 deletions

View File

@ -2302,6 +2302,7 @@ Tobias Bratfisch <tobias@reel-multimedia.com>
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 <bruno.roussel@free.fr>
for translating OSD texts to the French language

View File

@ -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).

41
eit.c
View File

@ -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 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) {