summaryrefslogtreecommitdiff
path: root/patches/vdr-1.7.27-to-epghandler-of-1.7.31.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/vdr-1.7.27-to-epghandler-of-1.7.31.patch')
-rw-r--r--patches/vdr-1.7.27-to-epghandler-of-1.7.31.patch219
1 files changed, 219 insertions, 0 deletions
diff --git a/patches/vdr-1.7.27-to-epghandler-of-1.7.31.patch b/patches/vdr-1.7.27-to-epghandler-of-1.7.31.patch
new file mode 100644
index 0000000..7be1802
--- /dev/null
+++ b/patches/vdr-1.7.27-to-epghandler-of-1.7.31.patch
@@ -0,0 +1,219 @@
+--- /home/wendel/vdr-1.7.27.plain//eit.c 2012-03-14 11:11:15.000000000 +0100
++++ eit.c 2012-10-01 09:38:51.526839349 +0200
+@@ -45,6 +45,7 @@
+ return;
+ }
+
++ bool handledExternally = EpgHandlers.HandledExternally(channel);
+ cSchedule *pSchedule = (cSchedule *)Schedules->GetSchedule(channel, true);
+
+ bool Empty = true;
+@@ -70,14 +71,18 @@
+ cEvent *newEvent = NULL;
+ cEvent *rEvent = NULL;
+ cEvent *pEvent = (cEvent *)pSchedule->GetEvent(SiEitEvent.getEventId(), StartTime);
+- if (!pEvent) {
++ if (!pEvent || handledExternally) {
+ if (OnlyRunningStatus)
+ continue;
++ if (handledExternally)
++ if (!EpgHandlers.IsUpdate(SiEitEvent.getEventId(), StartTime, Tid, getVersionNumber()))
++ continue;
+ // If we don't have that event yet, we create a new one.
+ // Otherwise we copy the information into the existing event anyway, because the data might have changed.
+ pEvent = newEvent = new cEvent(SiEitEvent.getEventId());
+ newEvent->SetStartTime(StartTime);
+ newEvent->SetDuration(Duration);
++ if (!handledExternally)
+ pSchedule->AddEvent(newEvent);
+ }
+ else {
+@@ -290,6 +295,9 @@
+ channel->SetLinkChannels(LinkChannels);
+ Modified = true;
+ EpgHandlers.HandleEvent(pEvent);
++
++ if (handledExternally)
++ delete pEvent;
+ }
+ if (Tid == 0x4E) {
+ if (Empty && getSectionNumber() == 0)
+--- /home/wendel/vdr-1.7.27.plain//epg.c 2012-03-10 14:14:27.000000000 +0100
++++ epg.c 2012-10-01 09:41:35.010845128 +0200
+@@ -18,6 +18,7 @@
+ #include "timers.h"
+
+ #define RUNNINGSTATUSTIMEOUT 30 // seconds before the running status is considered unknown
++#define EPGDATAWRITEDELTA 600 // seconds between writing the epg.data file
+
+ // --- tComponent ------------------------------------------------------------
+
+@@ -1109,6 +1110,47 @@
+ return false;
+ }
+
++// --- cEpgDataWriter ---------------------------------------------------------
++
++class cEpgDataWriter : public cThread {
++private:
++ cMutex mutex;
++protected:
++ virtual void Action(void);
++public:
++ cEpgDataWriter(void);
++ void Perform(void);
++ };
++
++cEpgDataWriter::cEpgDataWriter(void)
++:cThread("epg data writer")
++{
++}
++
++void cEpgDataWriter::Action(void)
++{
++ SetPriority(19);
++ SetIOPriority(7);
++ Perform();
++}
++
++void cEpgDataWriter::Perform(void)
++{
++ cMutexLock MutexLock(&mutex); // to make sure fore- and background calls don't cause parellel dumps!
++ {
++ cSchedulesLock SchedulesLock(true, 1000);
++ cSchedules *s = (cSchedules *)cSchedules::Schedules(SchedulesLock);
++ if (s) {
++ time_t now = time(NULL);
++ for (cSchedule *p = s->First(); p; p = s->Next(p))
++ p->Cleanup(now);
++ }
++ }
++ cSchedules::Dump();
++}
++
++static cEpgDataWriter EpgDataWriter;
++
+ // --- cSchedulesLock --------------------------------------------------------
+
+ cSchedulesLock::cSchedulesLock(bool WriteLock, int TimeoutMs)
+@@ -1152,28 +1194,13 @@
+ if (Force)
+ lastDump = 0;
+ time_t now = time(NULL);
+- struct tm tm_r;
+- struct tm *ptm = localtime_r(&now, &tm_r);
+- if (now - lastCleanup > 3600) {
+- isyslog("cleaning up schedules data");
+- cSchedulesLock SchedulesLock(true, 1000);
+- cSchedules *s = (cSchedules *)Schedules(SchedulesLock);
+- if (s) {
+- for (cSchedule *p = s->First(); p; p = s->Next(p))
+- p->Cleanup(now);
+- }
+- lastCleanup = now;
+- if (ptm->tm_hour == 5)
+- ReportEpgBugFixStats(true);
+- }
+- if (epgDataFileName && now - lastDump > 600) {
+- cSafeFile f(epgDataFileName);
+- if (f.Open()) {
+- Dump(f);
+- f.Close();
++ if (now - lastDump > EPGDATAWRITEDELTA) {
++ if (epgDataFileName) {
++ if (Force)
++ EpgDataWriter.Perform();
++ else if (!EpgDataWriter.Active())
++ EpgDataWriter.Start();
+ }
+- else
+- LOG_ERROR;
+ lastDump = now;
+ }
+ }
+@@ -1207,8 +1234,23 @@
+ cSchedulesLock SchedulesLock;
+ cSchedules *s = (cSchedules *)Schedules(SchedulesLock);
+ if (s) {
++ cSafeFile *sf = NULL;
++ if (!f) {
++ sf = new cSafeFile(epgDataFileName);
++ if (sf->Open())
++ f = *sf;
++ else {
++ LOG_ERROR;
++ delete sf;
++ return false;
++ }
++ }
+ for (cSchedule *p = s->First(); p; p = s->Next(p))
+ p->Dump(f, Prefix, DumpMode, AtTime);
++ if (sf) {
++ sf->Close();
++ delete sf;
++ }
+ return true;
+ }
+ return false;
+@@ -1329,6 +1371,24 @@
+ return true;
+ }
+ return false;
++}
++
++bool cEpgHandlers::HandledExternally(const cChannel *Channel)
++{
++ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
++ if (eh->HandledExternally(Channel))
++ return true;
++ }
++ return false;
++}
++
++bool cEpgHandlers::IsUpdate(tEventID EventID, time_t StartTime, uchar TableID, uchar Version)
++{
++ for (cEpgHandler *eh = First(); eh; eh = Next(eh)) {
++ if (eh->IsUpdate(EventID, StartTime, TableID, Version))
++ return true;
++ }
++ return false;
+ }
+
+ void cEpgHandlers::SetEventID(cEvent *Event, tEventID EventID)
+--- /home/wendel/vdr-1.7.27.plain//epg.h 2012-03-10 14:50:10.000000000 +0100
++++ epg.h 2012-10-01 09:43:28.162849134 +0200
+@@ -207,7 +207,7 @@
+ static void Cleanup(bool Force = false);
+ static void ResetVersions(void);
+ static bool ClearAll(void);
+- static bool Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0);
++ static bool Dump(FILE *f = NULL, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0);
+ static bool Read(FILE *f = NULL);
+ cSchedule *AddSchedule(tChannelID ChannelID);
+ const cSchedule *GetSchedule(tChannelID ChannelID) const;
+@@ -244,6 +244,16 @@
+ ///< EPG handlers are queried to see if any of them would like to do the
+ ///< complete processing by itself. TableID and Version are from the
+ ///< incoming section data.
++ virtual bool HandledExternally(const cChannel *Channel) { return false; }
++ ///< If any EPG handler returns true in this function, it is assumed that
++ ///< the EPG for the given Channel is handled completely from some external
++ ///< source. Incoming EIT data is processed as usual, but any new EPG event
++ ///< will not be added to the respective schedule. It's up to the EPG
++ ///< handler to take care of this.
++ virtual bool IsUpdate(tEventID EventID, time_t StartTime, uchar TableID, uchar Version) { return false; }
++ ///< VDR can't perform the update check (version, tid) for external handled events
++ ///< therefore the handle have to take care. Otherwise the parsing of 'non' updates will
++ ///< take a lot of resources
+ virtual bool SetEventID(cEvent *Event, tEventID EventID) { return false; }
+ virtual bool SetTitle(cEvent *Event, const char *Title) { return false; }
+ virtual bool SetShortText(cEvent *Event, const char *ShortText) { return false; }
+@@ -269,6 +279,8 @@
+ public:
+ bool IgnoreChannel(const cChannel *Channel);
+ bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version);
++ bool HandledExternally(const cChannel *Channel);
++ bool IsUpdate(tEventID EventID, time_t StartTime, uchar TableID, uchar Version);
+ void SetEventID(cEvent *Event, tEventID EventID);
+ void SetTitle(cEvent *Event, const char *Title);
+ void SetShortText(cEvent *Event, const char *ShortText);