vdr
1.7.27
|
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