4 #define ENABLE_PRIVATE_EPG 1
5 #define ENABLE_MHW_EPG 1
6 #define ENABLE_FREESAT 1
7 #define ENABLE_NETMED 1
8 #define ENABLE_VIRGIN 1
14 #include <tr1/unordered_map>
18 #include <lib/dvb/eit.h>
20 #include <lib/dvb/lowlevel/mhw.h>
22 #include <lib/dvb/idvb.h>
23 #include <lib/dvb/demux.h>
24 #include <lib/dvb/dvbtime.h>
25 #include <lib/base/ebase.h>
26 #include <lib/base/thread.h>
27 #include <lib/base/message.h>
28 #include <lib/service/event.h>
29 #include <lib/python/python.h>
32 class eServiceReferenceDVB;
33 class eDVBServicePMTHandler;
38 uniqueEPGKey( const eServiceReference &ref )
39 :sid( ref.type != eServiceReference::idInvalid ? ((eServiceReferenceDVB&)ref).getServiceID().get() : -1 )
40 ,onid( ref.type != eServiceReference::idInvalid ? ((eServiceReferenceDVB&)ref).getOriginalNetworkID().get() : -1 )
41 ,tsid( ref.type != eServiceReference::idInvalid ? ((eServiceReferenceDVB&)ref).getTransportStreamID().get() : -1 )
45 :sid(-1), onid(-1), tsid(-1)
48 uniqueEPGKey( int sid, int onid, int tsid )
49 :sid(sid), onid(onid), tsid(tsid)
52 bool operator <(const uniqueEPGKey &a) const
62 return (tsid < a.tsid);
66 return !(sid == -1 && onid == -1 && tsid == -1);
68 bool operator==(const uniqueEPGKey &a) const
70 return (tsid == a.tsid) && (onid == a.onid) && (sid == a.sid);
74 bool operator()(const uniqueEPGKey &a, const uniqueEPGKey &b) const
76 return (a.tsid == b.tsid) && (a.onid == b.onid) && (a.sid == b.sid);
81 //eventMap is sorted by event_id
82 typedef std::map<uint16_t, eventData*> eventMap;
83 //timeMap is sorted by beginTime
84 typedef std::map<time_t, eventData*> timeMap;
86 typedef std::map<eDVBChannelID, time_t> updateMap;
88 struct hash_uniqueEPGKey
90 inline size_t operator()( const uniqueEPGKey &x) const
92 return (x.onid << 16) | x.tsid;
96 struct EventCacheItem {
101 typedef std::set<uint32_t> tidMap;
103 typedef std::tr1::unordered_map<uniqueEPGKey, EventCacheItem, hash_uniqueEPGKey, uniqueEPGKey::equal> eventCache;
104 #ifdef ENABLE_PRIVATE_EPG
105 typedef std::tr1::unordered_map<time_t, std::pair<time_t, uint16_t> > contentTimeMap;
106 typedef std::tr1::unordered_map<int, contentTimeMap > contentMap;
107 typedef std::tr1::unordered_map<uniqueEPGKey, contentMap, hash_uniqueEPGKey, uniqueEPGKey::equal > contentMaps;
112 #ifdef ENABLE_FREESAT
114 class freesatEITSubtableStatus
118 uint16_t sectionMap[32];
119 void initMap(uint8_t maxSection);
122 freesatEITSubtableStatus(u_char version, uint8_t maxSection);
123 bool isSectionPresent(uint8_t sectionNo);
124 void seen(uint8_t sectionNo, uint8_t maxSegmentSection);
125 bool isVersionChanged(u_char testVersion);
126 void updateVersion(u_char newVersion, uint8_t maxSection);
131 class eEPGCache: public eMainloop, private eThread, public Object
134 DECLARE_REF(eEPGCache)
135 struct channel_data: public Object
137 pthread_mutex_t channel_active;
138 channel_data(eEPGCache*);
140 ePtr<eTimer> abortTimer, zapTimer;
141 int prevChannelState;
143 unsigned int isRunning, haveData;
144 ePtr<eDVBChannel> channel;
145 ePtr<eConnection> m_stateChangedConn, m_NowNextConn, m_ScheduleConn, m_ScheduleOtherConn, m_ViasatConn;
146 ePtr<iDVBSectionReader> m_NowNextReader, m_ScheduleReader, m_ScheduleOtherReader, m_ViasatReader;
147 tidMap seenSections[4], calcedSections[4];
149 ePtr<eConnection> m_VirginNowNextConn, m_VirginScheduleConn;
150 ePtr<iDVBSectionReader> m_VirginNowNextReader, m_VirginScheduleReader;
153 ePtr<eConnection> m_NetmedScheduleConn, m_NetmedScheduleOtherConn;
154 ePtr<iDVBSectionReader> m_NetmedScheduleReader, m_NetmedScheduleOtherReader;
156 #ifdef ENABLE_FREESAT
157 ePtr<eConnection> m_FreeSatScheduleOtherConn, m_FreeSatScheduleOtherConn2;
158 ePtr<iDVBSectionReader> m_FreeSatScheduleOtherReader, m_FreeSatScheduleOtherReader2;
159 std::map<uint32_t, freesatEITSubtableStatus> m_FreeSatSubTableStatus;
160 uint32_t m_FreesatTablesToComplete;
161 void readFreeSatScheduleOtherData(const uint8_t *data);
162 void cleanupFreeSat();
164 #ifdef ENABLE_PRIVATE_EPG
165 ePtr<eTimer> startPrivateTimer;
168 uniqueEPGKey m_PrivateService;
169 ePtr<eConnection> m_PrivateConn;
170 ePtr<iDVBSectionReader> m_PrivateReader;
171 std::set<uint8_t> seenPrivateSections;
172 void readPrivateData(const uint8_t *data);
173 void startPrivateReader();
175 #ifdef ENABLE_MHW_EPG
176 std::vector<mhw_channel_name_t> m_channels;
177 std::map<uint8_t, mhw_theme_name_t> m_themes;
178 std::map<uint32_t, mhw_title_t> m_titles;
179 std::multimap<uint32_t, uint32_t> m_program_ids;
180 ePtr<eConnection> m_MHWConn, m_MHWConn2;
181 ePtr<iDVBSectionReader> m_MHWReader, m_MHWReader2;
182 eDVBSectionFilterMask m_MHWFilterMask, m_MHWFilterMask2;
183 ePtr<eTimer> m_MHWTimeoutTimer;
184 uint16_t m_mhw2_channel_pid, m_mhw2_title_pid, m_mhw2_summary_pid;
186 void MHWTimeout() { m_MHWTimeoutet=true; }
187 void readMHWData(const uint8_t *data);
188 void readMHWData2(const uint8_t *data);
189 void startMHWReader(uint16_t pid, uint8_t tid);
190 void startMHWReader2(uint16_t pid, uint8_t tid, int ext=-1);
191 void startMHWTimeout(int msek);
192 bool checkMHWTimeout() { return m_MHWTimeoutet; }
194 uint8_t *delimitName( uint8_t *in, uint8_t *out, int len_in );
195 void timeMHW2DVB( u_char hours, u_char minutes, u_char *return_time);
196 void timeMHW2DVB( int minutes, u_char *return_time);
197 void timeMHW2DVB( u_char day, u_char hours, u_char minutes, u_char *return_time);
198 void storeMHWTitle(std::map<uint32_t, mhw_title_t>::iterator itTitle, std::string sumText, const uint8_t *data);
200 void readData(const uint8_t *data, int source);
205 void abortNonAvail();
207 bool FixOverlapping(EventCacheItem &servicemap, time_t TM, int duration, const timeMap::iterator &tm_it, const uniqueEPGKey &service);
218 got_mhw2_channel_pid,
220 got_mhw2_summary_pid,
224 iDVBChannel *channel;
225 uniqueEPGKey service;
236 Message(int type, bool b)
237 :type(type), avail(b) {}
238 Message(int type, iDVBChannel *channel, int err=0)
239 :type(type), channel(channel), err(err) {}
240 Message(int type, const eServiceReference& service, int err=0)
241 :type(type), service(service), err(err) {}
242 Message(int type, time_t time)
243 :type(type), time(time) {}
245 eFixedMessagePump<Message> messages;
247 friend class channel_data;
248 friend class eventData;
249 static eEPGCache *instance;
251 typedef std::map<iDVBChannel*, channel_data*> ChannelMap;
253 ePtr<eTimer> cleanTimer;
254 ChannelMap m_knownChannels;
255 ePtr<eConnection> m_chanAddedConn;
257 unsigned int enabledSources;
258 unsigned int historySeconds;
261 updateMap channelLastUpdated;
262 std::string m_filename;
265 #ifdef ENABLE_PRIVATE_EPG
266 contentMaps content_time_tables;
269 void thread(); // thread function
271 #ifdef ENABLE_PRIVATE_EPG
272 void privateSectionRead(const uniqueEPGKey &, const uint8_t *);
274 void sectionRead(const uint8_t *data, int source, channel_data *channel);
275 void gotMessage(const Message &message);
277 void submitEventData(const std::vector<int>& sids, const std::vector<eDVBChannelID>& chids, long start, long duration, const char* title, const char* short_summary, const char* long_description, char event_type, int source);
279 // called from main thread
280 void DVBChannelAdded(eDVBChannel*);
281 void DVBChannelStateChanged(iDVBChannel*);
282 void DVBChannelRunning(iDVBChannel *);
284 timeMap::iterator m_timemap_cursor, m_timemap_end;
285 int currentQueryTsidOnid; // needed for getNextTimeEntry.. only valid until next startTimeQuery call
291 static eEPGCache *getInstance() { return instance; }
296 void flushEPG(const uniqueEPGKey & s=uniqueEPGKey());
301 #ifdef ENABLE_PRIVATE_EPG
302 void PMTready(eDVBServicePMTHandler *pmthandler);
304 void PMTready(eDVBServicePMTHandler *pmthandler) {}
308 // must be called once!
309 void setCacheFile(const char *filename);
311 // at moment just for one service..
312 RESULT startTimeQuery(const eServiceReference &service, time_t begin=-1, int minutes=-1);
316 // For internal use only. Acquire the cache lock before calling.
317 RESULT lookupEventId(const eServiceReference &service, int event_id, const eventData *&);
318 RESULT lookupEventTime(const eServiceReference &service, time_t, const eventData *&, int direction=0);
321 /* Only used by servicedvbrecord.cpp to write the EIT file */
322 RESULT saveEventToFile(const char* filename, const eServiceReference &service, int eit_event_id, time_t begTime, time_t endTime);
324 // Events are parsed epg events.. it's safe to use them after cache unlock
325 // after use the Event pointer must be released using "delete".
326 RESULT lookupEventId(const eServiceReference &service, int event_id, Event* &);
327 RESULT lookupEventTime(const eServiceReference &service, time_t, Event* &, int direction=0);
328 RESULT getNextTimeEntry(Event *&);
331 SIMILAR_BROADCASTINGS_SEARCH,
333 PARTIAL_TITLE_SEARCH,
340 PyObject *lookupEvent(SWIG_PYOBJECT(ePyObject) list, SWIG_PYOBJECT(ePyObject) convertFunc=(PyObject*)0);
341 PyObject *search(SWIG_PYOBJECT(ePyObject));
343 // eServiceEvent are parsed epg events.. it's safe to use them after cache unlock
344 // for use from python ( members: m_start_time, m_duration, m_short_description, m_extended_description )
345 SWIG_VOID(RESULT) lookupEventId(const eServiceReference &service, int event_id, ePtr<eServiceEvent> &SWIG_OUTPUT);
346 SWIG_VOID(RESULT) lookupEventTime(const eServiceReference &service, time_t, ePtr<eServiceEvent> &SWIG_OUTPUT, int direction=0);
347 SWIG_VOID(RESULT) getNextTimeEntry(ePtr<eServiceEvent> &SWIG_OUTPUT);
349 enum {PRIVATE=0, NOWNEXT=1, SCHEDULE=2, SCHEDULE_OTHER=4
350 #ifdef ENABLE_MHW_EPG
353 #ifdef ENABLE_FREESAT
356 ,FREESAT_SCHEDULE_OTHER=64
361 ,NETMED_SCHEDULE_OTHER=1024
365 ,VIRGIN_SCHEDULE=4096
367 ,EPG_IMPORT=0x80000000
369 void setEpgHistorySeconds(time_t seconds);
370 void setEpgSources(unsigned int mask);
371 unsigned int getEpgSources();
373 void submitEventData(const std::vector<eServiceReferenceDVB>& serviceRefs, long start, long duration, const char* title, const char* short_summary, const char* long_description, char event_type);
374 void importEvents(SWIG_PYOBJECT(ePyObject) serviceReferences, SWIG_PYOBJECT(ePyObject) list);
375 void importEvent(SWIG_PYOBJECT(ePyObject) serviceReference, SWIG_PYOBJECT(ePyObject) list);