eacc49290bf5091f1d662cd362843a74d903820f
[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
362         };
363         virtual int readFrontendData(int type)=0;
364
365         virtual RESULT getData(int num, int &data)=0;
366         virtual RESULT setData(int num, int val)=0;
367         
368                 /* 0 means: not compatible. other values are a priority. */
369         virtual int isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)=0;
370 };
371
372 class iDVBSatelliteEquipmentControl: public iObject
373 {
374 public:
375         virtual RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, eDVBFrontendParametersSatellite &sat, int frontend_id)=0;
376         virtual int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *fe, int frontend_id)=0;
377         virtual void setRotorMoving(bool)=0;
378 };
379
380 struct eDVBCIRouting
381 {
382         int enabled;
383 };
384
385 class iDVBChannel: public iObject
386 {
387 public:
388         enum
389         {
390                 state_idle,        /* not yet tuned */
391                 state_tuning,      /* currently tuning (first time) */
392                 state_failed,      /* tuning failed. */
393                 state_unavailable, /* currently unavailable, will be back without further interaction */
394                 state_ok,          /* ok */
395                 state_last_instance, /* just one reference to this channel is left */
396                 state_release      /* channel is being shut down. */
397         };
398         
399         enum 
400         {
401                 evtEOF, evtSOF, evtFailed
402         };
403         virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
404         virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
405         virtual RESULT getState(int &state)=0;
406         
407                 /* demux capabilities */
408         enum
409         {
410                 capDecode = 1,
411                 /* capCI = 2 */
412         };
413         virtual RESULT setCIRouting(const eDVBCIRouting &routing)=0;
414         virtual RESULT getDemux(ePtr<iDVBDemux> &demux, int cap=0)=0;
415         
416                 /* direct frontend access for raw channels and/or status inquiries. */
417         virtual RESULT getFrontend(ePtr<iDVBFrontend> &frontend)=0;
418         
419                 /* use count handling */
420         virtual void AddUse() = 0;
421         virtual void ReleaseUse() = 0;
422 };
423
424         /* signed, so we can express deltas. */
425         
426 typedef long long pts_t;
427
428 class iFilePushScatterGather;
429
430         /* note that a cue sheet describes the logical positions. thus 
431            everything is specified in pts and not file positions */
432
433         /* implemented in dvb.cpp */
434 class eCueSheet: public iObject, public Object
435 {
436         DECLARE_REF(eCueSheet);
437 public:
438         eCueSheet();
439         
440                         /* frontend */
441         void seekTo(int relative, const pts_t &pts);
442         
443         void clear();
444         void addSourceSpan(const pts_t &begin, const pts_t &end);
445         
446         void setSkipmode(const pts_t &ratio); /* 90000 is 1:1 */
447         void setDecodingDemux(iDVBDemux *demux);
448         
449                         /* frontend and backend */
450         eSingleLock m_lock;
451         
452                         /* backend */
453         enum { evtSeek, evtSkipmode, evtSpanChanged };
454         RESULT connectEvent(const Slot1<void, int> &event, ePtr<eConnection> &connection);
455
456         std::list<std::pair<pts_t,pts_t> > m_spans;     /* begin, end */
457         std::list<std::pair<int, pts_t> > m_seek_requests; /* relative, delta */
458         pts_t m_skipmode_ratio;
459         Signal1<void,int> m_event;
460         ePtr<iDVBDemux> m_decoding_demux;
461 };
462
463 class iDVBPVRChannel: public iDVBChannel
464 {
465 public:
466         enum
467         {
468                 state_eof = state_release + 1  /* end-of-file reached. */
469         };
470         
471                 /* FIXME: there are some very ugly buffer-end and ... related problems */
472                 /* so this is VERY UGLY. 
473                 
474                    ok, it's going to get better. but still...*/
475         virtual RESULT playFile(const char *file) = 0;
476         virtual void stopFile() = 0;
477         
478         virtual void setCueSheet(eCueSheet *cuesheet) = 0;
479         
480         virtual RESULT getLength(pts_t &pts) = 0;
481         
482                 /* we explicitely ask for the decoding demux here because a channel
483                    can be shared between multiple decoders.
484                 */
485         virtual RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode) = 0;
486                 /* skipping must be done with a cue sheet */
487 };
488
489 class iDVBSectionReader;
490 class iDVBTSRecorder;
491 class iTSMPEGDecoder;
492
493 class iDVBDemux: public iObject
494 {
495 public:
496         virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
497         virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
498         virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader)=0;
499         virtual RESULT getSTC(pts_t &pts, int num=0)=0;
500         virtual RESULT getCADemuxID(uint8_t &id)=0;
501         virtual RESULT flush()=0;
502 };
503
504 class iTSMPEGDecoder: public iObject
505 {
506 public:
507         enum { pidDisabled = -1 };
508                 /** Set Displayed Video PID */
509         virtual RESULT setVideoPID(int vpid)=0;
510
511         enum { af_MPEG, af_AC3, af_DTS };
512                 /** Set Displayed Audio PID and type */
513         virtual RESULT setAudioPID(int apid, int type)=0;
514
515                 /** Set Displayed Videotext PID */
516         virtual RESULT setTextPID(int vpid)=0;
517
518                 /** Set Sync mode to PCR */
519         virtual RESULT setSyncPCR(int pcrpid)=0;
520         enum { sm_Audio, sm_Video };
521                 /** Set Sync mode to either audio or video master */
522         virtual RESULT setSyncMaster(int who)=0;
523
524                 /** Apply settings */
525         virtual RESULT start()=0;
526         
527                 /** Freeze frame. Either continue decoding (without display) or halt. */
528         virtual RESULT freeze(int cont)=0;
529                 /** Continue after freeze. */
530         virtual RESULT unfreeze()=0;
531         
532                 /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
533         virtual RESULT setFastForward(int skip=0)=0;
534         
535                 // stop on .. Picture
536         enum { spm_I, spm_Ref, spm_Any };
537                 /** Stop on specific decoded picture. For I-Frame display. */
538         virtual RESULT setSinglePictureMode(int when)=0;
539         
540         enum { pkm_B, pkm_PB };
541                 /** Fast forward by skipping either B or P/B pictures */
542         virtual RESULT setPictureSkipMode(int what)=0;
543         
544                 /** Slow Motion by repeating pictures */
545         virtual RESULT setSlowMotion(int repeat)=0;
546         
547         enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen };
548                 /** Set Zoom. mode *must* be fitting. */
549         virtual RESULT setZoom(int what)=0;
550         
551         virtual RESULT setTrickmode(int what) = 0;
552 };
553
554 #endif