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