add cue sheets
[vuplus_dvbapp] / lib / dvb / idvb.h
1 #ifndef __dvb_idvb_h
2 #define __dvb_idvb_h
3
4 #if HAVE_DVB_API_VERSION < 3
5 #include <ost/frontend.h>
6 #define FRONTENDPARAMETERS FrontendParameters
7 #else
8 #include <linux/dvb/frontend.h>
9 #define FRONTENDPARAMETERS struct dvb_frontend_parameters
10 #endif
11 #include <lib/dvb/frontendparms.h>
12 #include <lib/base/object.h>
13 #include <lib/base/ebase.h>
14 #include <lib/service/service.h>
15 #include <libsig_comp.h>
16 #include <connection.h>
17
18 struct eBouquet
19 {
20         std::string m_bouquet_name;
21         std::string m_filename;  // without path.. just name
22         typedef std::list<eServiceReference> list;
23         list m_services;
24 // the following five methods are implemented in db.cpp
25         RESULT flushChanges();
26         RESULT addService(const eServiceReference &);
27         RESULT removeService(const eServiceReference &);
28         RESULT moveService(const eServiceReference &, unsigned int);
29         RESULT setListName(const std::string &name);
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         eServiceReferenceDVB(const std::string &string)
190                 :eServiceReference(string)
191         {
192         }
193 };
194
195
196 ////////////////// TODO: we need an interface here, but what exactly?
197
198 #include <set>
199 // btw, still implemented in db.cpp. FIX THIS, TOO.
200
201 class eDVBChannelQuery;
202
203 class eDVBService: public iStaticServiceInformation
204 {
205         DECLARE_REF(eDVBService);
206 public:
207         enum cacheID
208         {
209                 cVPID, cAPID, cTPID, cPCRPID, cAC3PID, cacheMax
210         };
211
212         int getCachePID(cacheID);
213         void setCachePID(cacheID, int);
214         bool cacheEmpty() { return m_cache.empty(); }
215
216         eDVBService();
217                 /* m_service_name_sort is uppercase, with special chars removed, to increase sort performance. */
218         std::string m_service_name, m_service_name_sort;
219         std::string m_provider_name;
220         
221         void genSortName();
222         
223         int m_flags;
224         std::set<int> m_ca;
225         std::map<int,int> m_cache;
226         virtual ~eDVBService();
227         
228         eDVBService &operator=(const eDVBService &);
229         
230         // iStaticServiceInformation
231         RESULT getName(const eServiceReference &ref, std::string &name);
232         RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time);
233         bool isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
234
235                 /* for filtering: */
236         int checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query);
237 };
238
239 //////////////////
240
241 class iDVBChannel;
242 class iDVBDemux;
243 class iDVBFrontendParameters;
244
245 class iDVBChannelListQuery: public iObject
246 {
247 public:
248         virtual RESULT getNextResult(eServiceReferenceDVB &ref)=0;
249         virtual int compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b)=0;
250 };
251
252 class eDVBChannelQuery: public iObject
253 {
254         DECLARE_REF(eDVBChannelQuery);
255 public:
256         enum
257         {
258                 tName,
259                 tProvider,
260                 tType,
261                 tBouquet,
262                 tSatellitePosition,
263                 tChannelID,
264                 tAND,
265                 tOR
266         };
267         
268         int m_type;
269         int m_inverse;
270         
271         std::string m_string;
272         int m_int;
273         eDVBChannelID m_channelid;
274         
275                 /* sort is only valid in root, and must be from the enum above. */
276         int m_sort;
277         std::string m_bouquet_name;
278         
279         static RESULT compile(ePtr<eDVBChannelQuery> &res, std::string query);
280         
281         ePtr<eDVBChannelQuery> m_p1, m_p2;
282 };
283
284 class iDVBChannelList: public iObject
285 {
286 public:
287         virtual RESULT addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)=0;
288         virtual RESULT removeChannel(const eDVBChannelID &id)=0;
289         
290         virtual RESULT getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)=0;
291         
292         virtual RESULT addService(const eServiceReferenceDVB &service, eDVBService *service)=0;
293         virtual RESULT getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)=0;
294         virtual RESULT flush()=0;
295
296         virtual RESULT getBouquet(const eServiceReference &ref,  eBouquet* &bouquet)=0;
297
298         virtual RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *query, const eServiceReference &source)=0;
299 };
300
301 class iDVBFrontendParameters: public iObject
302 {
303 public:
304         virtual RESULT getSystem(int &type) const = 0;
305         virtual RESULT getDVBS(eDVBFrontendParametersSatellite &p) const = 0;
306         virtual RESULT getDVBC(eDVBFrontendParametersCable &p) const = 0;
307         virtual RESULT getDVBT(eDVBFrontendParametersTerrestrial &p) const = 0;
308         
309         virtual RESULT calculateDifference(const iDVBFrontendParameters *parm, int &diff) const = 0;
310         virtual RESULT getHash(unsigned long &hash) const = 0;
311 };
312
313 #define MAX_DISEQC_LENGTH  16
314
315 class eDVBDiseqcCommand
316 {
317 public:
318         int len;
319         __u8 data[MAX_DISEQC_LENGTH];
320 #if HAVE_DVB_API_VERSION < 3
321         int tone;
322         int voltage;
323 #endif
324 };
325
326 class iDVBSatelliteEquipmentControl;
327 class eSecCommandList;
328
329 class iDVBFrontend: public iObject
330 {
331 public:
332         enum {
333                 feSatellite, feCable, feTerrestrial
334         };
335         virtual RESULT getFrontendType(int &type)=0;
336         virtual RESULT tune(const iDVBFrontendParameters &where)=0;
337         virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
338         enum {
339                 stateIdle = 0,
340                 stateTuning = 1,
341                 stateFailed = 2,
342                 stateLock = 3,
343                 stateLostLock = 4,
344         };
345         virtual RESULT getState(int &state)=0;
346         enum {
347                 toneOff, toneOn
348         };
349         virtual RESULT setTone(int tone)=0;
350         enum {
351                 voltageOff, voltage13, voltage18, voltage13_5, voltage18_5
352         };
353         virtual RESULT setVoltage(int voltage)=0;
354         virtual RESULT sendDiseqc(const eDVBDiseqcCommand &diseqc)=0;
355         virtual RESULT sendToneburst(int burst)=0;
356         virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0;
357         virtual RESULT setSecSequence(const eSecCommandList &list)=0;
358
359         enum {
360                 bitErrorRate, signalPower, signalQuality
361         };
362         virtual int readFrontendData(int type)=0;
363
364         virtual RESULT getData(int num, int &data)=0;
365         virtual RESULT setData(int num, int val)=0;
366         
367                 /* 0 means: not compatible. other values are a priority. */
368         virtual int isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)=0;
369 };
370
371 class iDVBSatelliteEquipmentControl: public iObject
372 {
373 public:
374         virtual RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, eDVBFrontendParametersSatellite &sat, int frontend_id)=0;
375         virtual int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *fe, int frontend_id)=0;
376         virtual void setRotorMoving(bool)=0;
377 };
378
379 struct eDVBCIRouting
380 {
381         int enabled;
382 };
383
384 class iDVBChannel: public iObject
385 {
386 public:
387         enum
388         {
389                 state_idle,        /* not yet tuned */
390                 state_tuning,      /* currently tuning (first time) */
391                 state_failed,      /* tuning failed. */
392                 state_unavailable, /* currently unavailable, will be back without further interaction */
393                 state_ok,          /* ok */
394                 state_release      /* channel is being shut down. */
395         };
396         
397         enum 
398         {
399                 evtEOF, evtSOF, evtFailed
400         };
401         virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
402         virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
403         virtual RESULT getState(int &state)=0;
404         
405                 /* demux capabilities */
406         enum
407         {
408                 capDecode = 1,
409                 /* capCI = 2 */
410         };
411         virtual RESULT setCIRouting(const eDVBCIRouting &routing)=0;
412         virtual RESULT getDemux(ePtr<iDVBDemux> &demux, int cap=0)=0;
413         
414                 /* direct frontend access for raw channels and/or status inquiries. */
415         virtual RESULT getFrontend(ePtr<iDVBFrontend> &frontend)=0;
416         
417                 /* use count handling */
418         virtual void AddUse() = 0;
419         virtual void ReleaseUse() = 0;
420 };
421
422         /* signed, so we can express deltas. */
423         
424 typedef long long pts_t;
425
426 class iFilePushScatterGather;
427
428         /* note that a cue sheet describes the logical positions. thus 
429            everything is specified in pts and not file positions */
430
431         /* implemented in dvb.cpp */
432 class eCueSheet: public iObject, public Object
433 {
434         DECLARE_REF(eCueSheet);
435 public:
436         eCueSheet();
437         
438                         /* frontend */
439         void seekTo(int relative, const pts_t &pts);
440         
441         void clear();
442         void addSourceSpan(const pts_t &begin, const pts_t &end);
443         
444         void setSkipmode(const pts_t &ratio); /* 90000 is 1:1 */
445         void setDecodingDemux(iDVBDemux *demux);
446         
447                         /* backend */
448         enum { evtSeek, evtSkipmode, evtSpanChanged };
449         RESULT connectEvent(const Slot1<void, int> &event, ePtr<eConnection> &connection);
450
451         std::list<std::pair<pts_t,pts_t> > m_spans;     /* begin, end */
452         std::list<std::pair<int, pts_t> > m_seek_requests; /* relative, delta */
453         pts_t m_skipmode_ratio;
454         Signal1<void,int> m_event;
455         ePtr<iDVBDemux> m_decoding_demux;
456 };
457
458 class iDVBPVRChannel: public iDVBChannel
459 {
460 public:
461         enum
462         {
463                 state_eof = state_release + 1  /* end-of-file reached. */
464         };
465         
466                 /* FIXME: there are some very ugly buffer-end and ... related problems */
467                 /* so this is VERY UGLY. 
468                 
469                    ok, it's going to get better. but still...*/
470         virtual RESULT playFile(const char *file) = 0;
471         virtual void stopFile() = 0;
472         
473         virtual void setCueSheet(eCueSheet *cuesheet) = 0;
474         
475         virtual RESULT getLength(pts_t &pts) = 0;
476         
477                 /* we explicitely ask for the decoding demux here because a channel
478                    can be shared between multiple decoders.
479                 */
480         virtual RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode) = 0;
481                 /* skipping must be done with a cue sheet */
482 };
483
484 class iDVBSectionReader;
485 class iDVBTSRecorder;
486 class iTSMPEGDecoder;
487
488 class iDVBDemux: public iObject
489 {
490 public:
491         virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
492         virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
493         virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader)=0;
494         virtual RESULT getSTC(pts_t &pts, int num=0)=0;
495         virtual RESULT getCADemuxID(uint8_t &id)=0;
496         virtual RESULT flush()=0;
497 };
498
499 class iTSMPEGDecoder: public iObject
500 {
501 public:
502         enum { pidDisabled = -1 };
503                 /** Set Displayed Video PID */
504         virtual RESULT setVideoPID(int vpid)=0;
505
506         enum { af_MPEG, af_AC3, af_DTS };
507                 /** Set Displayed Audio PID and type */
508         virtual RESULT setAudioPID(int apid, int type)=0;
509
510                 /** Set Displayed Videotext PID */
511         virtual RESULT setTextPID(int vpid)=0;
512
513                 /** Set Sync mode to PCR */
514         virtual RESULT setSyncPCR(int pcrpid)=0;
515         enum { sm_Audio, sm_Video };
516                 /** Set Sync mode to either audio or video master */
517         virtual RESULT setSyncMaster(int who)=0;
518
519                 /** Apply settings */
520         virtual RESULT start()=0;
521         
522                 /** Freeze frame. Either continue decoding (without display) or halt. */
523         virtual RESULT freeze(int cont)=0;
524                 /** Continue after freeze. */
525         virtual RESULT unfreeze()=0;
526         
527                 /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
528         virtual RESULT setFastForward(int skip=0)=0;
529         
530                 // stop on .. Picture
531         enum { spm_I, spm_Ref, spm_Any };
532                 /** Stop on specific decoded picture. For I-Frame display. */
533         virtual RESULT setSinglePictureMode(int when)=0;
534         
535         enum { pkm_B, pkm_PB };
536                 /** Fast forward by skipping either B or P/B pictures */
537         virtual RESULT setPictureSkipMode(int what)=0;
538         
539                 /** Slow Motion by repeating pictures */
540         virtual RESULT setSlowMotion(int repeat)=0;
541         
542         enum { zoom_Normal, zoom_PanScan, zoom_Letterbox, zoom_Fullscreen };
543                 /** Set Zoom. mode *must* be fitting. */
544         virtual RESULT setZoom(int what)=0;
545         
546         virtual RESULT setTrickmode(int what) = 0;
547 };
548
549 #endif