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