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