add ability to selecte the audio channel (mono left, stereo, mono right) from python
[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, cVTYPE, cACHANNEL, cacheMax
227         };
228
229         int getCacheEntry(cacheID);
230         void setCacheEntry(cacheID, int);
231
232         bool cacheEmpty();
233
234         eDVBService();
235                 /* m_service_name_sort is uppercase, with special chars removed, to increase sort performance. */
236         std::string m_service_name, m_service_name_sort;
237         std::string m_provider_name;
238         
239         void genSortName();
240
241         int m_flags;
242         enum
243         {
244                 dxNoSDT=1,    // don't get SDT
245 //nyi   dxDontshow=2,
246                 dxNoDVB=4,  // dont use PMT for this service ( use cached pids )
247                 dxHoldName=8,
248                 dxNewFound=64,
249         };
250
251         bool usePMT() const { return !(m_flags & dxNoDVB); }
252
253 //      std::set<int> m_ca;
254
255         int m_cache[cacheMax];
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                 tFlags
298         };
299         
300         int m_type;
301         int m_inverse;
302         
303         std::string m_string;
304         int m_int;
305         eDVBChannelID m_channelid;
306         
307                 /* sort is only valid in root, and must be from the enum above. */
308         int m_sort;
309         std::string m_bouquet_name;
310         
311         static RESULT compile(ePtr<eDVBChannelQuery> &res, std::string query);
312         
313         ePtr<eDVBChannelQuery> m_p1, m_p2;
314 };
315
316 class iDVBChannelList: public iObject
317 {
318 public:
319         virtual RESULT removeService(const eServiceReference &service)=0;
320         virtual RESULT removeServices(eDVBChannelID chid=eDVBChannelID(), unsigned int orb_pos=0xFFFFFFFF)=0;
321         virtual RESULT removeServices(int dvb_namespace=-1, int tsid=-1, int onid=-1, unsigned int orb_pos=0xFFFFFFFF)=0;
322         virtual RESULT addFlag(const eServiceReference &service, unsigned int flagmask=0xFFFFFFFF)=0;
323         virtual RESULT removeFlag(const eServiceReference &service, unsigned int flagmask=0xFFFFFFFF)=0;
324         virtual RESULT removeFlags(unsigned int flagmask, eDVBChannelID chid=eDVBChannelID(), unsigned int orb_pos=0xFFFFFFFF)=0;
325         virtual RESULT removeFlags(unsigned int flagmask, int dvb_namespace=-1, int tsid=-1, int onid=-1, unsigned int orb_pos=0xFFFFFFFF)=0;
326         virtual RESULT addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)=0;
327         virtual RESULT removeChannel(const eDVBChannelID &id)=0;
328         
329         virtual RESULT getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)=0;
330         
331         virtual RESULT addService(const eServiceReferenceDVB &service, eDVBService *service)=0;
332         virtual RESULT getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)=0;
333         virtual RESULT flush()=0;
334
335         virtual RESULT getBouquet(const eServiceReference &ref,  eBouquet* &bouquet)=0;
336
337         virtual RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *query, const eServiceReference &source)=0;
338 };
339
340 #endif  // SWIG
341
342 class iDVBFrontendParameters: public iObject
343 {
344 #ifdef SWIG
345         iDVBFrontendParameters();
346         ~iDVBFrontendParameters();
347 #endif
348 public:
349         virtual RESULT getSystem(int &SWIG_OUTPUT) const = 0;
350         virtual RESULT getDVBS(eDVBFrontendParametersSatellite &SWIG_OUTPUT) const = 0;
351         virtual RESULT getDVBC(eDVBFrontendParametersCable &SWIG_OUTPUT) const = 0;
352         virtual RESULT getDVBT(eDVBFrontendParametersTerrestrial &SWIG_OUTPUT) const = 0;
353         
354         virtual RESULT calculateDifference(const iDVBFrontendParameters *parm, int &SWIG_OUTPUT) const = 0;
355         virtual RESULT getHash(unsigned long &SWIG_OUTPUT) const = 0;
356 };
357
358 #define MAX_DISEQC_LENGTH  16
359
360 class eDVBDiseqcCommand
361 {
362 #ifndef SWIG
363 public:
364 #endif
365         int len;
366         __u8 data[MAX_DISEQC_LENGTH];
367 #if HAVE_DVB_API_VERSION < 3
368         int tone;
369         int voltage;
370 #endif
371 #ifdef SWIG
372 public:
373 #endif
374         void setCommandString(const char *str);
375 };
376
377 class iDVBSatelliteEquipmentControl;
378 class eSecCommandList;
379
380 class iDVBFrontend: public iObject
381 {
382 public:
383         enum {
384                 feSatellite, feCable, feTerrestrial
385         };
386         virtual RESULT getFrontendType(int &SWIG_OUTPUT)=0;
387         virtual RESULT tune(const iDVBFrontendParameters &where)=0;
388 #ifndef SWIG
389         virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
390 #endif
391         enum {
392                 stateIdle = 0,
393                 stateTuning = 1,
394                 stateFailed = 2,
395                 stateLock = 3,
396                 stateLostLock = 4,
397         };
398         virtual RESULT getState(int &SWIG_OUTPUT)=0;
399         enum {
400                 toneOff, toneOn
401         };
402         virtual RESULT setTone(int tone)=0;
403         enum {
404                 voltageOff, voltage13, voltage18, voltage13_5, voltage18_5
405         };
406         virtual RESULT setVoltage(int voltage)=0;
407         virtual RESULT sendDiseqc(const eDVBDiseqcCommand &diseqc)=0;
408         virtual RESULT sendToneburst(int burst)=0;
409 #ifndef SWIG
410         virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0;
411         virtual RESULT setSecSequence(const eSecCommandList &list)=0;
412 #endif
413         enum {
414                 bitErrorRate, signalPower, signalQuality, Locked, Synced
415         };
416         virtual int readFrontendData(int type)=0;
417         virtual PyObject *readTransponderData(bool original)=0;
418
419 #ifndef SWIG
420         virtual RESULT getData(int num, int &data)=0;
421         virtual RESULT setData(int num, int val)=0;
422                 /* 0 means: not compatible. other values are a priority. */
423         virtual int isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)=0;
424 #endif
425 };
426 TEMPLATE_TYPEDEF(ePtr<iDVBFrontend>, iDVBFrontendPtr);
427
428 #ifndef SWIG
429 class iDVBSatelliteEquipmentControl: public iObject
430 {
431 public:
432         virtual RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int frontend_id)=0;
433         virtual int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *fe, int frontend_id)=0;
434         virtual void setRotorMoving(bool)=0;
435 };
436
437 struct eDVBCIRouting
438 {
439         int enabled;
440 };
441 #endif // SWIG
442
443 class iDVBChannel: public iObject
444 {
445 public:
446         enum
447         {
448                 state_idle,        /* not yet tuned */
449                 state_tuning,      /* currently tuning (first time) */
450                 state_failed,      /* tuning failed. */
451                 state_unavailable, /* currently unavailable, will be back without further interaction */
452                 state_ok,          /* ok */
453                 state_last_instance, /* just one reference to this channel is left */
454                 state_release      /* channel is being shut down. */
455         };
456         virtual RESULT getState(int &SWIG_OUTPUT)=0;    
457
458                 /* direct frontend access for raw channels and/or status inquiries. */
459         virtual RESULT getFrontend(ePtr<iDVBFrontend> &)=0;
460
461 #ifndef SWIG
462         virtual RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &)=0;
463         enum 
464         {
465                 evtEOF, evtSOF, evtFailed
466         };
467         virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
468         virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
469
470                 /* demux capabilities */
471         enum
472         {
473                 capDecode = 1,
474                 /* capCI = 2 */
475         };
476         virtual RESULT setCIRouting(const eDVBCIRouting &routing)=0;
477         virtual RESULT getDemux(ePtr<iDVBDemux> &demux, int cap=0)=0;
478         
479                 /* use count handling */
480         virtual void AddUse() = 0;
481         virtual void ReleaseUse() = 0;
482 #endif
483 };
484 TEMPLATE_TYPEDEF(eUsePtr<iDVBChannel>, iDVBChannelPtr);
485
486 #ifndef SWIG
487
488         /* signed, so we can express deltas. */
489         
490 typedef long long pts_t;
491
492 class iFilePushScatterGather;
493 class iTSMPEGDecoder;
494
495         /* note that a cue sheet describes the logical positions. thus 
496            everything is specified in pts and not file positions */
497
498         /* implemented in dvb.cpp */
499 class eCueSheet: public iObject, public Object
500 {
501         DECLARE_REF(eCueSheet);
502 public:
503         eCueSheet();
504         
505                         /* frontend */
506         void seekTo(int relative, const pts_t &pts);
507         
508         void clear();
509         void addSourceSpan(const pts_t &begin, const pts_t &end);
510         void commitSpans();
511         
512         void setSkipmode(const pts_t &ratio); /* 90000 is 1:1 */
513         void setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder);
514         
515                         /* frontend and backend */
516         eSingleLock m_lock;
517         
518                         /* backend */
519         enum { evtSeek, evtSkipmode, evtSpanChanged };
520         RESULT connectEvent(const Slot1<void, int> &event, ePtr<eConnection> &connection);
521
522         std::list<std::pair<pts_t,pts_t> > m_spans;     /* begin, end */
523         std::list<std::pair<int, pts_t> > m_seek_requests; /* relative, delta */
524         pts_t m_skipmode_ratio;
525         Signal1<void,int> m_event;
526         ePtr<iDVBDemux> m_decoding_demux;
527         ePtr<iTSMPEGDecoder> m_decoder;
528 };
529
530 class iDVBPVRChannel: public iDVBChannel
531 {
532 public:
533         enum
534         {
535                 state_eof = state_release + 1  /* end-of-file reached. */
536         };
537         
538                 /* FIXME: there are some very ugly buffer-end and ... related problems */
539                 /* so this is VERY UGLY. 
540                 
541                    ok, it's going to get better. but still...*/
542         virtual RESULT playFile(const char *file) = 0;
543         virtual void stopFile() = 0;
544         
545         virtual void setCueSheet(eCueSheet *cuesheet) = 0;
546         
547         virtual RESULT getLength(pts_t &pts) = 0;
548         
549                 /* we explicitely ask for the decoding demux here because a channel
550                    can be shared between multiple decoders.
551                 */
552         virtual RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode) = 0;
553                 /* skipping must be done with a cue sheet */
554 };
555
556 class iDVBSectionReader;
557 class iDVBPESReader;
558 class iDVBTSRecorder;
559 class iTSMPEGDecoder;
560
561 class iDVBDemux: public iObject
562 {
563 public:
564         virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
565         virtual RESULT createPESReader(eMainloop *context, ePtr<iDVBPESReader> &reader)=0;
566         virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
567         virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader, int primary=1)=0;
568         virtual RESULT getSTC(pts_t &pts, int num=0)=0;
569         virtual RESULT getCADemuxID(uint8_t &id)=0;
570         virtual RESULT flush()=0;
571 };
572
573 class iTSMPEGDecoder: public iObject
574 {
575 public:
576         enum { pidDisabled = -1 };
577                 /** Set Displayed Video PID and type */
578         virtual RESULT setVideoPID(int vpid, int type)=0;
579
580         enum { af_MPEG, af_AC3, af_DTS, af_AAC };
581                 /** Set Displayed Audio PID and type */
582         virtual RESULT setAudioPID(int apid, int type)=0;
583
584         enum { ac_left, ac_stereo, ac_right };
585                 /** Set Displayed Audio Channel */
586         virtual RESULT setAudioChannel(int channel)=0;
587
588                 /** Set Displayed Videotext PID */
589         virtual RESULT setTextPID(int vpid)=0;
590
591                 /** Set Sync mode to PCR */
592         virtual RESULT setSyncPCR(int pcrpid)=0;
593         enum { sm_Audio, sm_Video };
594                 /** Set Sync mode to either audio or video master */
595         virtual RESULT setSyncMaster(int who)=0;
596
597                 /** Apply settings */
598         virtual RESULT start()=0;
599         
600                 /** Freeze frame. Either continue decoding (without display) or halt. */
601         virtual RESULT freeze(int cont)=0;
602                 /** Continue after freeze. */
603         virtual RESULT unfreeze()=0;
604         
605                 /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
606         virtual RESULT setFastForward(int skip=0)=0;
607         
608                 // stop on .. Picture
609         enum { spm_I, spm_Ref, spm_Any };
610                 /** Stop on specific decoded picture. For I-Frame display. */
611         virtual RESULT setSinglePictureMode(int when)=0;
612         
613         enum { pkm_B, pkm_PB };
614                 /** Fast forward by skipping either B or P/B pictures */
615         virtual RESULT setPictureSkipMode(int what)=0;
616         
617                 /** Slow Motion by repeating pictures */
618         virtual RESULT setSlowMotion(int repeat)=0;
619         
620         enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen };
621                 /** Set Zoom. mode *must* be fitting. */
622         virtual RESULT setZoom(int what)=0;
623         
624         virtual RESULT setTrickmode(int what) = 0;
625         
626         virtual RESULT getPTS(int what, pts_t &pts) = 0;
627 };
628
629 #endif //SWIG
630 #endif