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