From 313448ad0cd49d6f515bb53b53d6b6700b96db00 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 24 Oct 2004 15:01:50 +0200 Subject: [PATCH] Implemented 'modified' and 'seen' for EPG schedules/events --- HISTORY | 6 ++++++ eit.c | 7 +++++-- epg.c | 18 ++++++++++++++++-- epg.h | 11 ++++++++++- timers.c | 54 +++++++++++++++++++++++++++++++++--------------------- timers.h | 6 ++++-- vdr.c | 13 ++++--------- 7 files changed, 78 insertions(+), 37 deletions(-) diff --git a/HISTORY b/HISTORY index 659a59af..31d07f5e 100644 --- a/HISTORY +++ b/HISTORY @@ -3071,3 +3071,9 @@ Video Disk Recorder Revision History running. - Added cCondWait::Sleep() and using it to replace all usleep() calls (based on a suggestion by Werner Fink). +- Only assigning events to timers if the related schedule has actually been + modified. +- When searching for the present event, the running status is now only taken + into account if the event has been "seen" within the past 30 seconds. + This avoids shortly seeing the wrong events in the channel display when + switching to a channel that hasn't been tuned to in a while. diff --git a/eit.c b/eit.c index b0cbfdfe..8ff51d34 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 1.97 2004/10/16 09:49:13 kls Exp $ + * $Id: eit.c 1.98 2004/10/24 14:56:39 kls Exp $ */ #include "eit.h" @@ -59,6 +59,7 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) } else { // We have found an existing event, either through its event ID or its start time. + pEvent->SetSeen(); // If the existing event has a zero table ID it was defined externally and shall // not be overwritten. if (pEvent->TableID() == 0x00) @@ -215,8 +216,10 @@ cEIT::cEIT(cSchedules *Schedules, int Source, u_char Tid, const u_char *Data) 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 (Modified) + if (Modified) { pSchedule->Sort(); + Schedules->SetModified(pSchedule); + } } // --- cTDT ------------------------------------------------------------------ diff --git a/epg.c b/epg.c index 2768db2e..39b029e5 100644 --- a/epg.c +++ b/epg.c @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider and Rolf Hakenes . * - * $Id: epg.c 1.19 2004/05/22 12:37:07 kls Exp $ + * $Id: epg.c 1.20 2004/10/24 15:01:50 kls Exp $ */ #include "epg.h" @@ -99,6 +99,11 @@ void cEvent::SetVps(time_t Vps) vps = Vps; } +void cEvent::SetSeen(void) +{ + seen = time(NULL); +} + bool cEvent::HasTimer(void) const { for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) { @@ -478,6 +483,7 @@ cSchedule::cSchedule(tChannelID ChannelID) { channelID = ChannelID; hasRunning = false;; + modified = 0; } cEvent *cSchedule::AddEvent(cEvent *Event) @@ -496,7 +502,7 @@ const cEvent *cSchedule::GetPresentEvent(bool CheckRunningStatus) const if (!CheckRunningStatus) break; } - if (CheckRunningStatus && p->RunningStatus() >= SI::RunningStatusPausing) + if (CheckRunningStatus && time(NULL) - p->Seen() < 30 && p->RunningStatus() >= SI::RunningStatusPausing) return p; } return pe; @@ -643,6 +649,7 @@ bool cSchedule::Read(FILE *f, cSchedules *Schedules) if (!cEvent::Read(f, p)) return false; p->Sort(); + Schedules->SetModified(p); } } else { @@ -680,6 +687,7 @@ cSchedules cSchedules::schedules; const char *cSchedules::epgDataFileName = NULL; time_t cSchedules::lastCleanup = time(NULL); time_t cSchedules::lastDump = time(NULL); +time_t cSchedules::modified = 0; const cSchedules *cSchedules::Schedules(cSchedulesLock &SchedulesLock) { @@ -693,6 +701,12 @@ void cSchedules::SetEpgDataFileName(const char *FileName) epgDataFileName = strdup(FileName); } +void cSchedules::SetModified(cSchedule *Schedule) +{ + Schedule->SetModified(); + modified = time(NULL); +} + void cSchedules::Cleanup(bool Force) { if (Force) diff --git a/epg.h b/epg.h index 9a6547ef..6c31049d 100644 --- a/epg.h +++ b/epg.h @@ -7,7 +7,7 @@ * Original version (as used in VDR before 1.3.0) written by * Robert Schneider and Rolf Hakenes . * - * $Id: epg.h 1.15 2004/03/14 13:25:39 kls Exp $ + * $Id: epg.h 1.16 2004/10/24 13:56:00 kls Exp $ */ #ifndef __EPG_H @@ -36,6 +36,7 @@ private: time_t startTime; // Start time of this event int duration; // Duration of this event in seconds time_t vps; // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL) + time_t seen; // When this event was last seen in the data stream public: cEvent(tChannelID ChannelID, u_int16_t EventID); ~cEvent(); @@ -52,6 +53,7 @@ public: time_t EndTime(void) const { return startTime + duration; } int Duration(void) const { return duration; } time_t Vps(void) const { return vps; } + time_t Seen(void) const { return seen; } bool HasTimer(void) const; bool IsRunning(bool OrAboutToStart = false) const; const char *GetDateString(void) const; @@ -68,6 +70,7 @@ public: void SetStartTime(time_t StartTime); void SetDuration(int Duration); void SetVps(time_t Vps); + void SetSeen(void); void Dump(FILE *f, const char *Prefix = "") const; static bool Read(FILE *f, cSchedule *Schedule); void FixEpgBugs(void); @@ -80,9 +83,12 @@ private: tChannelID channelID; cList events; bool hasRunning; + time_t modified; public: cSchedule(tChannelID ChannelID); tChannelID ChannelID(void) const { return channelID; } + time_t Modified(void) const { return modified; } + void SetModified(void) { modified = time(NULL); } void SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel = NULL); void ClrRunningStatus(cChannel *Channel = NULL); void ResetVersions(void); @@ -117,12 +123,15 @@ private: static const char *epgDataFileName; static time_t lastCleanup; static time_t lastDump; + static time_t modified; public: static void SetEpgDataFileName(const char *FileName); static const cSchedules *Schedules(cSchedulesLock &SchedulesLock); ///< Caller must provide a cSchedulesLock which has to survive the entire ///< time the returned cSchedules is accessed. Once the cSchedules is no ///< longer used, the cSchedulesLock must be destroyed. + static time_t Modified(void) { return modified; } + static void SetModified(cSchedule *Schedule); static void Cleanup(bool Force = false); static void ResetVersions(void); static bool ClearAll(void); diff --git a/timers.c b/timers.c index ab1690a6..4c4ba213 100644 --- a/timers.c +++ b/timers.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.c 1.13 2004/07/17 12:46:27 kls Exp $ + * $Id: timers.c 1.14 2004/10/24 14:56:55 kls Exp $ */ #include "timers.h" @@ -456,6 +456,12 @@ void cTimer::OnOff(void) cTimers Timers; +cTimers::cTimers(void) +{ + beingEdited = 0;; + lastSetEvents = 0; +} + cTimer *cTimers::GetTimer(cTimer *Timer) { for (cTimer *ti = First(); ti; ti = Next(ti)) { @@ -507,29 +513,35 @@ cTimer *cTimers::GetNextActiveTimer(void) void cTimers::SetEvents(void) { + if (time(NULL) - lastSetEvents < 5) + return; cSchedulesLock SchedulesLock(false, 100); const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock); if (Schedules) { - for (cTimer *ti = First(); ti; ti = Next(ti)) { - const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel()->GetChannelID()); - const cEvent *Event = NULL; - if (Schedule) { - //XXX what if the Schedule doesn't have any VPS??? - int Match = tmNone; - for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) { - if (cRemote::HasKeys()) - return; // react immediately on user input - int m = ti->Matches(e); - if (m > Match) { - Match = m; - Event = e; - if (Match == tmFull) - break; - //XXX what if there's another event with the same VPS time??? - } - } + if (!lastSetEvents || Schedules->Modified() >= lastSetEvents) { + for (cTimer *ti = First(); ti; ti = Next(ti)) { + const cSchedule *Schedule = Schedules->GetSchedule(ti->Channel()->GetChannelID()); + if (Schedule) { + if (!lastSetEvents || Schedule->Modified() >= lastSetEvents) { + const cEvent *Event = NULL; + int Match = tmNone; + for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) { + if (cRemote::HasKeys()) + return; // react immediately on user input + int m = ti->Matches(e); + if (m > Match) { + Match = m; + Event = e; + if (Match == tmFull) + break; + //XXX what if there's another event with the same VPS time??? + } + } + ti->SetEvent(Event); + } + } } - ti->SetEvent(Event); - } + } } + lastSetEvents = time(NULL); } diff --git a/timers.h b/timers.h index ce4bff60..cbc6a92f 100644 --- a/timers.h +++ b/timers.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: timers.h 1.7 2004/02/29 14:18:17 kls Exp $ + * $Id: timers.h 1.8 2004/10/24 14:40:37 kls Exp $ */ #ifndef __TIMERS_H @@ -93,14 +93,16 @@ public: class cTimers : public cConfig { private: int beingEdited; + time_t lastSetEvents; public: + cTimers(void); cTimer *GetTimer(cTimer *Timer); cTimer *GetMatch(time_t t); cTimer *GetMatch(const cEvent *Event, int *Match = NULL); cTimer *GetNextActiveTimer(void); int BeingEdited(void) { return beingEdited; } void IncBeingEdited(void) { beingEdited++; } - void DecBeingEdited(void) { beingEdited--; } + void DecBeingEdited(void) { if (!--beingEdited) lastSetEvents = 0; } void SetEvents(void); }; diff --git a/vdr.c b/vdr.c index 8ca7b5e6..033f186b 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/vdr * - * $Id: vdr.c 1.189 2004/10/23 15:04:52 kls Exp $ + * $Id: vdr.c 1.190 2004/10/24 14:01:11 kls Exp $ */ #include @@ -581,14 +581,9 @@ int main(int argc, char *argv[]) // Timers and Recordings: if (!Timers.BeingEdited()) { // Assign events to timers: - if (time(NULL) - LastActivity > 10) { - static time_t LastSetEvents = 0;//XXX trigger by actual EPG data modification??? - if (time(NULL) - LastSetEvents > 5) { - Timers.SetEvents(); - LastSetEvents = time(NULL); - } - } - time_t Now = time(NULL); // must do all following calls with the exact same time! + Timers.SetEvents(); + // Must do all following calls with the exact same time! + time_t Now = time(NULL); // Process ongoing recordings: cRecordControls::Process(Now); // Start new recordings: