da7ac3b5ca033ded6019feb0abfa0633ac1a7bbc
[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 class iTSMPEGDecoder;
430
431         /* note that a cue sheet describes the logical positions. thus 
432            everything is specified in pts and not file positions */
433
434         /* implemented in dvb.cpp */
435 class eCueSheet: public iObject, public Object
436 {
437         DECLARE_REF(eCueSheet);
438 public:
439         eCueSheet();
440         
441                         /* frontend */
442         void seekTo(int relative, const pts_t &pts);
443         
444         void clear();
445         void addSourceSpan(const pts_t &begin, const pts_t &end);
446         void commitSpans();
447         
448         void setSkipmode(const pts_t &ratio); /* 90000 is 1:1 */
449         void setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder);
450         
451                         /* frontend and backend */
452         eSingleLock m_lock;
453         
454                         /* backend */
455         enum { evtSeek, evtSkipmode, evtSpanChanged };
456         RESULT connectEvent(const Slot1<void, int> &event, ePtr<eConnection> &connection);
457
458         std::list<std::pair<pts_t,pts_t> > m_spans;     /* begin, end */
459         std::list<std::pair<int, pts_t> > m_seek_requests; /* relative, delta */
460         pts_t m_skipmode_ratio;
461         Signal1<void,int> m_event;
462         ePtr<iDVBDemux> m_decoding_demux;
463         ePtr<iTSMPEGDecoder> m_decoder;
464 };
465
466 class iDVBPVRChannel: public iDVBChannel
467 {
468 public:
469         enum
470         {
471                 state_eof = state_release + 1  /* end-of-file reached. */
472         };
473         
474                 /* FIXME: there are some very ugly buffer-end and ... related problems */
475                 /* so this is VERY UGLY. 
476                 
477                    ok, it's going to get better. but still...*/
478         virtual RESULT playFile(const char *file) = 0;
479         virtual void stopFile() = 0;
480         
481         virtual void setCueSheet(eCueSheet *cuesheet) = 0;
482         
483         virtual RESULT getLength(pts_t &pts) = 0;
484         
485                 /* we explicitely ask for the decoding demux here because a channel
486                    can be shared between multiple decoders.
487                 */
488         virtual RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode) = 0;
489                 /* skipping must be done with a cue sheet */
490 };
491
492 class iDVBSectionReader;
493 class iDVBTSRecorder;
494 class iTSMPEGDecoder;
495
496 class iDVBDemux: public iObject
497 {
498 public:
499         virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
500         virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
501         virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader)=0;
502         virtual RESULT getSTC(pts_t &pts, int num=0)=0;
503         virtual RESULT getCADemuxID(uint8_t &id)=0;
504         virtual RESULT flush()=0;
505 };
506
507 class iTSMPEGDecoder: public iObject
508 {
509 public:
510         enum { pidDisabled = -1 };
511                 /** Set Displayed Video PID */
512         virtual RESULT setVideoPID(int vpid)=0;
513
514         enum { af_MPEG, af_AC3, af_DTS };
515                 /** Set Displayed Audio PID and type */
516         virtual RESULT setAudioPID(int apid, int type)=0;
517
518                 /** Set Displayed Videotext PID */
519         virtual RESULT setTextPID(int vpid)=0;
520
521                 /** Set Sync mode to PCR */
522         virtual RESULT setSyncPCR(int pcrpid)=0;
523         enum { sm_Audio, sm_Video };
524                 /** Set Sync mode to either audio or video master */
525         virtual RESULT setSyncMaster(int who)=0;
526
527                 /** Apply settings */
528         virtual RESULT start()=0;
529         
530                 /** Freeze frame. Either continue decoding (without display) or halt. */
531         virtual RESULT freeze(int cont)=0;
532                 /** Continue after freeze. */
533         virtual RESULT unfreeze()=0;
534         
535                 /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
536         virtual RESULT setFastForward(int skip=0)=0;
537         
538                 // stop on .. Picture
539         enum { spm_I, spm_Ref, spm_Any };
540                 /** Stop on specific decoded picture. For I-Frame display. */
541         virtual RESULT setSinglePictureMode(int when)=0;
542         
543         enum { pkm_B, pkm_PB };
544                 /** Fast forward by skipping either B or P/B pictures */
545         virtual RESULT setPictureSkipMode(int what)=0;
546         
547                 /** Slow Motion by repeating pictures */
548         virtual RESULT setSlowMotion(int repeat)=0;
549         
550         enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen };
551                 /** Set Zoom. mode *must* be fitting. */
552         virtual RESULT setZoom(int what)=0;
553         
554         virtual RESULT setTrickmode(int what) = 0;
555         
556         virtual RESULT getPTS(int what, pts_t &pts) = 0;
557 };
558
559 #endif