3451e48b69c305c6d66047e1e993ff5a100f05cf
[enigma2.git] / 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 <connection.h>
14
15 class eDVBChannel;
16
17         /* we do NOT handle resource conflicts here. instead, the allocateChannel
18            fails, and the application has to see why the channel is allocated
19            (and how to deallocate it). */
20 class iDVBAdapter;
21
22 class eDVBRegisteredFrontend: public iObject, public Object
23 {
24         DECLARE_REF(eDVBRegisteredFrontend);
25         eTimer *disable;
26         void closeFrontend()
27         {
28                 if (!m_inuse && m_frontend->closeFrontend()) // frontend busy
29                         disable->start(60000, true);  // retry close in 60secs
30         }
31 public:
32         eDVBRegisteredFrontend(eDVBFrontend *fe, iDVBAdapter *adap)
33                 :disable(new eTimer(eApp)), m_adapter(adap), m_frontend(fe), m_inuse(0)
34         {
35                 disable = new eTimer(eApp);
36                 CONNECT(disable->timeout, eDVBRegisteredFrontend::closeFrontend);
37         }
38         void dec_use()
39         {
40                 if (!--m_inuse)
41                         disable->start(3000, true);
42         }
43         void inc_use()
44         {
45                 if (++m_inuse == 1)
46                         m_frontend->openFrontend();
47         }
48         iDVBAdapter *m_adapter;
49         ePtr<eDVBFrontend> m_frontend;
50         int m_inuse;
51 };
52
53 struct eDVBRegisteredDemux
54 {
55 DECLARE_REF(eDVBRegisteredDemux);
56 public:
57         iDVBAdapter *m_adapter;
58         ePtr<eDVBDemux> m_demux;
59         int m_inuse;
60         eDVBRegisteredDemux(eDVBDemux *demux, iDVBAdapter *adap): m_adapter(adap), m_demux(demux), m_inuse(0) { }
61 };
62
63 class eDVBAllocatedFrontend
64 {
65 DECLARE_REF(eDVBAllocatedFrontend);
66 public:
67         
68         eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe);
69         ~eDVBAllocatedFrontend();
70         eDVBFrontend &get() { return *m_fe->m_frontend; }
71         operator eDVBRegisteredFrontend*() { return m_fe; }
72         operator eDVBFrontend*() { return m_fe->m_frontend; }
73
74 private:
75         eDVBRegisteredFrontend *m_fe;
76 };
77
78 class eDVBAllocatedDemux
79 {
80 DECLARE_REF(eDVBAllocatedDemux);
81 public:
82         
83         eDVBAllocatedDemux(eDVBRegisteredDemux *demux);
84         ~eDVBAllocatedDemux();
85         eDVBDemux &get() { return *m_demux->m_demux; }
86         operator eDVBRegisteredDemux*() { return m_demux; }
87         operator eDVBDemux*() { return m_demux->m_demux; }
88         
89 private:
90         eDVBRegisteredDemux *m_demux;
91 };
92
93 class iDVBAdapter: public iObject
94 {
95 public:
96         virtual int getNumDemux() = 0;
97         virtual RESULT getDemux(ePtr<eDVBDemux> &demux, int nr) = 0;
98         
99         virtual int getNumFrontends() = 0;
100         virtual RESULT getFrontend(ePtr<eDVBFrontend> &fe, int nr) = 0;
101 };
102
103 class eDVBAdapterLinux: public iDVBAdapter
104 {
105 DECLARE_REF(eDVBAdapterLinux);
106 public:
107         eDVBAdapterLinux(int nr);
108
109         int getNumDemux();
110         RESULT getDemux(ePtr<eDVBDemux> &demux, int nr);
111         
112         int getNumFrontends();
113         RESULT getFrontend(ePtr<eDVBFrontend> &fe, int nr);
114         
115         static int exist(int nr);
116 private:
117         int m_nr;
118         eSmartPtrList<eDVBFrontend> m_frontend;
119         eSmartPtrList<eDVBDemux>    m_demux;
120 };
121
122 #endif // SWIG
123
124 class eDVBResourceManager: public iObject, public Object
125 {
126         DECLARE_REF(eDVBResourceManager);
127         int avail, busy;
128
129         eSmartPtrList<iDVBAdapter> m_adapter;
130         
131         eSmartPtrList<eDVBRegisteredDemux> m_demux;
132         eSmartPtrList<eDVBRegisteredFrontend> m_frontend;
133         
134         void addAdapter(iDVBAdapter *adapter);
135         
136                         /* allocates a frontend able to tune to frontend paramters 'feperm'.
137                            the frontend must be tuned lateron. there is no guarante
138                            that tuning will succeed - it just means that if this frontend
139                            can't tune, no other frontend could do it.
140                            
141                            there might be a priority given to certain frontend/chid 
142                            combinations. this will be evaluated here. */
143                            
144         RESULT allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm);
145         RESULT allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int index);
146         
147                         /* allocate a demux able to filter on the selected frontend. */
148         RESULT allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap);
149         
150         struct active_channel
151         {
152                 eDVBChannelID m_channel_id;
153                         /* we don't hold a reference here. */
154                 eDVBChannel *m_channel;
155                 
156                 active_channel(const eDVBChannelID &chid, eDVBChannel *ch) : m_channel_id(chid), m_channel(ch) { }
157         };
158         
159         std::list<active_channel> m_active_channels;
160         
161         ePtr<iDVBChannelList> m_list;
162         ePtr<iDVBSatelliteEquipmentControl> m_sec;
163         static eDVBResourceManager *instance;
164         
165         friend class eDVBChannel;
166         RESULT addChannel(const eDVBChannelID &chid, eDVBChannel *ch);
167         RESULT removeChannel(eDVBChannel *ch);
168
169         Signal1<void,eDVBChannel*> m_channelAdded;
170
171         bool canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm);
172
173         eUsePtr<iDVBChannel> m_cached_channel;
174         Connection m_cached_channel_state_changed_conn;
175         eTimer m_releaseCachedChannelTimer;
176         void DVBChannelStateChanged(iDVBChannel*);
177         void releaseCachedChannel();
178 #ifndef SWIG
179 public:
180 #endif
181         eDVBResourceManager();
182         virtual ~eDVBResourceManager();
183
184         RESULT setChannelList(iDVBChannelList *list);
185         RESULT getChannelList(ePtr<iDVBChannelList> &list);
186         
187         enum {
188                 errNoFrontend = -1,
189                 errNoDemux    = -2,
190                 errChidNotFound = -3
191         };
192
193         RESULT connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection);
194         bool canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore);
195
196                 /* allocate channel... */
197         RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel);
198         RESULT allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel);
199 #ifdef SWIG
200 public:
201 #endif
202         RESULT allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index);
203         static RESULT getInstance(ePtr<eDVBResourceManager> &ptr) { if (instance) { ptr = instance; return 0; } return -1; }
204 };
205
206 #ifndef SWIG
207
208         /* iDVBPVRChannel includes iDVBChannel. don't panic. */
209 class eDVBChannel: public iDVBPVRChannel, public iFilePushScatterGather, public Object
210 {
211         DECLARE_REF(eDVBChannel);
212         friend class eDVBResourceManager;
213 public:
214         eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend);
215         virtual ~eDVBChannel();
216
217                 /* only for managed channels - effectively tunes to the channelid. should not be used... */
218                 /* cannot be used for PVR channels. */
219         RESULT setChannel(const eDVBChannelID &id, ePtr<iDVBFrontendParameters> &feparam);
220         eDVBChannelID getChannelID() { return m_channel_id; }
221
222         RESULT connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection);
223         RESULT connectEvent(const Slot2<void,iDVBChannel*,int> &eventChange, ePtr<eConnection> &connection);
224         
225         RESULT getState(int &state);
226
227         RESULT setCIRouting(const eDVBCIRouting &routing);
228         RESULT getDemux(ePtr<iDVBDemux> &demux, int cap);
229         RESULT getFrontend(ePtr<iDVBFrontend> &frontend);
230         RESULT getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &param);
231
232                 /* iDVBPVRChannel */
233         RESULT playFile(const char *file);
234         void stopFile();
235         
236         void setCueSheet(eCueSheet *cuesheet);
237         
238         RESULT getLength(pts_t &len);
239         RESULT getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode);
240
241         int getUseCount() { return m_use_count; }
242 private:
243         ePtr<eDVBAllocatedFrontend> m_frontend;
244         ePtr<eDVBAllocatedDemux> m_demux, m_decoder_demux;
245         
246         ePtr<iDVBFrontendParameters> m_current_frontend_parameters;
247         eDVBChannelID m_channel_id;
248         Signal1<void,iDVBChannel*> m_stateChanged;
249         Signal2<void,iDVBChannel*,int> m_event;
250         int m_state;
251
252                         /* for channel list */
253         ePtr<eDVBResourceManager> m_mgr;
254         
255         void frontendStateChanged(iDVBFrontend*fe);
256         ePtr<eConnection> m_conn_frontendStateChanged;
257         
258                 /* for PVR playback */
259         eFilePushThread *m_pvr_thread;
260         void pvrEvent(int event);
261         
262         int m_pvr_fd_dst;
263         eDVBTSTools m_tstools;
264         
265         ePtr<eCueSheet> m_cue;
266         
267         void cueSheetEvent(int event);
268         ePtr<eConnection> m_conn_cueSheetEvent;
269         int m_skipmode_m, m_skipmode_n;
270         
271         std::list<std::pair<off_t, off_t> > m_source_span;
272         void getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size);
273         void flushPVR(iDVBDemux *decoding_demux=0);
274         
275         eSingleLock m_cuesheet_lock;
276
277         friend class eUsePtr<eDVBChannel>;
278                 /* use count */
279         oRefCount m_use_count;
280         void AddUse();
281         void ReleaseUse();
282 };
283
284 #endif // SWIG
285 #endif