Move filepush from lib/base to lib/dvb
[openblackhole/openblackhole-enigma2.git] / lib / dvb / dvb.cpp
1 #include <linux/dvb/frontend.h>
2 #include <linux/dvb/dmx.h>
3 #include <linux/dvb/version.h>
4
5 #include <lib/base/eerror.h>
6 #include <lib/base/wrappers.h>
7 #include <lib/dvb/cahandler.h>
8 #include <lib/dvb/idvb.h>
9 #include <lib/dvb/dvb.h>
10 #include <lib/dvb/sec.h>
11 #include <lib/dvb/specs.h>
12 #include "filepush.h"
13
14 #include <errno.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <sys/ioctl.h>
20
21 #define MIN(a,b) (a < b ? a : b)
22 #define MAX(a,b) (a > b ? a : b)
23
24 DEFINE_REF(eDVBRegisteredFrontend);
25 DEFINE_REF(eDVBRegisteredDemux);
26
27 DEFINE_REF(eDVBAllocatedFrontend);
28
29 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
30 {
31         m_fe->inc_use();
32 }
33
34 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
35 {
36         m_fe->dec_use();
37 }
38
39 DEFINE_REF(eDVBAllocatedDemux);
40
41 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
42 {
43         m_demux->m_inuse++;
44 }
45
46 eDVBAllocatedDemux::~eDVBAllocatedDemux()
47 {
48         --m_demux->m_inuse;
49 }
50
51 DEFINE_REF(eDVBResourceManager);
52
53 eDVBResourceManager *eDVBResourceManager::instance;
54
55 RESULT eDVBResourceManager::getInstance(ePtr<eDVBResourceManager> &ptr)
56 {
57         if (instance)
58         {
59                 ptr = instance;
60                 return 0;
61         }
62         return -1;
63 }
64
65 ePtr<eDVBResourceManager> NewResourceManagerPtr(void)
66 {
67         ePtr<eDVBResourceManager> ptr;
68         eDVBResourceManager::getInstance(ptr);
69         return ptr;
70 }
71
72 eDVBResourceManager::eDVBResourceManager()
73         :m_releaseCachedChannelTimer(eTimer::create(eApp))
74 {
75         avail = 1;
76         busy = 0;
77         m_sec = new eDVBSatelliteEquipmentControl(m_frontend, m_simulate_frontend);
78
79         if (!instance)
80                 instance = this;
81
82         int num_adapter = 1;
83         while (eDVBAdapterLinux::exist(num_adapter))
84         {
85                 if (eDVBAdapterLinux::isusb(num_adapter))
86                 {
87                         eDVBAdapterLinux *adapter = new eDVBUsbAdapter(num_adapter);
88                         addAdapter(adapter);
89                 }
90                 num_adapter++;
91         }
92
93         if (eDVBAdapterLinux::exist(0))
94         {
95                 eDVBAdapterLinux *adapter = new eDVBAdapterLinux(0);
96                 adapter->scanDevices();
97                 addAdapter(adapter, true);
98         }
99
100         eDebug("[eDVBResourceManager] found %zd adapter, %zd frontends(%zd sim) and %zd demux",
101                 m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size());
102
103         CONNECT(m_releaseCachedChannelTimer->timeout, eDVBResourceManager::releaseCachedChannel);
104 }
105
106 void eDVBResourceManager::feStateChanged()
107 {
108         int mask=0;
109         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
110                 if (i->m_inuse)
111                         mask |= ( 1 << i->m_frontend->getSlotID() );
112         /* emit */ frontendUseMaskChanged(mask);
113 }
114
115 std::map<std::string, std::string> eDVBAdapterLinux::mappedFrontendName;
116
117 DEFINE_REF(eDVBAdapterLinux);
118 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
119 {
120 }
121
122 void eDVBAdapterLinux::scanDevices()
123 {
124                 // scan frontends
125         int num_fe = 0;
126
127         eDebug("[eDVBResourceManager] scanning for frontends..");
128         while (1)
129         {
130                 /*
131                  * Some frontend devices might have been just created, if
132                  * they are virtual (vtuner) frontends.
133                  * In that case, we cannot be sure the devicenodes are available yet.
134                  * So it is safer to scan for sys entries, than for device nodes
135                  */
136                 char filename[128];
137                 snprintf(filename, sizeof(filename), "/sys/class/dvb/dvb%d.frontend%d", m_nr, num_fe);
138                 if (::access(filename, X_OK) < 0) break;
139                 snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
140                 eDVBFrontend *fe;
141                 std::string name = filename;
142                 std::map<std::string, std::string>::iterator it = mappedFrontendName.find(name);
143                 if (it != mappedFrontendName.end()) name = it->second;
144
145                 {
146                         int ok = 0;
147                         fe = new eDVBFrontend(name.c_str(), num_fe, ok, true);
148                         if (ok)
149                                 m_simulate_frontend.push_back(ePtr<eDVBFrontend>(fe));
150                 }
151
152                 {
153                         int ok = 0;
154                         fe = new eDVBFrontend(name.c_str(), num_fe, ok, false, fe);
155                         if (ok)
156                                 m_frontend.push_back(ePtr<eDVBFrontend>(fe));
157                 }
158                 ++num_fe;
159         }
160
161                 // scan demux
162         int num_demux = 0;
163         while (1)
164         {
165                 char filename[128];
166                 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
167                 if (::access(filename, R_OK) < 0) break;
168                 ePtr<eDVBDemux> demux;
169
170                 demux = new eDVBDemux(m_nr, num_demux);
171                 m_demux.push_back(demux);
172
173                 ++num_demux;
174         }
175 }
176
177 int eDVBAdapterLinux::getNumDemux()
178 {
179         return m_demux.size();
180 }
181
182 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
183 {
184         eDebug("[eDVBAdapterLinux] get demux %d", nr);
185
186         eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
187         while (nr && (i != m_demux.end()))
188         {
189                 --nr;
190                 ++i;
191         }
192
193         if (i != m_demux.end())
194                 demux = *i;
195         else
196                 return -1;
197
198         return 0;
199 }
200
201 int eDVBAdapterLinux::getNumFrontends()
202 {
203         return m_frontend.size();
204 }
205
206 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr, bool simulate)
207 {
208         eSmartPtrList<eDVBFrontend>::iterator i(simulate ? m_simulate_frontend.begin() : m_frontend.begin());
209         while (nr && (i != m_frontend.end()))
210         {
211                 --nr;
212                 ++i;
213         }
214
215         if (i != m_frontend.end())
216                 fe = *i;
217         else
218                 return -1;
219
220         return 0;
221 }
222
223 int eDVBAdapterLinux::exist(int nr)
224 {
225         char filename[128];
226         sprintf(filename, "/dev/dvb/adapter%d", nr);
227         return (::access(filename, X_OK) >= 0) ? 1 : 0;
228 }
229
230 bool eDVBAdapterLinux::isusb(int nr)
231 {
232         char devicename[256];
233         snprintf(devicename, sizeof(devicename), "/sys/class/dvb/dvb%d.frontend0/device/ep_00", nr);
234         return ::access(devicename, X_OK) >= 0;
235 }
236
237 DEFINE_REF(eDVBUsbAdapter);
238 eDVBUsbAdapter::eDVBUsbAdapter(int nr)
239 : eDVBAdapterLinux(nr)
240 {
241         int file;
242         char type[8];
243         struct dvb_frontend_info fe_info;
244         int frontend = -1;
245         char filename[256];
246         char name[128] = {0};
247         int vtunerid = nr - 1;
248
249         pumpThread = 0;
250
251         int num_fe = 0;
252         while (1)
253         {
254                 /*
255                  * Some frontend devices might have been just created, if
256                  * they are virtual (vtuner) frontends.
257                  * In that case, we cannot be sure the devicenodes are available yet.
258                  * So it is safer to scan for sys entries, than for device nodes
259                  */
260                 snprintf(filename, sizeof(filename), "/sys/class/dvb/dvb0.frontend%d", num_fe);
261                 if (::access(filename, X_OK) < 0) break;
262                 num_fe++;
263         }
264         snprintf(filename, sizeof(filename), "/dev/dvb/adapter0/frontend%d", num_fe);
265         virtualFrontendName = filename;
266
267         demuxFd = vtunerFd = pipeFd[0] = pipeFd[1] = -1;
268
269         /* find the device name */
270         snprintf(filename, sizeof(filename), "/sys/class/dvb/dvb%d.frontend0/device/product", nr);
271         file = ::open(filename, O_RDONLY);
272         if (file < 0)
273         {
274                 snprintf(filename, sizeof(filename), "/sys/class/dvb/dvb%d.frontend0/device/manufacturer", nr);
275                 file = ::open(filename, O_RDONLY);
276         }
277
278         if (file >= 0)
279         {
280                 int len = singleRead(file, name, sizeof(name) - 1);
281                 if (len >= 0)
282                 {
283                         name[len] = 0;
284                 }
285                 ::close(file);
286                 file = -1;
287         }
288
289         snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/frontend0", nr);
290         frontend = open(filename, O_RDWR);
291         if (frontend < 0)
292         {
293                 goto error;
294         }
295         if (::ioctl(frontend, FE_GET_INFO, &fe_info) < 0)
296         {
297                 ::close(frontend);
298                 frontend = -1;
299                 goto error;
300         }
301         ::close(frontend);
302         frontend = -1;
303
304         usbFrontendName = filename;
305
306         if (!name[0])
307         {
308                 /* fallback to the dvb_frontend_info name */
309                 int len = MIN(sizeof(fe_info.name), sizeof(name) - 1);
310                 strncpy(name, fe_info.name, len);
311                 name[len] = 0;
312         }
313         if (name[0])
314         {
315                 /* strip trailing LF / CR / whitespace */
316                 int len = strlen(name);
317                 char *tmp = name;
318                 while (len && (strchr(" \n\r\t", tmp[len - 1]) != NULL))
319                 {
320                         tmp[--len] = 0;
321                 }
322         }
323         if (!name[0])
324         {
325                 /* we did not find a usable name, fallback to a default */
326                 snprintf(name, sizeof(name), "usb frontend");
327         }
328
329         snprintf(filename, sizeof(filename), "/dev/dvb/adapter%d/demux0", nr);
330         demuxFd = open(filename, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
331         if (demuxFd < 0)
332         {
333                 goto error;
334         }
335
336         while (vtunerFd < 0)
337         {
338                 snprintf(filename, sizeof(filename), "/dev/misc/vtuner%d", vtunerid);
339                 if (::access(filename, F_OK) < 0) break;
340                 vtunerFd = open(filename, O_RDWR | O_CLOEXEC);
341                 if (vtunerFd < 0)
342                 {
343                         vtunerid++;
344                 }
345         }
346
347         if (vtunerFd < 0)
348         {
349                 goto error;
350         }
351
352         eDebug("[eDVBUsbAdapter] linking adapter%d/frontend0 to vtuner%d", nr, vtunerid);
353
354         switch (fe_info.type)
355         {
356         case FE_QPSK:
357                 strcpy(type,"DVB-S2");
358                 break;
359         case FE_QAM:
360                 strcpy(type,"DVB-C");
361                 break;
362         case FE_OFDM:
363                 strcpy(type,"DVB-T");
364                 break;
365         case FE_ATSC:
366                 strcpy(type,"ATSC");
367                 break;
368         default:
369                 eDebug("[eDVBUsbAdapter] Frontend type 0x%x not supported", fe_info.type);
370                 goto error;
371         }
372
373 #define VTUNER_GET_MESSAGE  1
374 #define VTUNER_SET_RESPONSE 2
375 #define VTUNER_SET_NAME     3
376 #define VTUNER_SET_TYPE     4
377 #define VTUNER_SET_HAS_OUTPUTS 5
378 #define VTUNER_SET_FE_INFO  6
379 #define VTUNER_SET_NUM_MODES 7
380 #define VTUNER_SET_MODES 8
381 #define VTUNER_SET_DELSYS 32
382 #define VTUNER_SET_ADAPTER 33
383         ioctl(vtunerFd, VTUNER_SET_NAME, name);
384         ioctl(vtunerFd, VTUNER_SET_TYPE, type);
385         ioctl(vtunerFd, VTUNER_SET_HAS_OUTPUTS, "no");
386         ioctl(vtunerFd, VTUNER_SET_ADAPTER, nr);
387
388         memset(pidList, 0xff, sizeof(pidList));
389
390         mappedFrontendName[virtualFrontendName] = usbFrontendName;
391         pipe(pipeFd);
392         running = true;
393         pthread_create(&pumpThread, NULL, threadproc, (void*)this);
394         return;
395
396 error:
397         if (vtunerFd >= 0)
398         {
399                 close(vtunerFd);
400                 vtunerFd = -1;
401         }
402         if (demuxFd >= 0)
403         {
404                 close(demuxFd);
405                 demuxFd = -1;
406         }
407 }
408
409 eDVBUsbAdapter::~eDVBUsbAdapter()
410 {
411         running = false;
412         if (pipeFd[1] >= 0)
413         {
414                 ::close(pipeFd[1]);
415                 pipeFd[1] = -1;
416         }
417         if (pumpThread) pthread_join(pumpThread, NULL);
418         if (pipeFd[0] >= 0)
419         {
420                 ::close(pipeFd[0]);
421                 pipeFd[0] = -1;
422         }
423         if (vtunerFd >= 0)
424         {
425                 close(vtunerFd);
426                 vtunerFd = -1;
427         }
428         if (demuxFd >= 0)
429         {
430                 close(demuxFd);
431                 demuxFd = -1;
432         }
433 }
434
435 void *eDVBUsbAdapter::threadproc(void *arg)
436 {
437         eDVBUsbAdapter *user = (eDVBUsbAdapter*)arg;
438         return user->vtunerPump();
439 }
440
441 static bool exist_in_pidlist(unsigned short int* pidlist, unsigned short int value)
442 {
443         for (int i=0; i<30; ++i)
444                 if (pidlist[i] == value)
445                         return true;
446         return false;
447 }
448
449 void *eDVBUsbAdapter::vtunerPump()
450 {
451         int pidcount = 0;
452         if (vtunerFd < 0 || demuxFd < 0 || pipeFd[0] < 0) return NULL;
453
454 #define MSG_PIDLIST         14
455         struct vtuner_message
456         {
457                 int type;
458                 unsigned short int pidlist[30];
459                 unsigned char pad[64]; /* nobody knows the much data the driver will try to copy into our struct, add some padding to be sure */
460         };
461
462 #define DEMUX_BUFFER_SIZE (8 * ((188 / 4) * 4096)) /* 1.5MB */
463         ioctl(demuxFd, DMX_SET_BUFFER_SIZE, DEMUX_BUFFER_SIZE);
464
465         while (running)
466         {
467                 fd_set rset, xset;
468                 int maxfd = vtunerFd;
469                 if (demuxFd > maxfd) maxfd = demuxFd;
470                 if (pipeFd[0] > maxfd) maxfd = pipeFd[0];
471                 FD_ZERO(&rset);
472                 FD_ZERO(&xset);
473                 FD_SET(vtunerFd, &xset);
474                 FD_SET(demuxFd, &rset);
475                 FD_SET(pipeFd[0], &rset);
476                 if (Select(maxfd + 1, &rset, NULL, &xset, NULL) > 0)
477                 {
478                         if (FD_ISSET(vtunerFd, &xset))
479                         {
480                                 struct vtuner_message message;
481                                 memset(message.pidlist, 0xff, sizeof(message.pidlist));
482                                 ::ioctl(vtunerFd, VTUNER_GET_MESSAGE, &message);
483
484                                 switch (message.type)
485                                 {
486                                 case MSG_PIDLIST:
487                                         /* remove old pids */
488                                         for (int i = 0; i < 30; i++)
489                                         {
490                                                 if (pidList[i] == 0xffff)
491                                                         continue;
492                                                 if (exist_in_pidlist(message.pidlist, pidList[i]))
493                                                         continue;
494
495                                                 if (pidcount > 1)
496                                                 {
497                                                         ::ioctl(demuxFd, DMX_REMOVE_PID, &pidList[i]);
498                                                         pidcount--;
499                                                 }
500                                                 else if (pidcount == 1)
501                                                 {
502                                                         ::ioctl(demuxFd, DMX_STOP);
503                                                         pidcount = 0;
504                                                 }
505                                         }
506
507                                         /* add new pids */
508                                         for (int i = 0; i < 30; i++)
509                                         {
510                                                 if (message.pidlist[i] == 0xffff)
511                                                         continue;
512                                                 if (exist_in_pidlist(pidList, message.pidlist[i]))
513                                                         continue;
514
515                                                 if (pidcount)
516                                                 {
517                                                         ::ioctl(demuxFd, DMX_ADD_PID, &message.pidlist[i]);
518                                                         pidcount++;
519                                                 }
520                                                 else
521                                                 {
522                                                         struct dmx_pes_filter_params filter;
523                                                         filter.input = DMX_IN_FRONTEND;
524                                                         filter.flags = 0;
525                                                         filter.pid = message.pidlist[i];
526                                                         filter.output = DMX_OUT_TSDEMUX_TAP;
527                                                         filter.pes_type = DMX_PES_OTHER;
528                                                         if (ioctl(demuxFd, DMX_SET_PES_FILTER, &filter) >= 0
529                                                                         && ioctl(demuxFd, DMX_START) >= 0)
530                                                         {
531                                                                 pidcount = 1;
532                                                         }
533                                                 }
534                                         }
535
536                                         /* copy pids */
537                                         memcpy(pidList, message.pidlist, sizeof(message.pidlist));
538
539                                         break;
540                                 }
541                         }
542                         if (FD_ISSET(demuxFd, &rset))
543                         {
544                                 ssize_t size = singleRead(demuxFd, buffer, sizeof(buffer));
545                                 if (size > 0 && writeAll(vtunerFd, buffer, size) <= 0)
546                                 {
547                                         break;
548                                 }
549                         }
550                 }
551         }
552         return NULL;
553 }
554
555 eDVBResourceManager::~eDVBResourceManager()
556 {
557         if (instance == this)
558                 instance = 0;
559 }
560
561 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter, bool front)
562 {
563         int num_fe = adapter->getNumFrontends();
564         int num_demux = adapter->getNumDemux();
565
566         if (front)
567         {
568                 m_adapter.push_front(adapter);
569         }
570         else
571         {
572                 m_adapter.push_back(adapter);
573         }
574
575         int i;
576         for (i=0; i<num_demux; ++i)
577         {
578                 ePtr<eDVBDemux> demux;
579                 if (!adapter->getDemux(demux, i))
580                         m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
581         }
582
583         ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
584         for (i=0; i<num_fe; ++i)
585         {
586                 ePtr<eDVBFrontend> frontend;
587                 if (!adapter->getFrontend(frontend, i))
588                 {
589                         eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
590                         CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
591                         m_frontend.push_back(new_fe);
592                         frontend->setSEC(m_sec);
593                         // we must link all dvb-t frontends ( for active antenna voltage )
594                         if (frontend->supportsDeliverySystem(SYS_DVBT, false) || frontend->supportsDeliverySystem(SYS_DVBT2, false))
595                         {
596                                 if (prev_dvbt_frontend)
597                                 {
598                                         prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe);
599                                         frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend));
600                                 }
601                                 prev_dvbt_frontend = new_fe;
602                         }
603                 }
604         }
605
606         prev_dvbt_frontend = 0;
607         for (i=0; i<num_fe; ++i)
608         {
609                 ePtr<eDVBFrontend> frontend;
610                 if (!adapter->getFrontend(frontend, i, true))
611                 {
612                         eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
613 //                      CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
614                         m_simulate_frontend.push_back(new_fe);
615                         frontend->setSEC(m_sec);
616                         // we must link all dvb-t frontends ( for active antenna voltage )
617                         if (frontend->supportsDeliverySystem(SYS_DVBT, false) || frontend->supportsDeliverySystem(SYS_DVBT2, false))
618                         {
619                                 if (prev_dvbt_frontend)
620                                 {
621                                         prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe);
622                                         frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend));
623                                 }
624                                 prev_dvbt_frontend = new_fe;
625                         }
626                 }
627         }
628
629 }
630
631 PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
632 {
633         if (!PyList_Check(list))
634         {
635                 PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
636                 return NULL;
637         }
638         unsigned int assigned=0;
639         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
640         {
641                 int pos=0;
642                 while (pos < PyList_Size(list)) {
643                         ePyObject obj = PyList_GET_ITEM(list, pos++);
644                         ePyObject Id, Descr, Enabled, IsDVBS2, frontendId;
645                         if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5)
646                                 continue;
647                         Id = PyTuple_GET_ITEM(obj, 0);
648                         Descr = PyTuple_GET_ITEM(obj, 1);
649                         Enabled = PyTuple_GET_ITEM(obj, 2);
650                         IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
651                         frontendId = PyTuple_GET_ITEM(obj, 4);
652                         if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId))
653                                 continue;
654                         if (!i->m_frontend->setSlotInfo(PyInt_AsLong(Id), PyString_AS_STRING(Descr), Enabled == Py_True, IsDVBS2 == Py_True, PyInt_AsLong(frontendId)))
655                                 continue;
656                         ++assigned;
657                         break;
658                 }
659         }
660         if (assigned != m_frontend.size()) {
661                 eDebug("[eDVBResourceManager::setFrontendSlotInformations] .. assigned %zd socket informations, but %d registered frontends!",
662                         m_frontend.size(), assigned);
663         }
664         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_simulate_frontend.begin()); i != m_simulate_frontend.end(); ++i)
665         {
666                 int pos=0;
667                 while (pos < PyList_Size(list)) {
668                         ePyObject obj = PyList_GET_ITEM(list, pos++);
669                         ePyObject Id, Descr, Enabled, IsDVBS2, frontendId;
670                         if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 5)
671                                 continue;
672                         Id = PyTuple_GET_ITEM(obj, 0);
673                         Descr = PyTuple_GET_ITEM(obj, 1);
674                         Enabled = PyTuple_GET_ITEM(obj, 2);
675                         IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
676                         frontendId = PyTuple_GET_ITEM(obj, 4);
677                         if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyInt_Check(frontendId))
678                                 continue;
679                         if (!i->m_frontend->setSlotInfo(PyInt_AsLong(Id), PyString_AS_STRING(Descr), Enabled == Py_True, IsDVBS2 == Py_True, PyInt_AsLong(frontendId)))
680                                 continue;
681                         break;
682                 }
683         }
684         Py_RETURN_NONE;
685 }
686
687 bool eDVBResourceManager::frontendIsCompatible(int index, const char *type)
688 {
689         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
690         {
691                 if (i->m_frontend->getSlotID() == index)
692                 {
693                         if (!strcmp(type, "DVB-S2"))
694                         {
695                                 return i->m_frontend->supportsDeliverySystem(SYS_DVBS2, false);
696                         }
697                         else if (!strcmp(type, "DVB-S"))
698                         {
699                                 return i->m_frontend->supportsDeliverySystem(SYS_DVBS, false);
700                         }
701                         else if (!strcmp(type, "DVB-T2"))
702                         {
703                                 return i->m_frontend->supportsDeliverySystem(SYS_DVBT2, false);
704                         }
705                         else if (!strcmp(type, "DVB-T"))
706                         {
707                                 return i->m_frontend->supportsDeliverySystem(SYS_DVBT, false);
708                         }
709                         else if (!strcmp(type, "DVB-C"))
710                         {
711 #if defined SYS_DVBC_ANNEX_A
712                                 return i->m_frontend->supportsDeliverySystem(SYS_DVBC_ANNEX_A, false) || i->m_frontend->supportsDeliverySystem(SYS_DVBC_ANNEX_C, false);
713 #else
714                                 return i->m_frontend->supportsDeliverySystem(SYS_DVBC_ANNEX_AC, false);
715 #endif
716                         }
717                         else if (!strcmp(type, "ATSC"))
718                         {
719                                 return i->m_frontend->supportsDeliverySystem(SYS_ATSC, false) || i->m_frontend->supportsDeliverySystem(SYS_DVBC_ANNEX_B, false);
720                         }
721                         break;
722                 }
723         }
724         return false;
725 }
726
727 void eDVBResourceManager::setFrontendType(int index, const char *type)
728 {
729         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
730         {
731                 if (i->m_frontend->getSlotID() == index)
732                 {
733                         std::vector<fe_delivery_system_t> whitelist;
734                         if (!strcmp(type, "DVB-S2") || !strcmp(type, "DVB-S"))
735                         {
736                                 whitelist.push_back(SYS_DVBS);
737                                 whitelist.push_back(SYS_DVBS2);
738                         }
739                         else if (!strcmp(type, "DVB-T2") || !strcmp(type, "DVB-T"))
740                         {
741                                 whitelist.push_back(SYS_DVBT);
742                                 whitelist.push_back(SYS_DVBT2);
743                         }
744                         else if (!strcmp(type, "DVB-C"))
745                         {
746 #if defined SYS_DVBC_ANNEX_A
747                                 whitelist.push_back(SYS_DVBC_ANNEX_A);
748                                 whitelist.push_back(SYS_DVBC_ANNEX_C);
749 #else
750                                 whitelist.push_back(SYS_DVBC_ANNEX_AC);
751 #endif
752                         }
753                         else if (!strcmp(type, "ATSC"))
754                         {
755                                 whitelist.push_back(SYS_ATSC);
756                                 whitelist.push_back(SYS_DVBC_ANNEX_B);
757                         }
758                         i->m_frontend->setDeliverySystemWhitelist(whitelist);
759                         break;
760                 }
761         }
762 }
763
764 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm, bool simulate)
765 {
766         eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
767         ePtr<eDVBRegisteredFrontend> best;
768         int bestval = 0;
769         int foundone = 0;
770
771         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
772         {
773                 int c = i->m_frontend->isCompatibleWith(feparm);
774
775                 if (c)  /* if we have at least one frontend which is compatible with the source, flag this. */
776                         foundone = 1;
777
778                 if (!i->m_inuse)
779                 {
780 //                      eDebug("[eDVBResourceManager] Slot %d, score %d", i->m_frontend->getSlotID(), c);
781                         if (c > bestval)
782                         {
783                                 bestval = c;
784                                 best = i;
785                         }
786                 }
787 //              else
788 //                      eDebug("[eDVBResourceManager] Slot %d, score %d... but BUSY!!!!!!!!!!!", i->m_frontend->getSlotID(), c);
789         }
790
791         if (best)
792         {
793                 fe = new eDVBAllocatedFrontend(best);
794                 return 0;
795         }
796
797         fe = 0;
798
799         if (foundone)
800                 return errAllSourcesBusy;
801         else
802                 return errNoSourceFound;
803 }
804
805 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index)
806 {
807         int err = errNoSourceFound;
808         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
809                 if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index)
810                 {
811                         // check if another slot linked to this is in use
812                         long tmp;
813                         i->m_frontend->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, tmp);
814                         if ( tmp != -1 )
815                         {
816                                 eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend *)tmp;
817                                 if (satpos_depends_to_fe->m_inuse)
818                                 {
819                                         eDebug("[eDVBResourceManager] another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!");
820                                         err = errAllSourcesBusy;
821                                         goto alloc_fe_by_id_not_possible;
822                                 }
823                         }
824                         else // check linked tuners
825                         {
826                                 i->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, tmp);
827                                 while ( tmp != -1 )
828                                 {
829                                         eDVBRegisteredFrontend *next = (eDVBRegisteredFrontend *) tmp;
830                                         if (next->m_inuse)
831                                         {
832                                                 eDebug("[eDVBResourceManager] another linked frontend is in use.. so allocateFrontendByIndex not possible!");
833                                                 err = errAllSourcesBusy;
834                                                 goto alloc_fe_by_id_not_possible;
835                                         }
836                                         next->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, tmp);
837                                 }
838                                 i->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp);
839                                 while ( tmp != -1 )
840                                 {
841                                         eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *) tmp;
842                                         if (prev->m_inuse)
843                                         {
844                                                 eDebug("[eDVBResourceManager] another linked frontend is in use.. so allocateFrontendByIndex not possible!");
845                                                 err = errAllSourcesBusy;
846                                                 goto alloc_fe_by_id_not_possible;
847                                         }
848                                         prev->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp);
849                                 }
850                         }
851                         fe = new eDVBAllocatedFrontend(i);
852                         return 0;
853                 }
854 alloc_fe_by_id_not_possible:
855         fe = 0;
856         return err;
857 }
858
859 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int &cap)
860 {
861         eDebug("[eDVBResourceManager] allocate demux cap=%02X", cap);
862         eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
863
864         if (i == m_demux.end())
865                 return -1;
866
867         iDVBAdapter *adapter = fe ? fe->m_adapter : m_adapter.begin();
868         int fesource = fe ? fe->m_frontend->getDVBID() : -1;
869         ePtr<eDVBRegisteredDemux> unused;
870         uint8_t d, a;
871
872         /*
873          * For pvr playback, start with the last demux.
874          * On some hardware, there are less ca devices than demuxes, so try to leave
875          * the first demuxes for live tv, and start with the last for pvr playback
876          */
877         bool use_decode_demux = (fe || (cap & iDVBChannel::capDecode));
878
879         if (!use_decode_demux)
880         {
881                 i = m_demux.end();
882                 --i;
883         }
884
885         while (i != m_demux.end())
886         {
887                 if (i->m_adapter == adapter)
888                 {
889                         if (!i->m_inuse)
890                         {
891                                 // mark the first unused demux and use that when no better match is found
892                                 if (!unused)
893                                         unused = i;
894                         }
895                         else
896                         {
897                                 // demux is in use, see if it can be shared
898                                 if (fesource >= 0 && i->m_demux->getSource() == fesource)
899                                 {
900                                         i->m_demux->getCAAdapterID(a);
901                                         i->m_demux->getCADemuxID(d);
902                                         eDebug("[eDVBResourceManager] allocating shared demux adapter=%d, demux=%d, source=%d", a, d, i->m_demux->getSource());
903                                         demux = new eDVBAllocatedDemux(i);
904                                         return 0;
905                                 }
906                         }
907                 }
908                 if (use_decode_demux)
909                 {
910                         ++i;
911                 }
912                 else
913                 {
914                         if (i == m_demux.begin())
915                                 break;
916                         --i;
917                 }
918         }
919
920         if (unused)
921         {
922                 unused->m_demux->getCAAdapterID(a);
923                 unused->m_demux->getCADemuxID(d);
924                 eDebug("[eDVBResourceManager] allocating demux adapter=%d, demux=%d, source=%d fesource=%d", a, d, unused->m_demux->getSource(), fesource);
925                 demux = new eDVBAllocatedDemux(unused);
926                 if (fe)
927                         demux->get().setSourceFrontend(fesource);
928                 else
929                         demux->get().setSourcePVR(0);
930                 return 0;
931         }
932
933         eDebug("[eDVBResourceManager] no free demux found");
934         return -1;
935 }
936
937 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
938 {
939         m_list = list;
940         return 0;
941 }
942
943 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
944 {
945         list = m_list;
946         if (list)
947                 return 0;
948         else
949                 return -ENOENT;
950 }
951
952 #define eDebugNoSimulate(x...) \
953         do { \
954                 if (!simulate) \
955                         eDebug(x); \
956         } while(0)
957
958
959 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate)
960 {
961                 /* first, check if a channel is already existing. */
962         std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
963
964         if (!simulate && m_cached_channel)
965         {
966                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
967                 if(channelid==cache_chan->getChannelID())
968                 {
969                         eDebug("[eDVBResourceManager] use cached_channel");
970                         channel = m_cached_channel;
971                         return 0;
972                 }
973                 m_cached_channel_state_changed_conn.disconnect();
974                 m_cached_channel=0;
975                 m_releaseCachedChannelTimer->stop();
976         }
977
978         eDebugNoSimulate("[eDVBResourceManager] allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
979         for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
980         {
981                 eDebugNoSimulate("[eDVBResourceManager] available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
982                 if (i->m_channel_id == channelid)
983                 {
984                         eDebugNoSimulate("[eDVBResourceManager] found shared channel..");
985                         channel = i->m_channel;
986                         return 0;
987                 }
988         }
989
990         /* no currently available channel is tuned to this channelid. create a new one, if possible. */
991
992         if (!m_list)
993         {
994                 eDebugNoSimulate("[eDVBResourceManager] no channel list set!");
995                 return errNoChannelList;
996         }
997
998         ePtr<iDVBFrontendParameters> feparm;
999         if (m_list->getChannelFrontendData(channelid, feparm))
1000         {
1001                 eDebugNoSimulate("[eDVBResourceManager] channel not found!");
1002                 return errChannelNotInList;
1003         }
1004
1005         /* allocate a frontend. */
1006
1007         ePtr<eDVBAllocatedFrontend> fe;
1008
1009         int err = allocateFrontend(fe, feparm, simulate);
1010         if (err)
1011                 return err;
1012
1013         RESULT res;
1014         ePtr<eDVBChannel> ch = new eDVBChannel(this, fe);
1015
1016         res = ch->setChannel(channelid, feparm);
1017         if (res)
1018         {
1019                 channel = 0;
1020                 return errChidNotFound;
1021         }
1022
1023         if (simulate)
1024                 channel = ch;
1025         else
1026         {
1027                 m_cached_channel = channel = ch;
1028                 m_cached_channel_state_changed_conn =
1029                         CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
1030         }
1031
1032         return 0;
1033 }
1034
1035 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
1036 {
1037         int state=0;
1038         chan->getState(state);
1039         switch (state)
1040         {
1041                 case iDVBChannel::state_release:
1042                 case iDVBChannel::state_ok:
1043                 {
1044                         eDebug("[eDVBResourceManager] stop release channel timer");
1045                         m_releaseCachedChannelTimer->stop();
1046                         break;
1047                 }
1048                 case iDVBChannel::state_last_instance:
1049                 {
1050                         eDebug("[eDVBResourceManager] start release channel timer");
1051                         m_releaseCachedChannelTimer->start(3000, true);
1052                         break;
1053                 }
1054                 default: // ignore all other events
1055                         break;
1056         }
1057 }
1058
1059 void eDVBResourceManager::releaseCachedChannel()
1060 {
1061         eDebug("[eDVBResourceManager] release cached channel (timer timeout)");
1062         m_cached_channel=0;
1063 }
1064
1065 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
1066 {
1067         ePtr<eDVBAllocatedFrontend> fe;
1068
1069         if (m_cached_channel)
1070         {
1071                 m_cached_channel_state_changed_conn.disconnect();
1072                 m_cached_channel=0;
1073                 m_releaseCachedChannelTimer->stop();
1074         }
1075
1076         int err = allocateFrontendByIndex(fe, slot_index);
1077         if (err)
1078                 return err;
1079
1080         channel = new eDVBChannel(this, fe);
1081         return 0;
1082 }
1083
1084
1085 RESULT eDVBResourceManager::allocatePVRChannel(const eDVBChannelID &channelid, eUsePtr<iDVBPVRChannel> &channel)
1086 {
1087         ePtr<eDVBAllocatedDemux> demux;
1088
1089         if (m_cached_channel && m_releaseCachedChannelTimer->isActive())
1090         {
1091                 m_cached_channel_state_changed_conn.disconnect();
1092                 m_cached_channel=0;
1093                 m_releaseCachedChannelTimer->stop();
1094         }
1095
1096         ePtr<eDVBChannel> ch = new eDVBChannel(this, 0);
1097         if (channelid)
1098         {
1099                 /*
1100                  * user provided a channelid, with the clear intention for
1101                  * this channel to be registered at the resource manager.
1102                  * (allowing e.g. epgcache to be started)
1103                  */
1104                 ePtr<iDVBFrontendParameters> feparm;
1105                 ch->setChannel(channelid, feparm);
1106         }
1107         channel = ch;
1108         return 0;
1109 }
1110
1111 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
1112 {
1113         bool simulate = false;
1114         ePtr<iDVBFrontend> fe;
1115         if (!ch->getFrontend(fe))
1116         {
1117                 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
1118                 simulate = frontend->is_simulate();
1119         }
1120         std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
1121         active_channels.push_back(active_channel(chid, ch));
1122         if (!simulate)
1123         {
1124                 /* emit */ m_channelAdded(ch);
1125         }
1126         return 0;
1127 }
1128
1129 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
1130 {
1131         bool simulate = false;
1132         ePtr<iDVBFrontend> fe;
1133         if (!ch->getFrontend(fe))
1134         {
1135                 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
1136                 simulate = frontend->is_simulate();
1137         }
1138         std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
1139         int cnt = 0;
1140         for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end();)
1141         {
1142                 if (i->m_channel == ch)
1143                 {
1144                         i = active_channels.erase(i);
1145                         ++cnt;
1146                 } else
1147                         ++i;
1148         }
1149         ASSERT(cnt == 1);
1150         if (cnt == 1)
1151                 return 0;
1152         return -ENOENT;
1153 }
1154
1155 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
1156 {
1157         connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
1158         return 0;
1159 }
1160
1161 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm, bool simulate)
1162 {
1163         eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
1164         ePtr<eDVBRegisteredFrontend> best;
1165         int bestval = 0;
1166
1167         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
1168                 if (!i->m_inuse)
1169                 {
1170                         int c = i->m_frontend->isCompatibleWith(feparm);
1171                         if (c > bestval)
1172                                 bestval = c;
1173                 }
1174         return bestval;
1175 }
1176
1177 int tuner_type_channel_default(ePtr<iDVBChannelList> &channellist, const eDVBChannelID &chid, int &system)
1178 {
1179         system = iDVBFrontend::feSatellite;
1180         if (channellist)
1181         {
1182                 ePtr<iDVBFrontendParameters> feparm;
1183                 if (!channellist->getChannelFrontendData(chid, feparm))
1184                 {
1185                         if (!feparm->getSystem(system))
1186                         {
1187                                 switch (system)
1188                                 {
1189                                         case iDVBFrontend::feSatellite:
1190                                                 return 50000;
1191                                         case iDVBFrontend::feCable:
1192                                                 return 40000;
1193                                         case iDVBFrontend::feTerrestrial:
1194                                                 return 30000;
1195                                         default:
1196                                                 break;
1197                                 }
1198                         }
1199                 }
1200         }
1201         return 0;
1202 }
1203
1204 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, int &system, bool simulate)
1205 {
1206         std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
1207         int ret = 0;
1208         system = iDVBFrontend::feSatellite;
1209         if (!simulate && m_cached_channel)
1210         {
1211                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
1212                 if(channelid==cache_chan->getChannelID())
1213                         return tuner_type_channel_default(m_list, channelid, system);
1214         }
1215
1216                 /* first, check if a channel is already existing. */
1217 //      eDebug("[eDVBResourceManager] allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
1218         for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
1219         {
1220 //              eDebug("[eDVBResourceManager] available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
1221                 if (i->m_channel_id == channelid)
1222                 {
1223 //                      eDebug("[eDVBResourceManager] found shared channel..");
1224                         return tuner_type_channel_default(m_list, channelid, system);
1225                 }
1226         }
1227
1228         int *decremented_cached_channel_fe_usecount=NULL,
1229                 *decremented_fe_usecount=NULL;
1230
1231         for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
1232         {
1233                 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
1234 //              eDebug("[eDVBResourceManager] available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
1235                 if (i->m_channel_id == ignore)
1236                 {
1237                         eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
1238                         // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
1239                         // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
1240                         // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
1241                         // or 2 when the cached channel is not equal to the compared channel
1242                         if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2)  // channel only used once..
1243                         {
1244                                 ePtr<iDVBFrontend> fe;
1245                                 if (!i->m_channel->getFrontend(fe))
1246                                 {
1247                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
1248                                         {
1249                                                 if ( &(*fe) == &(*ii->m_frontend) )
1250                                                 {
1251                                                         --ii->m_inuse;
1252                                                         decremented_fe_usecount = &ii->m_inuse;
1253                                                         if (channel == &(*m_cached_channel))
1254                                                                 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
1255                                                         break;
1256                                                 }
1257                                         }
1258                                 }
1259                         }
1260                         break;
1261                 }
1262         }
1263
1264         if (!decremented_cached_channel_fe_usecount)
1265         {
1266                 if (m_cached_channel)
1267                 {
1268                         eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
1269                         if (channel->getUseCount() == 1)
1270                         {
1271                                 ePtr<iDVBFrontend> fe;
1272                                 if (!channel->getFrontend(fe))
1273                                 {
1274                                         eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
1275                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
1276                                         {
1277                                                 if ( &(*fe) == &(*ii->m_frontend) )
1278                                                 {
1279                                                         --ii->m_inuse;
1280                                                         decremented_cached_channel_fe_usecount = &ii->m_inuse;
1281                                                         break;
1282                                                 }
1283                                         }
1284                                 }
1285                         }
1286                 }
1287         }
1288         else
1289                 decremented_cached_channel_fe_usecount=NULL;
1290
1291         ePtr<iDVBFrontendParameters> feparm;
1292
1293         if (!m_list)
1294         {
1295                 eDebug("[eDVBResourceManager] no channel list set!");
1296                 goto error;
1297         }
1298
1299         if (m_list->getChannelFrontendData(channelid, feparm))
1300         {
1301                 eDebug("[eDVBResourceManager] channel not found!");
1302                 goto error;
1303         }
1304         feparm->getSystem(system);
1305
1306         ret = canAllocateFrontend(feparm, simulate);
1307
1308 error:
1309         if (decremented_fe_usecount)
1310                 ++(*decremented_fe_usecount);
1311         if (decremented_cached_channel_fe_usecount)
1312                 ++(*decremented_cached_channel_fe_usecount);
1313
1314         return ret;
1315 }
1316
1317 bool eDVBResourceManager::canMeasureFrontendInputPower()
1318 {
1319         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
1320         {
1321                 return i->m_frontend->readInputpower() >= 0;
1322         }
1323         return false;
1324 }
1325
1326 class eDVBChannelFilePush: public eFilePushThread
1327 {
1328 public:
1329         eDVBChannelFilePush(int packetsize = 188):
1330                 eFilePushThread(packetsize, packetsize * 512),
1331                 m_iframe_search(0),
1332                 m_iframe_state(0),
1333                 m_pid(0),
1334                 m_timebase_change(0),
1335                 m_packet_size(packetsize),
1336                 m_parity_switch_delay(0),
1337                 m_parity(-1)
1338         {}
1339         void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
1340
1341                         /* "timebase change" is for doing trickmode playback at an exact speed, even when pictures are skipped. */
1342                         /* you need to set it to 1/16 if you want 16x playback, for example. you need video master sync. */
1343         void setTimebaseChange(int ratio) { m_timebase_change = ratio; } /* 16bit fixpoint, 0 for disable */
1344         void setParitySwitchDelay(int msdelay) { m_parity_switch_delay = msdelay; }
1345 protected:
1346         int m_iframe_search, m_iframe_state, m_pid;
1347         int m_timebase_change;
1348         int m_packet_size;
1349         int m_parity_switch_delay;
1350         int m_parity;
1351         void filterRecordData(const unsigned char *data, int len);
1352 };
1353
1354 void eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len)
1355 {
1356         if (m_parity_switch_delay)
1357         {
1358                 int offset;
1359                 for (offset = 0; offset < len; offset += m_packet_size)
1360                 {
1361                         const unsigned char *pkt = _data + offset + m_packet_size - 188;
1362                         if (pkt[3] & 0xc0)
1363                         {
1364                                 int parity = (pkt[3] & 0x40) ? 1 : 0;
1365                                 if (parity != m_parity)
1366                                 {
1367                                         if (m_parity >= 0)
1368                                         {
1369                                                 usleep(m_parity_switch_delay * 1000);
1370                                         }
1371                                         m_parity = parity;
1372                                         break;
1373                                 }
1374                         }
1375                 }
1376         }
1377 }
1378
1379 DEFINE_REF(eDVBChannel);
1380
1381 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1382 {
1383         m_frontend = frontend;
1384
1385         m_pvr_thread = 0;
1386         m_pvr_fd_dst = -1;
1387
1388         m_skipmode_n = m_skipmode_m = m_skipmode_frames = 0;
1389
1390         if (m_frontend)
1391                 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1392 }
1393
1394 eDVBChannel::~eDVBChannel()
1395 {
1396         if (m_channel_id)
1397                 m_mgr->removeChannel(this);
1398
1399         stop();
1400 }
1401
1402 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1403 {
1404         int state, ourstate = 0;
1405
1406                 /* if we are already in shutdown, don't change state. */
1407         if (m_state == state_release)
1408                 return;
1409
1410         if (fe->getState(state))
1411                 return;
1412
1413         if (state == iDVBFrontend::stateLock)
1414         {
1415                 eDebug("[eDVBChannel] OURSTATE: ok");
1416                 ourstate = state_ok;
1417         } else if (state == iDVBFrontend::stateTuning)
1418         {
1419                 eDebug("[eDVBChannel] OURSTATE: tuning");
1420                 ourstate = state_tuning;
1421         } else if (state == iDVBFrontend::stateLostLock)
1422         {
1423                         /* on managed channels, we try to retune in order to re-acquire lock. */
1424                 if (m_current_frontend_parameters)
1425                 {
1426                         eDebug("[eDVBChannel] OURSTATE: lost lock, trying to retune");
1427                         ourstate = state_tuning;
1428                         m_frontend->get().tune(*m_current_frontend_parameters);
1429                 } else
1430                         /* on unmanaged channels, we don't do this. the client will do this. */
1431                 {
1432                         eDebug("[eDVBChannel] OURSTATE: lost lock, unavailable now.");
1433                         ourstate = state_unavailable;
1434                 }
1435         } else if (state == iDVBFrontend::stateFailed)
1436         {
1437                 ourstate = state_failed;
1438                         /* on managed channels, we do a retry */
1439                 if (m_current_frontend_parameters)
1440                 {
1441                         eDebug("[eDVBChannel] OURSTATE: failed, retune");
1442                         m_frontend->get().tune(*m_current_frontend_parameters);
1443                 } else
1444                 { /* nothing we can do */
1445                         eDebug("[eDVBChannel] OURSTATE: failed, fatal");
1446                 }
1447         } else
1448                 eFatal("[eDVBChannel] state unknown");
1449
1450         if (ourstate != m_state)
1451         {
1452                 m_state = ourstate;
1453                 m_stateChanged(this);
1454         }
1455 }
1456
1457 void eDVBChannel::pvrEvent(int event)
1458 {
1459         switch (event)
1460         {
1461         case eFilePushThread::evtEOF:
1462                 eDebug("[eDVBChannel] End of file!");
1463                 m_event(this, evtEOF);
1464                 break;
1465         case eFilePushThread::evtUser: /* start */
1466                 eDebug("[eDVBChannel] SOF");
1467                 m_event(this, evtSOF);
1468                 break;
1469         case eFilePushThread::evtStopped:
1470                 eDebug("[eDVBChannel] pvrEvent evtStopped");
1471                 m_event(this, evtStopped);
1472                 break;
1473         }
1474 }
1475
1476 void eDVBChannel::cueSheetEvent(int event)
1477 {
1478                 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1479         if (!m_pvr_thread)
1480                 return;
1481         switch (event)
1482         {
1483         case eCueSheet::evtSeek:
1484                 eDebug("[eDVBChannel] seek.");
1485                 flushPVR(m_cue->m_decoding_demux);
1486                 break;
1487         case eCueSheet::evtSkipmode:
1488         {
1489                 {
1490                         m_cue->m_lock.WrLock();
1491                         m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1492                         m_cue->m_lock.Unlock();
1493                         eRdLocker l(m_cue->m_lock);
1494                         if (m_cue->m_skipmode_ratio)
1495                         {
1496                                 m_tstools_lock.lock();
1497                                 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1498                                 m_tstools_lock.unlock();
1499                                 eDebug("[eDVBChannel] skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1500                                                 /* i agree that this might look a bit like black magic. */
1501                                 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1502                                 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1503                                 m_skipmode_frames = m_cue->m_skipmode_ratio / 90000;
1504                                 m_skipmode_frames_remainder = 0;
1505
1506                                 if (m_cue->m_skipmode_ratio < 0)
1507                                         m_skipmode_m -= m_skipmode_n;
1508
1509                                 eDebug("[eDVBChannel] resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1510
1511                                 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1512                                 {
1513                                         eWarning("[eDVBChannel] something is wrong with this cueSheetEvent calculation");
1514                                         m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1515                                 }
1516                         } else
1517                         {
1518                                 eDebug("[eDVBChannel] skipmode ratio is 0, normal play");
1519                                 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1520                         }
1521                 }
1522                 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1523                 if (m_cue->m_skipmode_ratio != 0)
1524                         m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1525                 else
1526                         m_pvr_thread->setTimebaseChange(0); /* normal playback */
1527                 eDebug("[eDVBChannel] flush pvr");
1528                 flushPVR(m_cue->m_decoding_demux);
1529                 eDebug("[eDVBChannel] done");
1530                 break;
1531         }
1532         case eCueSheet::evtSpanChanged:
1533         {
1534                 m_source_span.clear();
1535                 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1536                 {
1537                         off_t offset_in, offset_out;
1538                         pts_t pts_in = i->first, pts_out = i->second;
1539                         m_tstools_lock.lock();
1540                         bool r = m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1);
1541                         m_tstools_lock.unlock();
1542                         if (r)
1543                         {
1544                                 eDebug("[eDVBChannel] span translation failed.\n");
1545                                 continue;
1546                         }
1547                         eDebug("[eDVBChannel] source span: %llu .. %llu, translated to %llu..%llu", pts_in, pts_out, offset_in, offset_out);
1548                         m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1549                 }
1550                 break;
1551         }
1552         }
1553 }
1554
1555         /* align toward zero */
1556 static inline long long align(long long x, int align)
1557 {
1558         if (x < 0)
1559         {
1560                 return x - (x % (-align));
1561         }
1562         else
1563         {
1564                 return x - (x % align);
1565         }
1566 }
1567
1568 static size_t diff_upto(off_t high, off_t low, size_t max)
1569 {
1570         off_t diff = high - low;
1571         if (diff < max)
1572                 return (size_t)diff;
1573         return max;
1574 }
1575
1576         /* remember, this gets called from another thread. */
1577 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size, int blocksize)
1578 {
1579         unsigned int max = align(1024*1024*1024, blocksize);
1580         current_offset = align(current_offset, blocksize);
1581
1582         if (!m_cue)
1583         {
1584                 eDebug("[eDVBChannel] no cue sheet. forcing normal play");
1585                 start = current_offset;
1586                 size = max;
1587                 return;
1588         }
1589
1590         if (m_skipmode_n)
1591         {
1592                 max = align(m_skipmode_n, blocksize);
1593         }
1594
1595         //eDebug("[eDVBChannel] getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1596         int frame_skip_success = 0;
1597
1598         if (m_skipmode_m)
1599         {
1600                 int frames_to_skip = m_skipmode_frames + m_skipmode_frames_remainder;
1601                 //eDebug("[eDVBChannel] we are at %llu, and we try to skip %d+%d frames from here", current_offset, m_skipmode_frames, m_skipmode_frames_remainder);
1602                 size_t iframe_len;
1603                 off_t iframe_start = current_offset;
1604                 int frames_skipped = frames_to_skip;
1605                 m_tstools_lock.lock();
1606                 int r = m_tstools.findNextPicture(iframe_start, iframe_len, frames_skipped);
1607                 m_tstools_lock.unlock();
1608                 if (!r)
1609                 {
1610                         m_skipmode_frames_remainder = frames_to_skip - frames_skipped;
1611                         //eDebug("[eDVBChannel] successfully skipped %d (out of %d, rem now %d) frames.", frames_skipped, frames_to_skip, m_skipmode_frames_remainder);
1612                         current_offset = align(iframe_start, blocksize);
1613                         max = align(iframe_len + 187, blocksize);
1614                         frame_skip_success = 1;
1615                 } else
1616                 {
1617                         m_skipmode_frames_remainder = 0;
1618                         eDebug("[eDVBChannel] frame skipping failed, reverting to byte-skipping");
1619                 }
1620         }
1621
1622         if (!frame_skip_success)
1623         {
1624                 current_offset += align(m_skipmode_m, blocksize);
1625
1626                 if (m_skipmode_m)
1627                 {
1628                         eDebug("[eDVBChannel] we are at %llu, and we try to find the iframe here:", current_offset);
1629                         size_t iframe_len;
1630                         off_t iframe_start = current_offset;
1631
1632                         int direction = (m_skipmode_m < 0) ? -1 : +1;
1633                         m_tstools_lock.lock();
1634                         int r = m_tstools.findFrame(iframe_start, iframe_len, direction);
1635                         m_tstools_lock.unlock();
1636                         if (r)
1637                                 eDebug("[eDVBChannel] failed");
1638                         else
1639                         {
1640                                 current_offset = align(iframe_start, blocksize);
1641                                 max = align(iframe_len, blocksize);
1642                         }
1643                 }
1644         }
1645
1646         m_cue->m_lock.RdLock();
1647
1648         while (!m_cue->m_seek_requests.empty())
1649         {
1650                 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1651                 m_cue->m_lock.Unlock();
1652                 m_cue->m_lock.WrLock();
1653                 m_cue->m_seek_requests.pop_front();
1654                 m_cue->m_lock.Unlock();
1655                 m_cue->m_lock.RdLock();
1656                 int relative = seek.first;
1657                 pts_t pts = seek.second;
1658                 pts_t now = 0;
1659                 if (relative)
1660                 {
1661                         if (!m_cue->m_decoder)
1662                         {
1663                                 eDebug("[eDVBChannel] no decoder - can't seek relative");
1664                                 continue;
1665                         }
1666                         if (m_cue->m_decoder->getPTS(0, now))
1667                         {
1668                                 eDebug("[eDVBChannel] decoder getPTS failed, can't seek relative");
1669                                 continue;
1670                         }
1671                         if (!m_cue->m_decoding_demux)
1672                         {
1673                                 eDebug("[eDVBChannel] getNextSourceSpan, no decoding demux. couldn't seek to %llu... ignore request!", pts);
1674                                 start = current_offset;
1675                                 size = max;
1676                                 continue;
1677                         }
1678                         if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1679                         {
1680                                 eDebug("[eDVBChannel] seekTo: getCurrentPosition failed!");
1681                                 continue;
1682                         }
1683                 } else if (pts < 0) /* seek relative to end */
1684                 {
1685                         pts_t len;
1686                         if (!getLength(len))
1687                         {
1688                                 eDebug("[eDVBChannel] seeking relative to end. len=%lld, seek = %lld", len, pts);
1689                                 pts += len;
1690                         } else
1691                         {
1692                                 eWarning("[eDVBChannel] getLength failed - can't seek relative to end!");
1693                                 continue;
1694                         }
1695                 }
1696
1697                 if (relative == 1) /* pts relative */
1698                 {
1699                         pts += now;
1700                         if (pts < 0)
1701                                 pts = 0;
1702                 }
1703
1704                 if (relative != 2)
1705                         if (pts < 0)
1706                                 pts = 0;
1707
1708                 if (relative == 2) /* AP relative */
1709                 {
1710                         eDebug("[eDVBChannel] AP relative seeking: %lld, at %lld", pts, now);
1711                         pts_t nextap;
1712                         eSingleLocker l(m_tstools_lock);
1713                         if (m_tstools.getNextAccessPoint(nextap, now, pts))
1714                         {
1715                                 pts = now - 90000; /* approx. 1s */
1716                                 eDebug("[eDVBChannel] AP relative seeking failed!");
1717                         } else
1718                         {
1719                                 pts = nextap;
1720                                 eDebug("[eDVBChannel] next ap is %llu\n", pts);
1721                         }
1722                 }
1723
1724                 off_t offset = 0;
1725                 m_tstools_lock.lock();
1726                 int r = m_tstools.getOffset(offset, pts, -1);
1727                 m_tstools_lock.unlock();
1728                 if (r)
1729                 {
1730                         eDebug("[eDVBChannel] get offset for pts=%llu failed!", pts);
1731                         continue;
1732                 }
1733
1734                 eDebug("[eDVBChannel] ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1735                 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1736         }
1737
1738         m_cue->m_lock.Unlock();
1739
1740         for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1741         {
1742                 if (current_offset >= i->first)
1743                 {
1744                         if (current_offset < i->second)
1745                         {
1746                                 start = current_offset;
1747                                 size = diff_upto(i->second, start, max);
1748                                 //eDebug("[eDVBChannel] HIT, %lld < %lld < %lld, size: %zd", i->first, current_offset, i->second, size);
1749                                 return;
1750                         }
1751                 }
1752                 else /* (current_offset < i->first) */
1753                 {
1754                                 /* ok, our current offset is in an 'out' zone. */
1755                         if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1756                         {
1757                                         /* in normal playback, just start at the next zone. */
1758                                 start = i->first;
1759                                 size = diff_upto(i->second, start, max);
1760                                 eDebug("[eDVBChannel] skip");
1761                                 if (m_skipmode_m < 0)
1762                                 {
1763                                         eDebug("[eDVBChannel] reached SOF");
1764                                         m_skipmode_m = 0;
1765                                         m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1766                                 }
1767                         } else
1768                         {
1769                                         /* when skipping reverse, however, choose the zone before. */
1770                                         /* This returns a size 0 block, in case you noticed... */
1771                                 --i;
1772                                 eDebug("[eDVBChannel] skip to previous block, which is %llu..%llu", i->first, i->second);
1773                                 size_t len = diff_upto(i->second, i->first, max);
1774                                 start = i->second - len;
1775                                 eDebug("[eDVBChannel] skipping to %llu, %zd", start, len);
1776                         }
1777
1778                         eDebug("[eDVBChannel] result: %llu, %zx (%llu %llu)", start, size, i->first, i->second);
1779                         return;
1780                 }
1781         }
1782
1783         if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1784         {
1785                 eDebug("[eDVBChannel] reached SOF");
1786                 m_skipmode_m = 0;
1787                 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1788         }
1789
1790         start = current_offset;
1791         if (m_source_span.empty())
1792         {
1793                 size = max;
1794                 // eDebug("[eDVBChannel] NO CUESHEET. (%08llx, %zd)", start, size);
1795         } else
1796         {
1797                 size = 0;
1798         }
1799         return;
1800 }
1801
1802 void eDVBChannel::AddUse()
1803 {
1804         if (++m_use_count > 1 && m_state == state_last_instance)
1805         {
1806                 m_state = state_ok;
1807                 m_stateChanged(this);
1808         }
1809 }
1810
1811 void eDVBChannel::ReleaseUse()
1812 {
1813         int count = --m_use_count;
1814         if (!count)
1815         {
1816                 m_state = state_release;
1817                 m_stateChanged(this);
1818         }
1819         else if (count == 1)
1820         {
1821                 m_state = state_last_instance;
1822                 m_stateChanged(this);
1823         }
1824 }
1825
1826 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1827 {
1828         if (m_channel_id)
1829                 m_mgr->removeChannel(this);
1830
1831         if (!channelid)
1832                 return 0;
1833
1834         m_channel_id = channelid;
1835         m_mgr->addChannel(channelid, this);
1836
1837         if (!m_frontend)
1838         {
1839                 /* no frontend, no need to tune (must be a streamed service) */
1840                 return 0;
1841         }
1842
1843         m_state = state_tuning;
1844                         /* if tuning fails, shutdown the channel immediately. */
1845         int res;
1846         res = m_frontend->get().tune(*feparm);
1847         m_current_frontend_parameters = feparm;
1848
1849         if (res)
1850         {
1851                 m_state = state_release;
1852                 m_stateChanged(this);
1853                 return res;
1854         }
1855
1856         return 0;
1857 }
1858
1859 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1860 {
1861         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1862         return 0;
1863 }
1864
1865 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1866 {
1867         connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1868         return 0;
1869 }
1870
1871 RESULT eDVBChannel::getState(int &state)
1872 {
1873         state = m_state;
1874         return 0;
1875 }
1876
1877 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1878 {
1879         return -1;
1880 }
1881
1882 void eDVBChannel::SDTready(int result)
1883 {
1884         int tsid = -1, onid = -1;
1885         if (!result)
1886         {
1887                 for (std::vector<ServiceDescriptionSection*>::const_iterator i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
1888                 {
1889                         tsid = (*i)->getTransportStreamId();
1890                         onid = (*i)->getOriginalNetworkId();
1891                         break;
1892                 }
1893         }
1894         /* emit */ receivedTsidOnid(tsid, onid);
1895         m_tsid_onid_demux = 0;
1896         m_SDT = 0;
1897 }
1898
1899 int eDVBChannel::reserveDemux()
1900 {
1901         ePtr<iDVBDemux> dmx;
1902         if (!getDemux(dmx, 0))
1903         {
1904                 uint8_t id;
1905                 if (!dmx->getCADemuxID(id))
1906                         return id;
1907         }
1908         return -1;
1909 }
1910
1911 RESULT eDVBChannel::requestTsidOnid()
1912 {
1913         if (!getDemux(m_tsid_onid_demux, 0))
1914         {
1915                 m_SDT = new eTable<ServiceDescriptionSection>;
1916                 CONNECT(m_SDT->tableReady, eDVBChannel::SDTready);
1917                 if (m_SDT->start(m_tsid_onid_demux, eDVBSDTSpec()))
1918                 {
1919                         m_tsid_onid_demux = 0;
1920                         m_SDT = 0;
1921                 }
1922                 else
1923                 {
1924                         return 0;
1925                 }
1926         }
1927         return -1;
1928 }
1929
1930 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1931 {
1932         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1933
1934         eDebug("[eDVBChannel] getDemux cap=%02X", cap);
1935
1936         if (!m_frontend)
1937         {
1938                 /* in dvr mode, we have to stick to a single demux (the one connected to our dvr device) */
1939                 our_demux = m_decoder_demux ? m_decoder_demux : m_demux;
1940         }
1941
1942         if (!our_demux)
1943         {
1944                 demux = 0;
1945
1946                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1947                         return -1;
1948
1949                 demux = *our_demux;
1950         }
1951         else
1952                 demux = *our_demux;
1953
1954         return 0;
1955 }
1956
1957 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1958 {
1959         frontend = 0;
1960         if (!m_frontend)
1961                 return -ENODEV;
1962         frontend = &m_frontend->get();
1963         if (frontend)
1964                 return 0;
1965         return -ENODEV;
1966 }
1967
1968 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &param)
1969 {
1970         param = m_current_frontend_parameters;
1971         return 0;
1972 }
1973
1974 RESULT eDVBChannel::playFile(const char *file)
1975 {
1976         eRawFile *f = new eRawFile();
1977         ePtr<iTsSource> source = f;
1978
1979         if (f->open(file) < 0)
1980         {
1981                 eDebug("[eDVBChannel] can't open PVR file %s: %m", file);
1982                 return -ENOENT;
1983         }
1984
1985         return playSource(source, file);
1986 }
1987
1988 RESULT eDVBChannel::playSource(ePtr<iTsSource> &source, const char *streaminfo_file)
1989 {
1990         ASSERT(!m_frontend);
1991         if (m_pvr_thread)
1992         {
1993                 m_pvr_thread->stop();
1994                 delete m_pvr_thread;
1995                 m_pvr_thread = 0;
1996         }
1997
1998         if (!source->valid() && !source->isStream())
1999         {
2000                 eDebug("[eDVBChannel] PVR source is not valid!");
2001                 return -ENOENT;
2002         }
2003
2004         m_source = source;
2005         m_tstools.setSource(m_source, streaminfo_file);
2006
2007                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
2008                    THEN DO A REAL FIX HERE! */
2009
2010         if (m_pvr_fd_dst < 0)
2011         {
2012                 /* (this codepath needs to be improved anyway.) */
2013 #ifdef HAVE_OLDPVR
2014                 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
2015                 if (m_pvr_fd_dst < 0)
2016                 {
2017                         eDebug("[eDVBChannel] can't open /dev/misc/pvr: %m"); // or wait for the driver to be improved.
2018                         return -ENODEV;
2019                 }
2020 #else
2021                 ePtr<eDVBAllocatedDemux> &demux = m_demux ? m_demux : m_decoder_demux;
2022                 if (demux)
2023                 {
2024                         m_pvr_fd_dst = demux->get().openDVR(O_WRONLY);
2025                         if (m_pvr_fd_dst < 0)
2026                         {
2027                                 eDebug("[eDVBChannel] can't open /dev/dvb/adapterX/dvrX: %m"); // or wait for the driver to be improved.
2028                                 return -ENODEV;
2029                         }
2030                 }
2031                 else
2032                 {
2033                         eDebug("[eDVBChannel] no demux allocated yet.. so its not possible to open the dvr device!!");
2034                         return -ENODEV;
2035                 }
2036 #endif
2037         }
2038
2039         m_pvr_thread = new eDVBChannelFilePush(m_source->getPacketSize());
2040         m_pvr_thread->enablePVRCommit(1);
2041         m_pvr_thread->setStreamMode(m_source->isStream());
2042         m_pvr_thread->setScatterGather(this);
2043
2044         m_event(this, evtPreStart);
2045
2046         m_pvr_thread->start(m_source, m_pvr_fd_dst);
2047         CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
2048
2049         m_state = state_ok;
2050         m_stateChanged(this);
2051
2052         return 0;
2053 }
2054
2055 void eDVBChannel::stop()
2056 {
2057         if (m_pvr_thread)
2058         {
2059                 m_pvr_thread->stop();
2060                 delete m_pvr_thread;
2061                 m_pvr_thread = 0;
2062         }
2063         if (m_pvr_fd_dst >= 0)
2064         {
2065                 ::close(m_pvr_fd_dst);
2066                 m_pvr_fd_dst = -1;
2067         }
2068         m_source = NULL;
2069         m_tstools.setSource(m_source);
2070 }
2071
2072 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
2073 {
2074         m_conn_cueSheetEvent = 0;
2075         m_cue = cuesheet;
2076         if (m_cue)
2077                 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
2078 }
2079
2080 void eDVBChannel::setOfflineDecodeMode(int parityswitchdelay)
2081 {
2082         if (m_pvr_thread) m_pvr_thread->setParitySwitchDelay(parityswitchdelay);
2083 }
2084
2085 RESULT eDVBChannel::getLength(pts_t &len)
2086 {
2087         m_tstools_lock.lock();
2088         RESULT r = m_tstools.calcLen(len);
2089         m_tstools_lock.unlock();
2090         return r;
2091 }
2092
2093 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
2094 {
2095         if (!decoding_demux)
2096                 return -1;
2097
2098         pts_t now;
2099
2100         int r;
2101
2102         if (mode == 0) /* demux */
2103         {
2104                 r = decoding_demux->getSTC(now, 0);
2105                 if (r)
2106                 {
2107                         eDebug("[eDVBChannel] demux getSTC failed");
2108                         return -1;
2109                 }
2110         } else
2111                 now = pos; /* fixup supplied */
2112
2113         m_tstools_lock.lock();
2114         /* Interesting: the only place where iTSSource->offset() is ever used */
2115         r = m_tstools.fixupPTS(m_source ? m_source->offset() : 0, now);
2116         m_tstools_lock.unlock();
2117         if (r)
2118         {
2119                 return -1;
2120         }
2121
2122         pos = now;
2123
2124         return 0;
2125 }
2126
2127 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
2128 {
2129                         /* when seeking, we have to ensure that all buffers are flushed.
2130                            there are basically 3 buffers:
2131                            a.) the filepush's internal buffer
2132                            b.) the PVR buffer (before demux)
2133                            c.) the ratebuffer (after demux)
2134
2135                            it's important to clear them in the correct order, otherwise
2136                            the ratebuffer (for example) would immediately refill from
2137                            the not-yet-flushed PVR buffer.
2138                         */
2139
2140         m_pvr_thread->pause();
2141                 /* HACK: flush PVR buffer */
2142         ::ioctl(m_pvr_fd_dst, 0);
2143
2144                 /* flush ratebuffers (video, audio) */
2145         if (decoding_demux)
2146                 decoding_demux->flush();
2147
2148                 /* demux will also flush all decoder.. */
2149                 /* resume will re-query the SG */
2150         m_pvr_thread->resume();
2151 }
2152
2153 DEFINE_REF(eCueSheet);
2154
2155 eCueSheet::eCueSheet()
2156 {
2157         m_skipmode_ratio = 0;
2158 }
2159
2160 void eCueSheet::seekTo(int relative, const pts_t &pts)
2161 {
2162         m_lock.WrLock();
2163         m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
2164         m_lock.Unlock();
2165         m_event(evtSeek);
2166 }
2167
2168 void eCueSheet::clear()
2169 {
2170         m_lock.WrLock();
2171         m_spans.clear();
2172         m_lock.Unlock();
2173 }
2174
2175 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
2176 {
2177         ASSERT(begin < end);
2178         m_lock.WrLock();
2179         m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
2180         m_lock.Unlock();
2181 }
2182
2183 void eCueSheet::commitSpans()
2184 {
2185         m_event(evtSpanChanged);
2186 }
2187
2188 void eCueSheet::setSkipmode(const pts_t &ratio)
2189 {
2190         m_lock.WrLock();
2191         m_skipmode_ratio = ratio;
2192         m_lock.Unlock();
2193         m_event(evtSkipmode);
2194 }
2195
2196 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
2197 {
2198         m_decoding_demux = demux;
2199         m_decoder = decoder;
2200 }
2201
2202 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
2203 {
2204         connection = new eConnection(this, m_event.connect(event));
2205         return 0;
2206 }