6 #include <linux/dvb/frontend.h>
7 #include <linux/dvb/video.h>
8 #define FRONTENDPARAMETERS struct dvb_frontend_parameters
9 #include <lib/dvb/frontendparms.h>
10 #include <lib/base/object.h>
11 #include <lib/base/ebase.h>
12 #include <lib/base/elock.h>
13 #include <lib/base/itssource.h>
14 #include <lib/service/service.h>
15 #include <libsig_comp.h>
16 #include <connection.h>
18 #if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ >= 1) || __GNUC__ == 4 ) // check if gcc version >= 3.1
20 #define CAID_LIST __gnu_cxx::slist<uint16_t>
23 #define CAID_LIST std::slist<uint16_t>
26 #ifndef DMX_FILTER_SIZE
27 #define DMX_FILTER_SIZE 16
30 struct eDVBSectionFilterMask
33 /* mode is 0 for positive, 1 for negative filtering */
34 __u8 data[DMX_FILTER_SIZE], mask[DMX_FILTER_SIZE], mode[DMX_FILTER_SIZE];
44 int pid, tid, tidext, tid_mask, tidext_mask;
46 int timeout; /* timeout in ms */
51 tfAnyVersion filter ANY version
52 0 filter all EXCEPT given version (negative filtering)
53 tfThisVersion filter only THIS version
69 std::string m_bouquet_name;
70 std::string m_filename; // without path.. just name
71 typedef std::list<eServiceReference> list;
73 // the following five methods are implemented in db.cpp
74 RESULT flushChanges();
75 RESULT addService(const eServiceReference &, eServiceReference before=eServiceReference());
76 RESULT removeService(const eServiceReference &);
77 RESULT moveService(const eServiceReference &, unsigned int);
78 RESULT setListName(const std::string &name);
81 /* these structures have by intention no operator int() defined.
82 the reason of these structures is to avoid mixing for example
83 a onid and a tsid (as there's no general order for them).
85 defining an operator int() would implicitely convert values
86 between them over the constructor with the int argument.
88 'explicit' doesn't here - eTransportStreamID(eOriginalNetworkID(n))
91 struct eTransportStreamID
96 int get() const { return v; }
97 eTransportStreamID(int i): v(i) { }
98 eTransportStreamID(): v(-1) { }
99 bool operator == (const eTransportStreamID &c) const { return v == c.v; }
100 bool operator != (const eTransportStreamID &c) const { return v != c.v; }
101 bool operator < (const eTransportStreamID &c) const { return v < c.v; }
102 bool operator > (const eTransportStreamID &c) const { return v > c.v; }
110 int get() const { return v; }
111 eServiceID(int i): v(i) { }
112 eServiceID(): v(-1) { }
113 bool operator == (const eServiceID &c) const { return v == c.v; }
114 bool operator != (const eServiceID &c) const { return v != c.v; }
115 bool operator < (const eServiceID &c) const { return v < c.v; }
116 bool operator > (const eServiceID &c) const { return v > c.v; }
119 struct eOriginalNetworkID
124 int get() const { return v; }
125 eOriginalNetworkID(int i): v(i) { }
126 eOriginalNetworkID(): v(-1) { }
127 bool operator == (const eOriginalNetworkID &c) const { return v == c.v; }
128 bool operator != (const eOriginalNetworkID &c) const { return v != c.v; }
129 bool operator < (const eOriginalNetworkID &c) const { return v < c.v; }
130 bool operator > (const eOriginalNetworkID &c) const { return v > c.v; }
138 int get() const { return v; }
139 eDVBNamespace(int i): v(i) { }
140 eDVBNamespace(): v(-1) { }
141 bool operator == (const eDVBNamespace &c) const { return v == c.v; }
142 bool operator != (const eDVBNamespace &c) const { return v != c.v; }
143 bool operator < (const eDVBNamespace &c) const { return v < c.v; }
144 bool operator > (const eDVBNamespace &c) const { return v > c.v; }
149 eDVBNamespace dvbnamespace;
150 eTransportStreamID transport_stream_id;
151 eOriginalNetworkID original_network_id;
153 bool operator==(const eDVBChannelID &c) const
155 return dvbnamespace == c.dvbnamespace &&
156 transport_stream_id == c.transport_stream_id &&
157 original_network_id == c.original_network_id;
160 bool operator<(const eDVBChannelID &c) const
162 if (dvbnamespace < c.dvbnamespace)
164 else if (dvbnamespace == c.dvbnamespace)
166 if (original_network_id < c.original_network_id)
168 else if (original_network_id == c.original_network_id)
169 if (transport_stream_id < c.transport_stream_id)
174 eDVBChannelID(eDVBNamespace dvbnamespace, eTransportStreamID tsid, eOriginalNetworkID onid):
175 dvbnamespace(dvbnamespace), transport_stream_id(tsid), original_network_id(onid)
179 dvbnamespace(-1), transport_stream_id(-1), original_network_id(-1)
182 operator bool() const
184 return (dvbnamespace != -1) && (transport_stream_id != -1) && (original_network_id != -1);
188 struct eServiceReferenceDVB: public eServiceReference
190 int getServiceType() const { return data[0]; }
191 void setServiceType(int service_type) { data[0]=service_type; }
193 eServiceID getServiceID() const { return eServiceID(data[1]); }
194 void setServiceID(eServiceID service_id) { data[1]=service_id.get(); }
196 eTransportStreamID getTransportStreamID() const { return eTransportStreamID(data[2]); }
197 void setTransportStreamID(eTransportStreamID transport_stream_id) { data[2]=transport_stream_id.get(); }
199 eOriginalNetworkID getOriginalNetworkID() const { return eOriginalNetworkID(data[3]); }
200 void setOriginalNetworkID(eOriginalNetworkID original_network_id) { data[3]=original_network_id.get(); }
202 eDVBNamespace getDVBNamespace() const { return eDVBNamespace(data[4]); }
203 void setDVBNamespace(eDVBNamespace dvbnamespace) { data[4]=dvbnamespace.get(); }
205 eServiceID getParentServiceID() const { return eServiceID(data[5]); }
206 void setParentServiceID( eServiceID sid ) { data[5]=sid.get(); }
208 eTransportStreamID getParentTransportStreamID() const { return eTransportStreamID(data[6]); }
209 void setParentTransportStreamID( eTransportStreamID tsid ) { data[6]=tsid.get(); }
211 eServiceReferenceDVB getParentServiceReference() const
213 eServiceReferenceDVB tmp(*this);
214 if (data[5] && data[6])
216 tmp.data[1] = data[5];
217 tmp.data[2] = data[6];
218 tmp.data[5] = tmp.data[6] = 0;
221 tmp.type = idInvalid;
225 eServiceReferenceDVB(eDVBNamespace dvbnamespace, eTransportStreamID transport_stream_id, eOriginalNetworkID original_network_id, eServiceID service_id, int service_type)
226 :eServiceReference(eServiceReference::idDVB, 0)
228 setTransportStreamID(transport_stream_id);
229 setOriginalNetworkID(original_network_id);
230 setDVBNamespace(dvbnamespace);
231 setServiceID(service_id);
232 setServiceType(service_type);
235 void set(const eDVBChannelID &chid)
237 setDVBNamespace(chid.dvbnamespace);
238 setOriginalNetworkID(chid.original_network_id);
239 setTransportStreamID(chid.transport_stream_id);
242 void getChannelID(eDVBChannelID &chid) const
244 chid = eDVBChannelID(getDVBNamespace(), getTransportStreamID(), getOriginalNetworkID());
247 eServiceReferenceDVB()
248 :eServiceReference(eServiceReference::idDVB, 0)
252 eServiceReferenceDVB(const std::string &string)
253 :eServiceReference(string)
259 ////////////////// TODO: we need an interface here, but what exactly?
262 // btw, still implemented in db.cpp. FIX THIS, TOO.
264 class eDVBChannelQuery;
266 class eDVBService: public iStaticServiceInformation
268 DECLARE_REF(eDVBService);
271 void copyCache(int *source);
275 cVPID, cMPEGAPID, cTPID, cPCRPID, cAC3PID,
276 cVTYPE, cACHANNEL, cAC3DELAY, cPCMDELAY,
277 cSUBTITLE, cAACHEAPID=12, cDDPPID, cAACAPID, cacheMax
280 int getCacheEntry(cacheID);
281 void setCacheEntry(cacheID, int);
286 /* m_service_name_sort is uppercase, with special chars removed, to increase sort performance. */
287 std::string m_service_name, m_service_name_sort;
288 std::string m_provider_name;
295 dxNoSDT=1, // don't get SDT
297 dxNoDVB=4, // dont use PMT for this service ( use cached pids )
302 bool usePMT() const { return !(m_flags & dxNoDVB); }
303 bool isHidden() const { return m_flags & dxDontshow; }
307 virtual ~eDVBService();
309 eDVBService &operator=(const eDVBService &);
311 // iStaticServiceInformation
312 RESULT getName(const eServiceReference &ref, std::string &name);
313 RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time);
314 int isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate=false);
315 PyObject *getInfoObject(const eServiceReference &ref, int); // implemented in lib/service/servicedvb.h
318 int checkFilter(const eServiceReferenceDVB &ref, const eDVBChannelQuery &query);
325 class iDVBFrontendParameters;
327 class iDVBChannelListQuery: public iObject
330 virtual RESULT getNextResult(eServiceReferenceDVB &ref)=0;
331 virtual int compareLessEqual(const eServiceReferenceDVB &a, const eServiceReferenceDVB &b)=0;
334 class eDVBChannelQuery: public iObject
336 DECLARE_REF(eDVBChannelQuery);
355 std::string m_string;
357 eDVBChannelID m_channelid;
359 /* sort is only valid in root, and must be from the enum above. */
361 std::string m_bouquet_name;
363 static RESULT compile(ePtr<eDVBChannelQuery> &res, std::string query);
365 ePtr<eDVBChannelQuery> m_p1, m_p2;
368 class iDVBChannelList: public iObject
371 virtual RESULT removeService(const eServiceReference &service)=0;
372 virtual RESULT removeServices(eDVBChannelID chid=eDVBChannelID(), unsigned int orb_pos=0xFFFFFFFF)=0;
373 virtual RESULT removeServices(int dvb_namespace=-1, int tsid=-1, int onid=-1, unsigned int orb_pos=0xFFFFFFFF)=0;
374 virtual RESULT removeServices(iDVBFrontendParameters *feparm)=0;
375 virtual RESULT addFlag(const eServiceReference &service, unsigned int flagmask=0xFFFFFFFF)=0;
376 virtual RESULT removeFlag(const eServiceReference &service, unsigned int flagmask=0xFFFFFFFF)=0;
377 virtual RESULT removeFlags(unsigned int flagmask, eDVBChannelID chid=eDVBChannelID(), unsigned int orb_pos=0xFFFFFFFF)=0;
378 virtual RESULT removeFlags(unsigned int flagmask, int dvb_namespace=-1, int tsid=-1, int onid=-1, unsigned int orb_pos=0xFFFFFFFF)=0;
379 virtual RESULT addChannelToList(const eDVBChannelID &id, iDVBFrontendParameters *feparm)=0;
380 virtual RESULT removeChannel(const eDVBChannelID &id)=0;
382 virtual RESULT getChannelFrontendData(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &parm)=0;
384 virtual RESULT addService(const eServiceReferenceDVB &reference, eDVBService *service)=0;
385 virtual RESULT getService(const eServiceReferenceDVB &reference, ePtr<eDVBService> &service)=0;
386 virtual RESULT flush()=0;
388 virtual RESULT getBouquet(const eServiceReference &ref, eBouquet* &bouquet)=0;
390 virtual RESULT startQuery(ePtr<iDVBChannelListQuery> &query, eDVBChannelQuery *q, const eServiceReference &source)=0;
395 class iDVBFrontendParameters: public iObject
398 iDVBFrontendParameters();
399 ~iDVBFrontendParameters();
402 enum { flagOnlyFree = 1 };
403 virtual SWIG_VOID(RESULT) getSystem(int &SWIG_OUTPUT) const = 0;
404 virtual SWIG_VOID(RESULT) getDVBS(eDVBFrontendParametersSatellite &SWIG_OUTPUT) const = 0;
405 virtual SWIG_VOID(RESULT) getDVBC(eDVBFrontendParametersCable &SWIG_OUTPUT) const = 0;
406 virtual SWIG_VOID(RESULT) getDVBT(eDVBFrontendParametersTerrestrial &SWIG_OUTPUT) const = 0;
407 virtual SWIG_VOID(RESULT) getFlags(unsigned int &SWIG_OUTPUT) const = 0;
409 virtual SWIG_VOID(RESULT) calculateDifference(const iDVBFrontendParameters *parm, int &, bool exact) const = 0;
410 virtual SWIG_VOID(RESULT) getHash(unsigned long &) const = 0;
411 virtual SWIG_VOID(RESULT) calcLockTimeout(unsigned int &) const = 0;
414 SWIG_TEMPLATE_TYPEDEF(ePtr<iDVBFrontendParameters>, iDVBFrontendParametersPtr);
416 #define MAX_DISEQC_LENGTH 16
418 class eDVBDiseqcCommand
424 __u8 data[MAX_DISEQC_LENGTH];
428 void setCommandString(const char *str);
431 class iDVBSatelliteEquipmentControl;
432 class eSecCommandList;
434 class iDVBFrontend_ENUMS
437 iDVBFrontend_ENUMS();
438 ~iDVBFrontend_ENUMS();
441 enum { feSatellite, feCable, feTerrestrial };
442 enum { stateIdle, stateTuning, stateFailed, stateLock, stateLostLock, stateClosed };
443 enum { toneOff, toneOn };
444 enum { voltageOff, voltage13, voltage18, voltage13_5, voltage18_5 };
445 enum { bitErrorRate, signalPower, signalQuality, locked, synced, frontendNumber, signalQualitydB, isUsbTuner };
448 SWIG_IGNORE(iDVBFrontend);
449 class iDVBFrontend: public iDVBFrontend_ENUMS, public iObject
452 virtual RESULT tune(const iDVBFrontendParameters &where)=0;
453 virtual int closeFrontend(bool force = false, bool no_delayed = false)=0;
454 virtual void reopenFrontend()=0;
456 virtual RESULT connectStateChange(const Slot1<void,iDVBFrontend*> &stateChange, ePtr<eConnection> &connection)=0;
458 virtual RESULT getState(int &SWIG_OUTPUT)=0;
459 virtual RESULT setTone(int tone)=0;
460 virtual RESULT setVoltage(int voltage)=0;
461 virtual RESULT sendDiseqc(const eDVBDiseqcCommand &diseqc)=0;
462 virtual RESULT sendToneburst(int burst)=0;
464 virtual RESULT setSEC(iDVBSatelliteEquipmentControl *sec)=0;
465 virtual RESULT setSecSequence(eSecCommandList &list)=0;
467 virtual int readFrontendData(int type)=0;
468 virtual void getFrontendStatus(SWIG_PYOBJECT(ePyObject) dest)=0;
469 virtual void getTransponderData(SWIG_PYOBJECT(ePyObject) dest, bool original)=0;
470 virtual void getFrontendData(SWIG_PYOBJECT(ePyObject) dest)=0;
472 virtual RESULT getData(int num, long &data)=0;
473 virtual RESULT setData(int num, long val)=0;
474 /* 0 means: not compatible. other values are a priority. */
475 virtual int isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)=0;
478 SWIG_TEMPLATE_TYPEDEF(ePtr<iDVBFrontend>, iDVBFrontendPtr);
481 class iDVBSatelliteEquipmentControl: public iObject
484 virtual RESULT prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, const eDVBFrontendParametersSatellite &sat, int frontend_id, unsigned int timeout)=0;
485 virtual void prepareTurnOffSatCR(iDVBFrontend &frontend)=0;
486 virtual int canTune(const eDVBFrontendParametersSatellite &feparm, iDVBFrontend *fe, int frontend_id, int *highest_score_lnb=0)=0;
487 virtual void setRotorMoving(int slotid, bool)=0;
496 SWIG_IGNORE(iDVBChannel);
497 class iDVBChannel: public iObject
500 /* direct frontend access for raw channels and/or status inquiries. */
501 virtual SWIG_VOID(RESULT) getFrontend(ePtr<iDVBFrontend> &SWIG_OUTPUT)=0;
502 virtual RESULT requestTsidOnid(SWIG_PYOBJECT(ePyObject) callback) { return -1; }
503 virtual int reserveDemux() { return -1; }
507 state_idle, /* not yet tuned */
508 state_tuning, /* currently tuning (first time) */
509 state_failed, /* tuning failed. */
510 state_unavailable, /* currently unavailable, will be back without further interaction */
512 state_last_instance, /* just one reference to this channel is left */
513 state_release /* channel is being shut down. */
515 virtual RESULT getState(int &)=0;
517 virtual RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &)=0;
520 evtPreStart, evtEOF, evtSOF, evtFailed
522 virtual RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)=0;
523 virtual RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection)=0;
525 /* demux capabilities */
531 virtual RESULT setCIRouting(const eDVBCIRouting &routing)=0;
532 virtual RESULT getDemux(ePtr<iDVBDemux> &demux, int cap=0)=0;
534 /* use count handling */
535 virtual void AddUse() = 0;
536 virtual void ReleaseUse() = 0;
539 SWIG_TEMPLATE_TYPEDEF(eUsePtr<iDVBChannel>, iDVBChannelPtr);
542 /* signed, so we can express deltas. */
544 typedef long long pts_t;
546 class iFilePushScatterGather;
547 class iTSMPEGDecoder;
549 /* note that a cue sheet describes the logical positions. thus
550 everything is specified in pts and not file positions */
552 /* implemented in dvb.cpp */
553 class eCueSheet: public iObject, public Object
555 DECLARE_REF(eCueSheet);
560 void seekTo(int relative, const pts_t &pts);
563 void addSourceSpan(const pts_t &begin, const pts_t &end);
566 void setSkipmode(const pts_t &ratio); /* 90000 is 1:1 */
567 void setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder);
569 /* frontend and backend */
573 enum { evtSeek, evtSkipmode, evtSpanChanged };
574 RESULT connectEvent(const Slot1<void, int> &event, ePtr<eConnection> &connection);
576 std::list<std::pair<pts_t,pts_t> > m_spans; /* begin, end */
577 std::list<std::pair<int, pts_t> > m_seek_requests; /* relative, delta */
578 pts_t m_skipmode_ratio;
579 Signal1<void,int> m_event;
580 ePtr<iDVBDemux> m_decoding_demux;
581 ePtr<iTSMPEGDecoder> m_decoder;
584 class iDVBPVRChannel: public iDVBChannel
589 state_eof = state_release + 1 /* end-of-file reached. */
592 /* FIXME: there are some very ugly buffer-end and ... related problems */
593 /* so this is VERY UGLY.
595 ok, it's going to get better. but still...*/
596 virtual RESULT playFile(const char *file) = 0;
597 virtual void stopFile() = 0;
600 virtual RESULT playSource(ePtr<iTsSource> &source, const char *priv=NULL) = 0;
601 virtual void stopSource() = 0;
603 virtual void setCueSheet(eCueSheet *cuesheet) = 0;
605 virtual RESULT getLength(pts_t &pts) = 0;
607 /* we explicitely ask for the decoding demux here because a channel
608 can be shared between multiple decoders.
610 virtual RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode) = 0;
611 /* skipping must be done with a cue sheet */
614 class iDVBSectionReader;
616 class iDVBTSRecorder;
617 class iTSMPEGDecoder;
619 class iDVBDemux: public iObject
622 virtual RESULT createSectionReader(eMainloop *context, ePtr<iDVBSectionReader> &reader)=0;
623 virtual RESULT createPESReader(eMainloop *context, ePtr<iDVBPESReader> &reader)=0;
624 virtual RESULT createTSRecorder(ePtr<iDVBTSRecorder> &recorder)=0;
625 virtual RESULT getMPEGDecoder(ePtr<iTSMPEGDecoder> &reader, int primary=1)=0;
626 virtual RESULT getSTC(pts_t &pts, int num=0)=0;
627 virtual RESULT getCADemuxID(uint8_t &id)=0;
628 virtual RESULT flush()=0;
629 virtual int openDVR(int flags)=0;
630 virtual int getSource()=0;
633 class iTSMPEGDecoder: public iObject
636 enum { pidDisabled = -1 };
637 /** Set Displayed Video PID and type */
638 virtual RESULT setVideoPID(int vpid, int type)=0;
640 enum { af_MPEG, af_AC3, af_DTS, af_AAC, af_DTSHD };
641 /** Set Displayed Audio PID and type */
642 virtual RESULT setAudioPID(int apid, int type)=0;
644 enum { ac_left, ac_stereo, ac_right };
645 /** Set Displayed Audio Channel */
646 virtual RESULT setAudioChannel(int channel)=0;
647 virtual int getAudioChannel()=0;
649 virtual RESULT setPCMDelay(int delay)=0;
650 virtual int getPCMDelay()=0;
651 virtual RESULT setAC3Delay(int delay)=0;
652 virtual int getAC3Delay()=0;
654 /** Set Displayed Videotext PID */
655 virtual RESULT setTextPID(int vpid)=0;
657 /** Set Sync mode to PCR */
658 virtual RESULT setSyncPCR(int pcrpid)=0;
659 enum { sm_Audio, sm_Video };
660 /** Set Sync mode to either audio or video master */
661 virtual RESULT setSyncMaster(int who)=0;
663 /** Apply settings but don't change state */
664 virtual RESULT set()=0;
665 /* all those apply settings, then transition to the given state */
668 virtual RESULT play()=0;
670 virtual RESULT pause()=0;
672 /** fast forward by skipping frames. 0 is disabled, 2 is twice-the-speed, ... */
673 virtual RESULT setFastForward(int skip=0)=0;
675 /** Slow Motion by repeating pictures */
676 virtual RESULT setSlowMotion(int repeat)=0;
678 /** Display any complete data as fast as possible */
679 virtual RESULT setTrickmode()=0;
681 virtual RESULT prepareFCC(int fe_id, int vpid, int vtype, int pcrpid)=0;
683 virtual RESULT fccDecoderStart()=0;
685 virtual RESULT fccDecoderStop()=0;
687 virtual RESULT fccUpdatePids(int fe_id, int vpid, int vtype, int pcrpid)=0;
689 virtual RESULT getPTS(int what, pts_t &pts) = 0;
691 virtual RESULT showSinglePic(const char *filename) = 0;
693 virtual RESULT setRadioPic(const std::string &filename) = 0;
697 enum { eventUnknown = 0,
698 eventSizeChanged = VIDEO_EVENT_SIZE_CHANGED,
699 eventFrameRateChanged = VIDEO_EVENT_FRAME_RATE_CHANGED,
700 eventProgressiveChanged = 16
702 unsigned char aspect;
703 unsigned short height;
704 unsigned short width;
706 unsigned short framerate;
709 virtual RESULT connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &connection) = 0;
711 virtual int getVideoWidth() = 0;
712 virtual int getVideoHeight() = 0;
713 virtual int getVideoProgressive() = 0;
714 virtual int getVideoFrameRate() = 0;
715 virtual int getVideoAspect() = 0;