4.5.0r6
[enigma2.git] / usr / include / enigma2 / lib / dvb / dvb.h
1 #ifndef __dvb_dvb_h
2 #define __dvb_dvb_h
3
4 #ifndef SWIG
5
6 #include <lib/base/ebase.h>
7 #include <lib/base/filepush.h>
8 #include <lib/base/elock.h>
9 #include <lib/dvb/idvb.h>
10 #include <lib/dvb/demux.h>
11 #include <lib/dvb/frontend.h>
12 #include <lib/dvb/tstools.h>
13 #include <lib/dvb/esection.h>
14 #include <lib/base/connection.h>
15
16 #include <dvbsi++/service_description_section.h>
17
18 class eDVBChannel;
19
20         /* we do NOT handle resource conflicts here. instead, the allocateChannel
21            fails, and the application has to see why the channel is allocated
22            (and how to deallocate it). */
23 class iDVBAdapter;
24
25 class eDVBRegisteredFrontend: public iObject, public sigc::trackable
26 {
27         DECLARE_REF(eDVBRegisteredFrontend);
28         ePtr<eTimer> disable;
29         void closeFrontend()
30         {
31                 if (!m_inuse && m_frontend->closeFrontend()) // frontend busy
32                         disable->start(60000, true);  // retry close in 60secs
33         }
34 public:
35         sigc::signal0<void> stateChanged;
36         eDVBRegisteredFrontend(eDVBFrontend *fe, iDVBAdapter *adap)
37                 :disable(eTimer::create(eApp)), m_adapter(adap), m_frontend(fe), m_inuse(0)
38         {
39                 CONNECT(disable->timeout, eDVBRegisteredFrontend::closeFrontend);
40                 fe->m_inputChanged.connect(stateChanged.make_slot());
41         }
42         void dec_use()
43         {
44                 if (!--m_inuse)
45                 {
46                         /* emit */ stateChanged();
47                         m_frontend->preClose();
48                         disable->start(3000, true);
49                 }
50         }
51         void inc_use()
52         {
53                 if (++m_inuse == 1)
54                 {
55                         m_frontend->openFrontend();
56                         /* emit */ stateChanged();
57                 }
58         }
59         iDVBAdapter *m_adapter;
60         ePtr<eDVBFrontend> m_frontend;
61         int m_inuse;
62 };
63
64 struct eDVBRegisteredDemux: public iObject
65 {
66         DECLARE_REF(eDVBRegisteredDemux);
67 public:
68         iDVBAdapter *m_adapter;
69         ePtr<eDVBDemux> m_demux;
70         int m_inuse;
71         bool m_have_descrambler;
72         eDVBRegisteredDemux(eDVBDemux *demux, iDVBAdapter *adap, bool have_descrambler)
73                 :m_adapter(adap), m_demux(demux), m_inuse(0), m_have_descrambler(have_descrambler)
74         { }
75 };
76
77 class eDVBAllocatedFrontend: public iObject
78 {
79         DECLARE_REF(eDVBAllocatedFrontend);
80 public:
81         
82         eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe);
83         ~eDVBAllocatedFrontend();
84         eDVBFrontend &get() { return *m_fe->m_frontend; }
85         operator eDVBRegisteredFrontend*() { return m_fe; }
86         operator eDVBFrontend*() { return m_fe->m_frontend; }
87
88 private:
89         eDVBRegisteredFrontend *m_fe;
90 };
91
92 class eDVBAllocatedDemux: public iObject
93 {
94         DECLARE_REF(eDVBAllocatedDemux);
95 public:
96         
97         eDVBAllocatedDemux(eDVBRegisteredDemux *demux);
98         ~eDVBAllocatedDemux();
99         eDVBDemux &get() { return *m_demux->m_demux; }
100         operator eDVBRegisteredDemux*() { return m_demux; }
101         operator eDVBDemux*() { return m_demux->m_demux; }
102         
103 private:
104         eDVBRegisteredDemux *m_demux;
105 };
106
107 class iDVBAdapter: public iObject
108 {
109 public:
110         virtual int getNumDemux() = 0;
111         virtual RESULT getDemux(ePtr<eDVBDemux> &demux, int nr) = 0;
112
113         virtual int getNumFrontends() = 0;
114         virtual RESULT getFrontend(ePtr<eDVBFrontend> &fe, int nr, bool simulate=false) = 0;
115
116         virtual int getNumDecodersAudio() = 0;
117         virtual int getNumDecodersVideo() = 0;
118         virtual int getNumDescramblers() = 0;
119 };
120
121 class eDVBAdapterLinux: public iDVBAdapter
122 {
123         DECLARE_REF(eDVBAdapterLinux);
124 public:
125         eDVBAdapterLinux(int nr);
126
127         int getNumDemux();
128         RESULT getDemux(ePtr<eDVBDemux> &demux, int nr);
129         
130         int getNumFrontends();
131         RESULT getFrontend(ePtr<eDVBFrontend> &fe, int nr, bool simulate=false);
132         
133         int getNumDecodersAudio();
134         int getNumDecodersVideo();
135         int getNumDescramblers();
136         
137         static int exist(int nr);
138 private:
139         int m_nr;
140         int m_nr_decoders_audio;
141         int m_nr_decoders_video;
142         int m_nr_descramblers;
143         eSmartPtrList<eDVBFrontend> m_frontend, m_simulate_frontend;
144         eSmartPtrList<eDVBDemux>    m_demux;
145 };
146 #endif // SWIG
147
148 SWIG_IGNORE(eDVBResourceManager);
149 class eDVBResourceManager: public iObject, public sigc::trackable
150 {
151         DECLARE_REF(eDVBResourceManager);
152         int avail, busy;
153
154         eSmartPtrList<iDVBAdapter> m_adapter;
155         eSmartPtrList<eDVBRegisteredDemux> m_demux;
156         eSmartPtrList<eDVBRegisteredFrontend>m_frontend, m_simulate_frontend;
157         void addAdapter(iDVBAdapter *adapter);
158
159         struct active_channel
160         {
161                 eDVBChannelID m_channel_id;
162                         /* we don't hold a reference here. */
163                 eDVBChannel *m_channel;
164                 
165                 active_channel(const eDVBChannelID &chid, eDVBChannel *ch) : m_channel_id(chid), m_channel(ch) { }
166         };
167         
168         std::list<active_channel> m_active_channels, m_active_simulate_channels;
169         
170         ePtr<iDVBChannelList> m_list;
171         ePtr<iDVBSatelliteEquipmentControl> m_sec;
172         static eDVBResourceManager *instance;
173         
174         friend class eDVBChannel;
175         RESULT addChannel(const eDVBChannelID &chid, eDVBChannel *ch);
176         RESULT removeChannel(eDVBChannel *ch);
177
178         sigc::signal1<void,eDVBChannel*> m_channelAdded;
179
180         eUsePtr<iDVBChannel> m_cached_channel;
181         sigc::connection m_cached_channel_state_changed_conn;
182         ePtr<eTimer> m_releaseCachedChannelTimer;
183         void DVBChannelStateChanged(iDVBChannel*);
184         void feStateChanged();
185 #ifndef SWIG
186 public:
187 #endif
188         void releaseCachedChannel();
189         eDVBResourceManager();
190         virtual ~eDVBResourceManager();
191
192         RESULT setChannelList(iDVBChannelList *list);
193         RESULT getChannelList(ePtr<iDVBChannelList> &list);
194         
195         enum {
196                         /* errNoFrontend = -1 replaced by more spcific messages */
197                 errNoDemux    = -2,
198                 errChidNotFound = -3,
199                 errNoChannelList = -4,
200                 errChannelNotInList = -5,
201                 errAllSourcesBusy = -6,
202                 errNoSourceFound = -7,
203         };
204         
205         RESULT connectChannelAdded(const sigc::slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection);
206         int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, bool simulate=false);
207
208                 /* allocate channel... */
209         RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate=false);
210                 /* allocate a pvr channel */
211         RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBPVRChannel> &channel);
212
213         static RESULT getInstance(ePtr<eDVBResourceManager> &);
214
215                         /* allocates a frontend able to tune to frontend paramters 'feperm'.
216                            the frontend must be tuned lateron. there is no guarante
217                            that tuning will succeed - it just means that if this frontend
218                            can't tune, no other frontend could do it.
219
220                            there might be a priority given to certain frontend/chid
221                            combinations. this will be evaluated here. */
222         RESULT allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm, bool simulate=false);
223
224         RESULT allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index);
225                         /* allocate a demux able to filter on the selected frontend. */
226
227         eDVBRegisteredFrontend *getFrontendBySlotIndex(int slot_index, bool simulate=false); // steals a reference!! not refcounted... just for temporary use
228
229         int canAllocateDemux(const eDVBRegisteredFrontend *fe, int cap);
230
231         RESULT allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int &cap);
232                         /* allocate a demux able to filter on the selected pvr source. */
233         RESULT allocateDemux(const std::string &pvr_source, ePtr<eDVBAllocatedDemux> &demux, int &cap);
234 #ifdef SWIG
235 public:
236 #endif
237         int canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm, bool simulate=false);
238         unsigned int canMeasureFrontendInputPower();
239         eSignal1<void, int> frontendUseMaskChanged;
240         eSignal1<void, int> frontendInputUseMaskChanged;
241         SWIG_VOID(RESULT) allocateRawChannel(eUsePtr<iDVBChannel> &SWIG_OUTPUT, int slot_index);
242         void setFrontendSlotInformations(std::list<std::tuple<int, std::string, int, int, std::string, int, int> >);
243         int getFrontendCapabilities(int frontend) const;
244 };
245 SWIG_TEMPLATE_TYPEDEF(ePtr<eDVBResourceManager>, eDVBResourceManager);
246 SWIG_EXTEND(ePtr<eDVBResourceManager>,
247         static ePtr<eDVBResourceManager> getInstance()
248         {
249                 extern ePtr<eDVBResourceManager> NewResourceManagerPtr(void);
250                 return NewResourceManagerPtr();
251         }
252 );
253
254 #ifndef SWIG
255
256 class eDVBChannelFilePush;
257
258         /* iDVBPVRChannel includes iDVBChannel. don't panic. */
259 class eDVBChannel: public iDVBPVRChannel, public iFilePushScatterGather, public sigc::trackable
260 {
261         DECLARE_REF(eDVBChannel);
262         friend class eDVBResourceManager;
263 public:
264         eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend);
265         virtual ~eDVBChannel();
266
267                 /* only for managed channels - effectively tunes to the channelid. should not be used... */
268                 /* cannot be used for PVR channels. */
269         RESULT setChannel(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &feparam);
270         eDVBChannelID getChannelID() { return m_channel_id; }
271
272         RESULT connectStateChange(const sigc::slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection);
273         RESULT connectEvent(const sigc::slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection);
274         RESULT connectSourceEvent(const sigc::slot2<void,int,std::string> &sourceEventChange, ePtr<eConnection> &connection);
275         
276         RESULT getState(int &state);
277
278         RESULT getDemux(ePtr<iDVBDemux> &demux, int cap);
279         RESULT getFrontend(ePtr<iDVBFrontend> &frontend);
280         RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &param);
281
282                 /* iDVBPVRChannel */
283         RESULT setChannel(const eDVBChannelID &id);
284         RESULT playFile(const char *file);
285         void stopFile();
286
287         RESULT playSource(ePtr<iTsSource>& source, const char *priv=NULL);
288         void stopSource();
289
290         void setCueSheet(eCueSheet *cuesheet);
291         
292         RESULT getLength(pts_t &len);
293         RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode);
294
295         int getUseCount() { return m_use_count; }
296
297         RESULT requestTsidOnid(eSlot1<void, int> &cb_func);
298         int reserveDemux();
299 private:
300         ePtr<eDVBAllocatedFrontend> m_frontend;
301         ePtr<eDVBAllocatedDemux> m_demux, m_decoder_demux;
302         
303         ePtr<iDVBFrontendParameters> m_current_frontend_parameters;
304         eDVBChannelID m_channel_id;
305         sigc::signal1<void,iDVBChannel*> m_stateChanged;
306         sigc::signal2<void,iDVBChannel*,int> m_event;
307         sigc::signal2<void,int,std::string> m_sourceEvent;
308         int m_state;
309
310                         /* for channel list */
311         ePtr<eDVBResourceManager> m_mgr;
312         
313         void frontendStateChanged(iDVBFrontend*fe);
314         ePtr<eConnection> m_conn_frontendStateChanged;
315         
316                 /* for PVR playback */
317         eDVBChannelFilePush *m_pvr_thread;
318         void pvrEvent(int event);
319         
320         int m_pvr_fd_dst;
321         eDVBTSTools m_tstools;
322         
323         ePtr<eCueSheet> m_cue;
324         
325         void cueSheetEvent(int event);
326         ePtr<eConnection> m_conn_cueSheetEvent;
327         int m_skipmode_m, m_skipmode_n, m_skipmode_frames, m_skipmode_frames_remainder;
328         
329         std::list<std::pair<uint64_t, uint64_t> > m_source_span;
330         void getNextSourceSpan(int64_t current_offset, size_t bytes_read, int64_t &start, size_t &size);
331         void flushPVR(iDVBDemux *decoding_demux=0);
332
333         eSingleLock m_cuesheet_lock;
334
335         friend class eUsePtr<eDVBChannel>;
336                 /* use count */
337         oRefCount m_use_count;
338         void AddUse();
339         void ReleaseUse();
340
341                 /* for tsid/onid read */
342         eSignal1<void, int> m_tsid_onid_cb;
343         ePtr<iDVBDemux> m_tsid_onid_demux;
344         ePtr<eTable<ServiceDescriptionSection> > m_SDT;
345         void SDTready(int err);
346
347         ePtr<eConnection> m_conn_sourceEvent;
348         void onSourceEvent(int, std::string);
349 };
350 #endif // SWIG
351
352 #endif