955688b95e679a306dea07336624023262c2561d
[enigma2.git] / lib / dvb / idvb.h
1 #ifndef __dvb_idvb_h
2 #define __dvb_idvb_h
3
4 #if HAVE_DVB_API_VERSION < 3
5 #include <ost/frontend.h>
6 #define FRONTENDPARAMETERS FrontendParameters
7 #else
8 #include <linux/dvb/frontend.h>
9 #define FRONTENDPARAMETERS struct dvb_frontend_parameters
10 #endif
11 #include <lib/dvb/frontendparms.h>
12 #include <lib/base/object.h>
13 #include <lib/base/ebase.h>
14 #include <lib/base/elock.h>
15 #include <lib/service/service.h>
16 #include <libsig_comp.h>
17 #include <connection.h>
18
19 struct eBouquet
20 {
21         std::string m_bouquet_name;
22         std::string m_filename;  // without path.. just name
23         typedef std::list<eServiceReference> list;
24         list m_services;
25 // the following five methods are implemented in db.cpp
26         RESULT flushChanges();
27         RESULT addService(const eServiceReference &);
28         RESULT removeService(const eServiceReference &);
29         RESULT moveService(const eServiceReference &, unsigned int);
30         RESULT setListName(const std::string &name);
31 };
32
33                 /* these structures have by intention no operator int() defined.
34                    the reason of these structures is to avoid mixing for example
35                    a onid and a tsid (as there's no general order for them).
36                    
37                    defining an operator int() would implicitely convert values
38                    between them over the constructor with the int argument.
39                    
40                    'explicit' doesn't here - eTransportStreamID(eOriginalNetworkID(n)) 
41                    would still work. */
42
43 struct eTransportStreamID
44 {
45 private:
46         int v;
47 public:
48         int get() const { return v; }
49         eTransportStreamID(int i): v(i) { }
50         eTransportStreamID(): v(-1) { }
51         bool operator == (const eTransportStreamID &c) const { return v == c.v; }
52         bool operator != (const eTransportStreamID &c) const { return v != c.v; }
53         bool operator < (const eTransportStreamID &c) const { return v < c.v; }
54         bool operator > (const eTransportStreamID &c) const { return v > c.v; }
55 };
56
57 struct eServiceID
58 {
59 private:
60         int v;
61 public:
62         int get() const { return v; }
63         eServiceID(int i): v(i) { }
64         eServiceID(): v(-1) { }
65         bool operator == (const eServiceID &c) const { return v == c.v; }
66         bool operator != (const eServiceID &c) const { return v != c.v; }
67         bool operator < (const eServiceID &c) const { return v < c.v; }
68         bool operator > (const eServiceID &c) const { return v > c.v; }
69 };
70
71 struct eOriginalNetworkID
72 {
73 private:
74         int v;
75 public:
76         int get() const { return v; }
77         eOriginalNetworkID(int i): v(i) { }
78         eOriginalNetworkID(): v(-1) { }
79         bool operator == (const eOriginalNetworkID &c) const { return v == c.v; }
80         bool operator != (const eOriginalNetworkID &c) const { return v != c.v; }
81         bool operator < (const eOriginalNetworkID &c) const { return v < c.v; }
82         bool operator > (const eOriginalNetworkID &c) const { return v > c.v; }
83 };
84
85 struct eDVBNamespace
86 {
87 private:
88         int v;
89 public:
90         int get() const { return v; }
91         eDVBNamespace(int i): v(i) { }
92         eDVBNamespace(): v(-1) { }
93         bool operator == (const eDVBNamespace &c) const { return v == c.v; }
94         bool operator != (const eDVBNamespace &c) const { return v != c.v; }
95         bool operator < (const eDVBNamespace &c) const { return v < c.v; }
96         bool operator > (const eDVBNamespace &c) const { return v > c.v; }
97 };
98
99 struct eDVBChannelID
100 {
101         eDVBNamespace dvbnamespace;
102         eTransportStreamID transport_stream_id;
103         eOriginalNetworkID original_network_id;
104         
105         bool operator==(const eDVBChannelID &c) const
106         {
107                 return dvbnamespace == c.dvbnamespace &&
108                         transport_stream_id == c.transport_stream_id &&
109                         original_network_id == c.original_network_id;
110         }
111         
112         bool operator<(const eDVBChannelID &c) const
113         {
114                 if (dvbnamespace < c.dvbnamespace)
115                         return 1;
116                 else if (dvbnamespace == c.dvbnamespace)
117                 {
118                         if (original_network_id < c.original_network_id)
119                                 return 1;
120                         else if (original_network_id == c.original_network_id)
121                                 if (transport_stream_id < c.transport_stream_id)
122                                         return 1;
123                 }
124                 return 0;
125         }
126         eDVBChannelID(eDVBNamespace dvbnamespace, eTransportStreamID tsid, eOriginalNetworkID onid): 
127                         dvbnamespace(dvbnamespace), transport_stream_id(tsid), original_network_id(onid)
128         {
129         }
130         eDVBChannelID():
131                         dvbnamespace(-1), transport_stream_id(-1), original_network_id(-1)
132         {
133         }
134         operator bool() const
135         {
136                 return (dvbnamespace != -1) && (transport_stream_id != -1) && (original_network_id != -1);
137         }
138 };
139
140 struct eServiceReferenceDVB: public eServiceReference
141 {
142         int getServiceType() const { return data[0]; }
143         void setServiceType(int service_type) { data[0]=service_type; }
144
145         eServiceID getServiceID() const { return eServiceID(data[1]); }
146         void setServiceID(eServiceID service_id) { data[1]=service_id.get(); }
147
148         eTransportStreamID getTransportStreamID() const { return eTransportStreamID(data[2]); }
149         void setTransportStreamID(eTransportStreamID transport_stream_id) { data[2]=transport_stream_id.get(); }
150
151         eOriginalNetworkID getOriginalNetworkID() const { return eOriginalNetworkID(data[3]); }
152         void setOriginalNetworkID(eOriginalNetworkID original_network_id) { data[3]=original_network_id.get(); }
153
154         eDVBNamespace getDVBNamespace() const { return eDVBNamespace(data[4]); }
155         void setDVBNamespace(eDVBNamespace dvbnamespace) { data[4]=dvbnamespace.get(); }
156
157         eServiceID getParentServiceID() const { return eServiceID(data[5]); }
158         void setParentServiceID( eServiceID sid ) { data[5]=sid.get(); }
159
160         eTransportStreamID getParentTransportStreamID() const { return eTransportStreamID(data[6]); }
161         void setParentTransportStreamID( eTransportStreamID tsid ) { data[6]=tsid.get(); }
162
163         eServiceReferenceDVB(eDVBNamespace dvbnamespace, eTransportStreamID transport_stream_id, eOriginalNetworkID original_network_id, eServiceID service_id, int service_type)
164                 :eServiceReference(eServiceReference::idDVB, 0)
165         {
166                 setTransportStreamID(transport_stream_id);
167                 setOriginalNetworkID(original_network_id);
168                 setDVBNamespace(dvbnamespace);
169                 setServiceID(service_id);
170                 setServiceType(service_type);
171         }
172         
173         void set(const eDVBChannelID &chid)
174         {
175                 setDVBNamespace(chid.dvbnamespace);
176                 setOriginalNetworkID(chid.original_network_id);
177                 setTransportStreamID(chid.transport_stream_id);
178         }
179         
180         void getChannelID(eDVBChannelID &chid) const
181         {
182                 chid = eDVBChannelID(getDVBNamespace(), getTransportStreamID(), getOriginalNetworkID());
183         }
184
185         eServiceReferenceDVB()
186                 :eServiceReference(eServiceReference::idDVB, 0)
187         {
188         }
189
190         eServiceReferenceDVB(const std::string &string)
191                 :eServiceReference(string)
192         {
193         }
194 };
195
196
197 ////////////////// TODO: we need an interface here, but what exactly?
198
199 #include <set>
200 // btw, still implemented in db.cpp. FIX THIS, TOO.
201
202 class eDVBChannelQuery;
203
204 class eDVBService: public iStaticServiceInformation
205 {
206         DECLARE_REF(eDVBService);
207 public:
208         enum cacheID
209         {
210                 cVPID, cAPID, cTPID, cPCRPID, cAC3PID, cacheMax
211         };
212
213         int getCachePID(cacheID);
214         void setCachePID(cacheID, int);
215         bool cacheEmpty() { return m_cache.empty(); }
216
217         eDVBService();
218                 /* m_service_name_sort is uppercase, with special chars removed, to increase sort performance. */
219         std::string m_service_name, m_service_name_sort;
220         std::string m_provider_name;
221         
222         void genSortName();
223         
224         int m_flags;
225         std::set<int> m_ca;
226         std::map<int,int> m_cache;
227         virtual ~eDVBService();
228         
229         eDVBService &operator=(const eDVBService &);
230         
231         // iStaticServiceInformation
232         RESULT getName(const eServiceReference &ref, std::string &name);
233         RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time);
234         bool isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
235
236                 /* for filtering: */
237         int checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query);
238 };
239
240 //////////////////
241
242 class iDVBChannel;
243 class iDVBDemux;
244 class iDVBFrontendParameters;
245
246 class iDVBChannelListQuery: public iObject
247 {
248 public:
249         virtual RESULT getNextResult(eServiceReferenceDVB &ref)=0;
250         virtual int compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b)=0;
251 };
252
253 class eDVBChannelQuery: public iObject
254 {
255         DECLARE_REF(eDVBChannelQuery);
256 public:
257         enum
258         {
259                 tName,
260                 tProvider,
261                 tType,
262                 tBouquet,
263                 tSatellitePosition,
264                 tChannelID,
265                 tAND,
266                 tOR
267         };
268         
269         int m_type;
270         int m_inverse;
271         
272         std::string m_string;
273         int m_int;
274         eDVBChannelID m_channelid;
275         
276                 /* sort is only valid in root, and must be from the enum above. */
277         int m_sort;
278         std::string m_bouquet_name;
279         
280         static RESULT compile(ePtr<eDVBChannelQuery> &res, std::string query);
281         
282         ePtr<eDVBChannelQuery> m_p1, m_p2;
283 };
284
285 class iDVBChannelList: public iObject
286 {
287 public:
288         virtual RESULT addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)=0;
289         virtual RESULT removeChannel(const eDVBChannelID &id)=0;
290         
291         virtual RESULT getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)=0;
292         
293         virtual RESULT addService(const eServiceReferenceDVB &service, eDVBService *service)=0;
294         virtual RESULT getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)=0;
295         virtual RESULT flush()=0;
296
297         virtual RESULT getBouquet(const eServiceReference &ref,  eBouquet* &bouquet)=0;
298
299         virtual RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *query, const eServiceReference &source)=0;
300 };
301
302 class iDVBFrontendParameters: public iObject
303 {
304 public:
305         virtual RESULT getSystem(int &type) const = 0;
306         virtual RESULT getDVBS(eDVBFrontendParametersSatellite &p) const = 0;
307         virtual RESULT getDVBC(eDVBFrontendParametersCable &p) const = 0;
308         virtual RESULT getDVBT(eDVBFrontendParametersTerrestrial &p) const = 0;
309         
310         virtual RESULT calculateDifference(const iDVBFrontendParameters *parm, int &diff) const = 0;
311         virtual RESULT getHash(unsigned long &hash) const = 0;
312 };
313
314 #define MAX_DISEQC_LENGTH  16
315
316 class eDVBDiseqcCommand
317 {
318 public:
319         int len;
320         __u8 data[MAX_DISEQC_LENGTH];
321 #if HAVE_DVB_API_VERSION < 3
322         int tone;
323         int voltage;
324 #endif
325 };
326
327 class iDVBSatelliteEquipmentControl;
328 class eSecCommandList;
329
330 class iDVBFrontend: public iObject
331 {
332 public:
333         enum {
334                 feSatellite, feCable, feTerrestrial
335         };
336         virtual RESULT getFrontendType(int &type)=0;
337         virtual RESULT tune(const iDVBFrontendParameters &where)=0;
338         virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
339         enum {
340                 stateIdle = 0,
341                 stateTuning = 1,
342                 stateFailed = 2,
343                 stateLock = 3,
344                 stateLostLock = 4,
345         };
346         virtual RESULT getState(int &state)=0;
347         enum {
348                 toneOff, toneOn
349         };
350         virtual RESULT setTone(int tone)=0;
351         enum {
352                 voltageOff, voltage13, voltage18, voltage13_5, voltage18_5
353         };
354         virtual RESULT setVoltage(int voltage)=0;
355         virtual RESULT sendDiseqc(const eDVBDiseqcCommand &diseqc)=0;
356         virtual RESULT sendToneburst(int burst)=0;
357         virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0;
358         virtual RESULT setSecSequence(const eSecCommandList &list)=0;
359
360         enum {
361                 bitErrorRate, signalPower, signalQuality, Locked, Synced
362         };
363         virtual int readFrontendData(int type)=0;
364         virtual PyObject *readTransponderData(bool original)=0;
365
366         virtual RESULT getData(int num, int &data)=0;
367         virtual RESULT setData(int num, int val)=0;
368         
369                 /* 0 means: not compatible. other values are a priority. */
370         virtual int isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)=0;
371 };
372
373 class iDVBSatelliteEquipmentControl: public iObject
374 {
375 public:
376         virtual RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int frontend_id)=0;
377         virtual int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *fe, int frontend_id)=0;
378         virtual void setRotorMoving(bool)=0;
379 };
380
381 struct eDVBCIRouting
382 {
383         int enabled;
384 };
385
386 class iDVBChannel: public iObject
387 {
388 public:
389         enum
390         {
391                 state_idle,        /* not yet tuned */
392                 state_tuning,      /* currently tuning (first time) */
393                 state_failed,      /* tuning failed. */
394                 state_unavailable, /* currently unavailable, will be back without further interaction */
395                 state_ok,          /* ok */
396                 state_last_instance, /* just one reference to this channel is left */
397                 state_release      /* channel is being shut down. */
398         };
399         
400         enum 
401         {
402                 evtEOF, evtSOF, evtFailed
403         };
404         virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
405         virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
406         virtual RESULT getState(int &state)=0;
407         
408                 /* demux capabilities */
409         enum
410         {
411                 capDecode = 1,
412                 /* capCI = 2 */
413         };
414         virtual RESULT setCIRouting(const eDVBCIRouting &routing)=0;
415         virtual RESULT getDemux(ePtr<iDVBDemux> &demux, int cap=0)=0;
416         
417                 /* direct frontend access for raw channels and/or status inquiries. */
418         virtual RESULT getFrontend(ePtr<iDVBFrontend> &frontend)=0;
419         virtual RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &)=0;
420         
421                 /* use count handling */
422         virtual void AddUse() = 0;
423         virtual void ReleaseUse() = 0;
424 };
425
426         /* signed, so we can express deltas. */
427         
428 typedef long long pts_t;
429
430 class iFilePushScatterGather;
431 class iTSMPEGDecoder;
432
433         /* note that a cue sheet describes the logical positions. thus 
434            everything is specified in pts and not file positions */
435
436         /* implemented in dvb.cpp */
437 class eCueSheet: public iObject, public Object
438 {
439         DECLARE_REF(eCueSheet);
440 public:
441         eCueSheet();
442         
443                         /* frontend */
444         void seekTo(int relative, const pts_t &pts);
445         
446         void clear();
447         void addSourceSpan(const pts_t &begin, const pts_t &end);
448         void commitSpans();
449         
450         void setSkipmode(const pts_t &ratio); /* 90000 is 1:1 */
451         void setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder);
452         
453                         /* frontend and backend */
454         eSingleLock m_lock;
455         
456                         /* backend */
457         enum { evtSeek, evtSkipmode, evtSpanChanged };
458         RESULT connectEvent(const Slot1<void, int> &event, ePtr<eConnection> &connection);
459
460         std::list<std::pair<pts_t,pts_t> > m_spans;     /* begin, end */
461         std::list<std::pair<int, pts_t> > m_seek_requests; /* relative, delta */
462         pts_t m_skipmode_ratio;
463         Signal1<void,int> m_event;
464         ePtr<iDVBDemux> m_decoding_demux;
465         ePtr<iTSMPEGDecoder> m_decoder;
466 };
467
468 class iDVBPVRChannel: public iDVBChannel
469 {
470 public:
471         enum
472         {
473                 state_eof = state_release + 1  /* end-of-file reached. */
474         };
475         
476                 /* FIXME: there are some very ugly buffer-end and ... related problems */
477                 /* so this is VERY UGLY. 
478                 
479                    ok, it's going to get better. but still...*/
480         virtual RESULT playFile(const char *file) = 0;
481         virtual void stopFile() = 0;
482         
483         virtual void setCueSheet(eCueSheet *cuesheet) = 0;
484         
485         virtual RESULT getLength(pts_t &pts) = 0;
486         
487                 /* we explicitely ask for the decoding demux here because a channel
488                    can be shared between multiple decoders.
489                 */
490         virtual RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode) = 0;
491                 /* skipping must be done with a cue sheet */
492 };
493
494 class iDVBSectionReader;
495 class iDVBTSRecorder;
496 class iTSMPEGDecoder;
497
498 class iDVBDemux: public iObject
499 {
500 public:
501         virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
502         virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
503         virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader)=0;
504         virtual RESULT getSTC(pts_t &pts, int num=0)=0;
505         virtual RESULT getCADemuxID(uint8_t &id)=0;
506         virtual RESULT flush()=0;
507 };
508
509 class iTSMPEGDecoder: public iObject
510 {
511 public:
512         enum { pidDisabled = -1 };
513                 /** Set Displayed Video PID */
514         virtual RESULT setVideoPID(int vpid)=0;
515
516         enum { af_MPEG, af_AC3, af_DTS };
517                 /** Set Displayed Audio PID and type */
518         virtual RESULT setAudioPID(int apid, int type)=0;
519
520                 /** Set Displayed Videotext PID */
521         virtual RESULT setTextPID(int vpid)=0;
522
523                 /** Set Sync mode to PCR */
524         virtual RESULT setSyncPCR(int pcrpid)=0;
525         enum { sm_Audio, sm_Video };
526                 /** Set Sync mode to either audio or video master */
527         virtual RESULT setSyncMaster(int who)=0;
528
529                 /** Apply settings */
530         virtual RESULT start()=0;
531         
532                 /** Freeze frame. Either continue decoding (without display) or halt. */
533         virtual RESULT freeze(int cont)=0;
534                 /** Continue after freeze. */
535         virtual RESULT unfreeze()=0;
536         
537                 /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
538         virtual RESULT setFastForward(int skip=0)=0;
539         
540                 // stop on .. Picture
541         enum { spm_I, spm_Ref, spm_Any };
542                 /** Stop on specific decoded picture. For I-Frame display. */
543         virtual RESULT setSinglePictureMode(int when)=0;
544         
545         enum { pkm_B, pkm_PB };
546                 /** Fast forward by skipping either B or P/B pictures */
547         virtual RESULT setPictureSkipMode(int what)=0;
548         
549                 /** Slow Motion by repeating pictures */
550         virtual RESULT setSlowMotion(int repeat)=0;
551         
552         enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen };
553                 /** Set Zoom. mode *must* be fitting. */
554         virtual RESULT setZoom(int what)=0;
555         
556         virtual RESULT setTrickmode(int what) = 0;
557         
558         virtual RESULT getPTS(int what, pts_t &pts) = 0;
559 };
560
561 #endif