vdr  1.7.27
epg.h
Go to the documentation of this file.
00001 /*
00002  * epg.h: Electronic Program Guide
00003  *
00004  * See the main source file 'vdr.c' for copyright information and
00005  * how to reach the author.
00006  *
00007  * Original version (as used in VDR before 1.3.0) written by
00008  * Robert Schneider <Robert.Schneider@web.de> and Rolf Hakenes <hakenes@hippomi.de>.
00009  *
00010  * $Id: epg.h 2.8 2012/03/10 13:50:10 kls Exp $
00011  */
00012 
00013 #ifndef __EPG_H
00014 #define __EPG_H
00015 
00016 #include "channels.h"
00017 #include "libsi/section.h"
00018 #include "thread.h"
00019 #include "tools.h"
00020 
00021 #define MAXEPGBUGFIXLEVEL 3
00022 
00023 enum { MaxEventContents = 4 };
00024 
00025 enum eEventContentGroup {
00026   ecgMovieDrama               = 0x10,
00027   ecgNewsCurrentAffairs       = 0x20,
00028   ecgShow                     = 0x30,
00029   ecgSports                   = 0x40,
00030   ecgChildrenYouth            = 0x50,
00031   ecgMusicBalletDance         = 0x60,
00032   ecgArtsCulture              = 0x70,
00033   ecgSocialPoliticalEconomics = 0x80,
00034   ecgEducationalScience       = 0x90,
00035   ecgLeisureHobbies           = 0xA0,
00036   ecgSpecial                  = 0xB0,
00037   ecgUserDefined              = 0xF0
00038   };
00039 
00040 enum eDumpMode { dmAll, dmPresent, dmFollowing, dmAtTime };
00041 
00042 struct tComponent {
00043   uchar stream;
00044   uchar type;
00045   char language[MAXLANGCODE2];
00046   char *description;
00047   cString ToString(void);
00048   bool FromString(const char *s);
00049   };
00050 
00051 class cComponents {
00052 private:
00053   int numComponents;
00054   tComponent *components;
00055   bool Realloc(int Index);
00056 public:
00057   cComponents(void);
00058   ~cComponents(void);
00059   int NumComponents(void) const { return numComponents; }
00060   void SetComponent(int Index, const char *s);
00061   void SetComponent(int Index, uchar Stream, uchar Type, const char *Language, const char *Description);
00062   tComponent *Component(int Index) const { return (Index < numComponents) ? &components[Index] : NULL; }
00063   tComponent *GetComponent(int Index, uchar Stream, uchar Type); // Gets the Index'th component of Stream and Type, skipping other components
00064                                                                  // In case of an audio stream the 'type' check actually just distinguishes between "normal" and "Dolby Digital"
00065   };
00066 
00067 class cSchedule;
00068 
00069 typedef u_int32_t tEventID;
00070 
00071 class cEvent : public cListObject {
00072   friend class cSchedule;
00073 private:
00074   // The sequence of these parameters is optimized for minimal memory waste!
00075   cSchedule *schedule;     // The Schedule this event belongs to
00076   tEventID eventID;        // Event ID of this event
00077   uchar tableID;           // Table ID this event came from
00078   uchar version;           // Version number of section this event came from
00079   uchar runningStatus;     // 0=undefined, 1=not running, 2=starts in a few seconds, 3=pausing, 4=running
00080   uchar parentalRating;    // Parental rating of this event
00081   char *title;             // Title of this event
00082   char *shortText;         // Short description of this event (typically the episode name in case of a series)
00083   char *description;       // Description of this event
00084   cComponents *components; // The stream components of this event
00085   uchar contents[MaxEventContents]; // Contents of this event
00086   time_t startTime;        // Start time of this event
00087   int duration;            // Duration of this event in seconds
00088   time_t vps;              // Video Programming Service timestamp (VPS, aka "Programme Identification Label", PIL)
00089   time_t seen;             // When this event was last seen in the data stream
00090 public:
00091   cEvent(tEventID EventID);
00092   ~cEvent();
00093   virtual int Compare(const cListObject &ListObject) const;
00094   tChannelID ChannelID(void) const;
00095   const cSchedule *Schedule(void) const { return schedule; }
00096   tEventID EventID(void) const { return eventID; }
00097   uchar TableID(void) const { return tableID; }
00098   uchar Version(void) const { return version; }
00099   int RunningStatus(void) const { return runningStatus; }
00100   const char *Title(void) const { return title; }
00101   const char *ShortText(void) const { return shortText; }
00102   const char *Description(void) const { return description; }
00103   const cComponents *Components(void) const { return components; }
00104   uchar Contents(int i = 0) const { return (0 <= i && i < MaxEventContents) ? contents[i] : uchar(0); }
00105   int ParentalRating(void) const { return parentalRating; }
00106   time_t StartTime(void) const { return startTime; }
00107   time_t EndTime(void) const { return startTime + duration; }
00108   int Duration(void) const { return duration; }
00109   time_t Vps(void) const { return vps; }
00110   time_t Seen(void) const { return seen; }
00111   bool SeenWithin(int Seconds) const { return time(NULL) - seen < Seconds; }
00112   bool HasTimer(void) const;
00113   bool IsRunning(bool OrAboutToStart = false) const;
00114   static const char *ContentToString(uchar Content);
00115   cString GetParentalRatingString(void) const;
00116   cString GetDateString(void) const;
00117   cString GetTimeString(void) const;
00118   cString GetEndTimeString(void) const;
00119   cString GetVpsString(void) const;
00120   void SetEventID(tEventID EventID);
00121   void SetTableID(uchar TableID);
00122   void SetVersion(uchar Version);
00123   void SetRunningStatus(int RunningStatus, cChannel *Channel = NULL);
00124   void SetTitle(const char *Title);
00125   void SetShortText(const char *ShortText);
00126   void SetDescription(const char *Description);
00127   void SetComponents(cComponents *Components); // Will take ownership of Components!
00128   void SetContents(uchar *Contents);
00129   void SetParentalRating(int ParentalRating);
00130   void SetStartTime(time_t StartTime);
00131   void SetDuration(int Duration);
00132   void SetVps(time_t Vps);
00133   void SetSeen(void);
00134   cString ToDescr(void) const;
00135   void Dump(FILE *f, const char *Prefix = "", bool InfoOnly = false) const;
00136   bool Parse(char *s);
00137   static bool Read(FILE *f, cSchedule *Schedule);
00138   void FixEpgBugs(void);
00139   };
00140 
00141 class cSchedules;
00142 
00143 class cSchedule : public cListObject  {
00144 private:
00145   tChannelID channelID;
00146   cList<cEvent> events;
00147   cHash<cEvent> eventsHashID;
00148   cHash<cEvent> eventsHashStartTime;
00149   bool hasRunning;
00150   time_t modified;
00151   time_t presentSeen;
00152 public:
00153   cSchedule(tChannelID ChannelID);
00154   tChannelID ChannelID(void) const { return channelID; }
00155   time_t Modified(void) const { return modified; }
00156   time_t PresentSeen(void) const { return presentSeen; }
00157   bool PresentSeenWithin(int Seconds) const { return time(NULL) - presentSeen < Seconds; }
00158   void SetModified(void) { modified = time(NULL); }
00159   void SetPresentSeen(void) { presentSeen = time(NULL); }
00160   void SetRunningStatus(cEvent *Event, int RunningStatus, cChannel *Channel = NULL);
00161   void ClrRunningStatus(cChannel *Channel = NULL);
00162   void ResetVersions(void);
00163   void Sort(void);
00164   void DropOutdated(time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version);
00165   void Cleanup(time_t Time);
00166   void Cleanup(void);
00167   cEvent *AddEvent(cEvent *Event);
00168   void DelEvent(cEvent *Event);
00169   void HashEvent(cEvent *Event);
00170   void UnhashEvent(cEvent *Event);
00171   const cList<cEvent> *Events(void) const { return &events; }
00172   const cEvent *GetPresentEvent(void) const;
00173   const cEvent *GetFollowingEvent(void) const;
00174   const cEvent *GetEvent(tEventID EventID, time_t StartTime = 0) const;
00175   const cEvent *GetEventAround(time_t Time) const;
00176   void Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0) const;
00177   static bool Read(FILE *f, cSchedules *Schedules);
00178   };
00179 
00180 class cSchedulesLock {
00181 private:
00182   bool locked;
00183 public:
00184   cSchedulesLock(bool WriteLock = false, int TimeoutMs = 0);
00185   ~cSchedulesLock();
00186   bool Locked(void) { return locked; }
00187   };
00188 
00189 class cSchedules : public cList<cSchedule> {
00190   friend class cSchedule;
00191   friend class cSchedulesLock;
00192 private:
00193   cRwLock rwlock;
00194   static cSchedules schedules;
00195   static const char *epgDataFileName;
00196   static time_t lastCleanup;
00197   static time_t lastDump;
00198   static time_t modified;
00199 public:
00200   static void SetEpgDataFileName(const char *FileName);
00201   static const cSchedules *Schedules(cSchedulesLock &SchedulesLock);
00205   static time_t Modified(void) { return modified; }
00206   static void SetModified(cSchedule *Schedule);
00207   static void Cleanup(bool Force = false);
00208   static void ResetVersions(void);
00209   static bool ClearAll(void);
00210   static bool Dump(FILE *f, const char *Prefix = "", eDumpMode DumpMode = dmAll, time_t AtTime = 0);
00211   static bool Read(FILE *f = NULL);
00212   cSchedule *AddSchedule(tChannelID ChannelID);
00213   const cSchedule *GetSchedule(tChannelID ChannelID) const;
00214   const cSchedule *GetSchedule(const cChannel *Channel, bool AddIfMissing = false) const;
00215   };
00216 
00217 class cEpgDataReader : public cThread {
00218 public:
00219   cEpgDataReader(void);
00220   virtual void Action(void);
00221   };
00222 
00223 void ReportEpgBugFixStats(bool Reset = false);
00224 
00225 class cEpgHandler : public cListObject {
00226 public:
00227   cEpgHandler(void);
00236   virtual ~cEpgHandler();
00237   virtual bool IgnoreChannel(const cChannel *Channel) { return false; }
00242   virtual bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version) { return false; }
00247   virtual bool SetEventID(cEvent *Event, tEventID EventID) { return false; }
00248   virtual bool SetTitle(cEvent *Event, const char *Title) { return false; }
00249   virtual bool SetShortText(cEvent *Event, const char *ShortText) { return false; }
00250   virtual bool SetDescription(cEvent *Event, const char *Description) { return false; }
00251   virtual bool SetContents(cEvent *Event, uchar *Contents) { return false; }
00252   virtual bool SetParentalRating(cEvent *Event, int ParentalRating) { return false; }
00253   virtual bool SetStartTime(cEvent *Event, time_t StartTime) { return false; }
00254   virtual bool SetDuration(cEvent *Event, int Duration) { return false; }
00255   virtual bool SetVps(cEvent *Event, time_t Vps) { return false; }
00256   virtual bool FixEpgBugs(cEvent *Event) { return false; }
00258   virtual bool HandleEvent(cEvent *Event) { return false; }
00261   virtual bool SortSchedule(cSchedule *Schedule) { return false; }
00263   virtual bool DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version) { return false; }
00266   };
00267 
00268 class cEpgHandlers : public cList<cEpgHandler> {
00269 public:
00270   bool IgnoreChannel(const cChannel *Channel);
00271   bool HandleEitEvent(cSchedule *Schedule, const SI::EIT::Event *EitEvent, uchar TableID, uchar Version);
00272   void SetEventID(cEvent *Event, tEventID EventID);
00273   void SetTitle(cEvent *Event, const char *Title);
00274   void SetShortText(cEvent *Event, const char *ShortText);
00275   void SetDescription(cEvent *Event, const char *Description);
00276   void SetContents(cEvent *Event, uchar *Contents);
00277   void SetParentalRating(cEvent *Event, int ParentalRating);
00278   void SetStartTime(cEvent *Event, time_t StartTime);
00279   void SetDuration(cEvent *Event, int Duration);
00280   void SetVps(cEvent *Event, time_t Vps);
00281   void FixEpgBugs(cEvent *Event);
00282   void HandleEvent(cEvent *Event);
00283   void SortSchedule(cSchedule *Schedule);
00284   void DropOutdated(cSchedule *Schedule, time_t SegmentStart, time_t SegmentEnd, uchar TableID, uchar Version);
00285   };
00286 
00287 extern cEpgHandlers EpgHandlers;
00288 
00289 #endif //__EPG_H