fix timer skip
[enigma2.git] / 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/sec.h>
6
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <sys/ioctl.h>
13
14 DEFINE_REF(eDVBRegisteredFrontend);
15 DEFINE_REF(eDVBRegisteredDemux);
16
17 DEFINE_REF(eDVBAllocatedFrontend);
18
19 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
20 {
21         m_fe->inc_use();
22 }
23
24 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
25 {
26         m_fe->dec_use();
27 }
28
29 DEFINE_REF(eDVBAllocatedDemux);
30
31 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
32 {
33         m_demux->m_inuse++;
34 }
35
36 eDVBAllocatedDemux::~eDVBAllocatedDemux()
37 {
38         --m_demux->m_inuse;
39 }
40
41 DEFINE_REF(eDVBResourceManager);
42
43 eDVBResourceManager *eDVBResourceManager::instance;
44
45 eDVBResourceManager::eDVBResourceManager()
46 {
47         avail = 1;
48         busy = 0;
49         m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
50         if (!instance)
51                 instance = this;
52                 
53                 /* search available adapters... */
54
55                 // add linux devices
56         
57         int num_adapter = 0;
58         while (eDVBAdapterLinux::exist(num_adapter))
59         {
60                 addAdapter(new eDVBAdapterLinux(num_adapter));
61                 num_adapter++;
62         }
63         
64         eDebug("found %d adapter, %d frontends and %d demux", 
65                 m_adapter.size(), m_frontend.size(), m_demux.size());
66 }
67
68
69 DEFINE_REF(eDVBAdapterLinux);
70 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
71 {
72                 // scan frontends
73         int num_fe = 0;
74         
75         eDebug("scanning for frontends..");
76         while (1)
77         {
78                 struct stat s;
79                 char filename[128];
80 #if HAVE_DVB_API_VERSION < 3
81                 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
82 #else
83                 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
84 #endif
85                 if (stat(filename, &s))
86                         break;
87                 ePtr<eDVBFrontend> fe;
88
89                 int ok = 0;
90                 fe = new eDVBFrontend(m_nr, num_fe, ok);
91                 if (ok)
92                         m_frontend.push_back(fe);
93                 ++num_fe;
94         }
95         
96                 // scan demux
97         int num_demux = 0;
98         while (1)
99         {
100                 struct stat s;
101                 char filename[128];
102 #if HAVE_DVB_API_VERSION < 3
103                 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
104 #else
105                 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
106 #endif
107                 if (stat(filename, &s))
108                         break;
109                 ePtr<eDVBDemux> demux;
110                 
111                 demux = new eDVBDemux(m_nr, num_demux);
112                 m_demux.push_back(demux);
113                         
114                 ++num_demux;
115         }
116 }
117
118 int eDVBAdapterLinux::getNumDemux()
119 {
120         return m_demux.size();
121 }
122
123 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
124 {
125         eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
126         while (nr && (i != m_demux.end()))
127         {
128                 --nr;
129                 ++i;
130         }
131         
132         if (i != m_demux.end())
133                 demux = *i;
134         else
135                 return -1;
136                 
137         return 0;
138 }
139
140 int eDVBAdapterLinux::getNumFrontends()
141 {
142         return m_frontend.size();
143 }
144
145 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
146 {
147         eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
148         while (nr && (i != m_frontend.end()))
149         {
150                 --nr;
151                 ++i;
152         }
153         
154         if (i != m_frontend.end())
155                 fe = *i;
156         else
157                 return -1;
158                 
159         return 0;
160 }
161
162 int eDVBAdapterLinux::exist(int nr)
163 {
164         struct stat s;
165         char filename[128];
166 #if HAVE_DVB_API_VERSION < 3
167         sprintf(filename, "/dev/dvb/card%d", nr);
168 #else
169         sprintf(filename, "/dev/dvb/adapter%d", nr);
170 #endif
171         if (!stat(filename, &s))
172                 return 1;
173         return 0;
174 }
175
176 eDVBResourceManager::~eDVBResourceManager()
177 {
178         if (instance == this)
179                 instance = 0;
180 }
181
182 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
183 {
184         int num_fe = adapter->getNumFrontends();
185         int num_demux = adapter->getNumDemux();
186         
187         m_adapter.push_back(adapter);
188         
189         int i;
190         for (i=0; i<num_demux; ++i)
191         {
192                 ePtr<eDVBDemux> demux;
193                 if (!adapter->getDemux(demux, i))
194                         m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
195         }
196
197         for (i=0; i<num_fe; ++i)
198         {
199                 ePtr<eDVBFrontend> frontend;
200
201                 if (!adapter->getFrontend(frontend, i))
202                 {
203                         frontend->setSEC(m_sec);
204                         m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
205                 }
206         }
207 }
208
209 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
210 {
211         ePtr<eDVBRegisteredFrontend> best;
212         int bestval = 0;
213
214         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
215                 if (!i->m_inuse)
216                 {
217                         int c = i->m_frontend->isCompatibleWith(feparm);
218                         if (c > bestval)
219                         {
220                                 bestval = c;
221                                 best = i;
222                         }
223                 }
224
225         if (best)
226         {
227                 fe = new eDVBAllocatedFrontend(best);
228                 return 0;
229         }
230         
231         fe = 0;
232         
233         return -1;
234 }
235
236 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
237 {
238         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
239                 if ((!nr) && !i->m_inuse)
240                 {
241                         fe = new eDVBAllocatedFrontend(i);
242                         return 0;
243                 }
244         
245         fe = 0;
246         return -1;
247 }
248
249 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
250 {
251                 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
252                    never use the first one unless we need a decoding demux. */
253
254         eDebug("allocate demux");
255         eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
256         
257         if (i == m_demux.end())
258                 return -1;
259                 
260         int n=0;
261                 /* FIXME: hardware demux policy */
262         if (!(cap & iDVBChannel::capDecode))
263                 ++i, ++n;
264         
265         for (; i != m_demux.end(); ++i, ++n)
266                 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
267                 {
268                         if ((cap & iDVBChannel::capDecode) && n)
269                                 continue;
270                         
271                         demux = new eDVBAllocatedDemux(i);
272                         if (fe)
273                                 demux->get().setSourceFrontend(fe->m_frontend->getID());
274                         else
275                                 demux->get().setSourcePVR(0);
276                         return 0;
277                 }
278         eDebug("demux not found");
279         return -1;
280 }
281
282 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
283 {
284         m_list = list;
285         return 0;
286 }
287
288 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
289 {
290         list = m_list;
291         if (list)
292                 return 0;
293         else
294                 return -ENOENT;
295 }
296
297 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
298 {
299                 /* first, check if a channel is already existing. */
300
301         if (m_cached_channel)
302         {
303                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
304                 if(channelid==cache_chan->getChannelID())
305                 {
306                         eDebug("use cached_channel");
307                         channel = m_cached_channel;
308                         return 0;
309                 }
310                 m_cached_channel=0;
311         }
312
313 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
314         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
315         {
316 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
317                 if (i->m_channel_id == channelid)
318                 {
319 //                      eDebug("found shared channel..");
320                         channel = i->m_channel;
321                         return 0;
322                 }
323         }
324         
325         /* no currently available channel is tuned to this channelid. create a new one, if possible. */
326
327         if (!m_list)
328         {
329                 eDebug("no channel list set!");
330                 return -ENOENT;
331         }
332
333         ePtr<iDVBFrontendParameters> feparm;
334         if (m_list->getChannelFrontendData(channelid, feparm))
335         {
336                 eDebug("channel not found!");
337                 return -ENOENT;
338         }
339
340         /* allocate a frontend. */
341         
342         ePtr<eDVBAllocatedFrontend> fe;
343         
344         if (allocateFrontend(fe, feparm))
345                 return errNoFrontend;
346
347         RESULT res;
348         ePtr<eDVBChannel> ch;
349         ch = new eDVBChannel(this, fe);
350
351         res = ch->setChannel(channelid, feparm);
352         if (res)
353         {
354                 channel = 0;
355                 return errChidNotFound;
356         }
357         m_cached_channel = channel = ch;
358
359         return 0;
360 }
361
362 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
363 {
364         ePtr<eDVBAllocatedFrontend> fe;
365
366         if (m_cached_channel)
367                 m_cached_channel=0;
368
369         if (allocateFrontendByIndex(fe, frontend_index))
370                 return errNoFrontend;
371         
372         eDVBChannel *ch;
373         ch = new eDVBChannel(this, fe);
374
375         channel = ch;
376         return 0;
377 }
378
379
380 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
381 {
382         ePtr<eDVBAllocatedDemux> demux;
383
384         if (m_cached_channel)
385                 m_cached_channel=0;
386
387         eDVBChannel *ch;
388         ch = new eDVBChannel(this, 0);
389         
390         channel = ch;
391         return 0;
392 }
393
394 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
395 {
396         m_active_channels.push_back(active_channel(chid, ch));
397         /* emit */ m_channelAdded(ch);
398         return 0;
399 }
400
401 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
402 {
403         int cnt = 0;
404         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
405         {
406                 if (i->m_channel == ch)
407                 {
408                         i = m_active_channels.erase(i);
409                         ++cnt;
410                 } else
411                         ++i;
412         }
413         ASSERT(cnt == 1);
414         if (cnt == 1)
415                 return 0;
416         return -ENOENT;
417 }
418
419 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
420 {
421         connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
422         return 0;
423 }
424
425 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
426 {
427         ePtr<eDVBRegisteredFrontend> best;
428         int bestval = 0;
429
430         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
431                 if (!i->m_inuse)
432                 {
433                         int c = i->m_frontend->isCompatibleWith(feparm);
434                         if (c > bestval)
435                                 bestval = c;
436                 }
437
438         return bestval>0;
439 }
440
441 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
442 {
443         bool ret=true;
444         if (m_cached_channel)
445         {
446                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
447                 if(channelid==cache_chan->getChannelID())
448                         return ret;
449         }
450
451                 /* first, check if a channel is already existing. */
452 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
453         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
454         {
455 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
456                 if (i->m_channel_id == channelid)
457                 {
458 //                      eDebug("found shared channel..");
459                         return ret;
460                 }
461         }
462
463         int *decremented_cached_channel_fe_usecount=NULL,
464                 *decremented_fe_usecount=NULL;
465
466         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
467         {
468 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
469                 if (i->m_channel_id == ignore)
470                 {
471                         eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
472                         if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1)  // channel only used once..
473                         {
474                                 ePtr<iDVBFrontend> fe;
475                                 if (!i->m_channel->getFrontend(fe))
476                                 {
477                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
478                                         {
479                                                 if ( &(*fe) == &(*ii->m_frontend) )
480                                                 {
481                                                         --ii->m_inuse;
482                                                         decremented_fe_usecount = &ii->m_inuse;
483                                                         if (channel == &(*m_cached_channel))
484                                                                 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
485                                                         break;
486                                                 }
487                                         }
488                                 }
489                         }
490                         break;
491                 }
492         }
493
494         if (!decremented_cached_channel_fe_usecount)
495         {
496                 if (m_cached_channel)
497                 {
498                         eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
499                         if (channel->getUseCount() == 1)
500                         {
501                                 ePtr<iDVBFrontend> fe;
502                                 if (!channel->getFrontend(fe))
503                                 {
504                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
505                                         {
506                                                 if ( &(*fe) == &(*ii->m_frontend) )
507                                                 {
508                                                         --ii->m_inuse;
509                                                         decremented_cached_channel_fe_usecount = &ii->m_inuse;
510                                                         break;
511                                                 }
512                                         }
513                                 }
514                         }
515                 }
516         }
517         else
518                 decremented_cached_channel_fe_usecount=NULL;
519
520         ePtr<iDVBFrontendParameters> feparm;
521
522         if (!m_list)
523         {
524                 eDebug("no channel list set!");
525                 ret = false;
526                 goto error;
527         }
528
529         if (m_list->getChannelFrontendData(channelid, feparm))
530         {
531                 eDebug("channel not found!");
532                 ret = false;
533                 goto error;
534         }
535
536         ret = canAllocateFrontend(feparm);
537
538 error:
539         if (decremented_fe_usecount)
540                 ++(*decremented_fe_usecount);
541         if (decremented_cached_channel_fe_usecount)
542                 ++(*decremented_cached_channel_fe_usecount);
543
544         return ret;
545 }
546
547 DEFINE_REF(eDVBChannel);
548
549 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
550 {
551         m_frontend = frontend;
552
553         m_pvr_thread = 0;
554         
555         m_skipmode_n = m_skipmode_m = 0;
556         
557         if (m_frontend)
558                 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
559 }
560
561 eDVBChannel::~eDVBChannel()
562 {
563         if (m_channel_id)
564                 m_mgr->removeChannel(this);
565
566         stopFile();
567 }
568
569 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
570 {
571         int state, ourstate = 0;
572         
573                 /* if we are already in shutdown, don't change state. */
574         if (m_state == state_release)
575                 return;
576         
577         if (fe->getState(state))
578                 return;
579         
580         if (state == iDVBFrontend::stateLock)
581         {
582                 eDebug("OURSTATE: ok");
583                 ourstate = state_ok;
584         } else if (state == iDVBFrontend::stateTuning)
585         {
586                 eDebug("OURSTATE: tuning");
587                 ourstate = state_tuning;
588         } else if (state == iDVBFrontend::stateLostLock)
589         {
590                         /* on managed channels, we try to retune in order to re-acquire lock. */
591                 if (m_feparm)
592                 {
593                         eDebug("OURSTATE: lost lock, trying to retune");
594                         ourstate = state_tuning;
595                         m_frontend->get().tune(*m_feparm);
596                 } else
597                         /* on unmanaged channels, we don't do this. the client will do this. */
598                 {
599                         eDebug("OURSTATE: lost lock, unavailable now.");
600                         ourstate = state_unavailable;
601                 }
602         } else if (state == iDVBFrontend::stateFailed)
603         {
604                 eDebug("OURSTATE: failed");
605                 ourstate = state_failed;
606         } else
607                 eFatal("state unknown");
608         
609         if (ourstate != m_state)
610         {
611                 m_state = ourstate;
612                 m_stateChanged(this);
613         }
614 }
615
616 void eDVBChannel::pvrEvent(int event)
617 {
618         switch (event)
619         {
620         case eFilePushThread::evtEOF:
621                 eDebug("eDVBChannel: End of file!");
622                 m_event(this, evtEOF);
623                 break;
624         case eFilePushThread::evtUser: /* start */
625                 eDebug("SOF");
626                 m_event(this, evtSOF);
627                 break;
628         }
629 }
630
631 void eDVBChannel::cueSheetEvent(int event)
632 {
633         switch (event)
634         {
635         case eCueSheet::evtSeek:
636                 eDebug("seek.");
637                 flushPVR(m_cue->m_decoding_demux);
638                 break;
639         case eCueSheet::evtSkipmode:
640         {
641                 {
642                         eSingleLocker l(m_cue->m_lock);
643                         m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
644                         if (m_cue->m_skipmode_ratio)
645                         {
646                                 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
647                                 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
648                                                 /* i agree that this might look a bit like black magic. */
649                                 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
650                                 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio;
651         
652                                 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
653                                 
654                                 if (abs(m_skipmode_m) < abs(m_skipmode_n))
655                                 {
656                                         eFatal("damn, something is wrong with this calculation");
657                                         m_skipmode_n = m_skipmode_m = 0;
658                                 }
659                                 
660                         } else
661                         {
662                                 eDebug("skipmode ratio is 0, normal play");
663                                 m_skipmode_n = m_skipmode_m = 0;
664                         }
665                 }
666                 flushPVR(m_cue->m_decoding_demux);
667                 break;
668         }
669         case eCueSheet::evtSpanChanged:
670                 eDebug("source span translation not yet supported");
671         //      recheckCuesheetSpans();
672                 break;
673         }
674 }
675
676         /* remember, this gets called from another thread. */
677 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
678 {
679         unsigned int max = 10*1024*1024;
680         
681         if (!m_cue)
682         {
683                 eDebug("no cue sheet. forcing normal play");
684                 start = current_offset;
685                 size = max;
686                 return;
687         }
688
689         eSingleLocker l(m_cue->m_lock);
690         
691         if (!m_cue->m_decoding_demux)
692         {
693                 start = current_offset;
694                 size = max;
695                 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
696                 return;
697         }
698         
699         if (m_skipmode_n)
700         {
701                 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
702                 max = m_skipmode_n;
703         }
704         
705         eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
706         
707         if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
708         {
709                 eDebug("reached SOF");
710                 m_skipmode_m = 0;
711                 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
712         }
713         
714         current_offset += m_skipmode_m;
715         
716         while (!m_cue->m_seek_requests.empty())
717         {
718                 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
719                 m_cue->m_seek_requests.pop_front();
720                 int relative = seek.first;
721                 pts_t pts = seek.second;
722
723                 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
724         
725                 if (bitrate == -1)
726                         continue;
727         
728                 if (relative)
729                 {
730                         pts_t now;
731                                         /* we're using the decoder's timestamp here. this 
732                                            won't work for radio (ouch). */
733                         if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
734                         {
735                                 eDebug("seekTo: getCurrentPosition failed!");
736                                 continue;
737                         }
738                         pts += now;
739                 }
740         
741                 if (pts < 0)
742                         pts = 0;
743         
744                 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
745                 
746                 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
747                 current_offset = offset;
748         }
749         
750         for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
751         {
752                 if ((current_offset >= i->first) && (current_offset < i->second))
753                 {
754                         start = current_offset;
755                         size = i->second - current_offset;
756                         if (size > max)
757                                 size = max;
758                         eDebug("HIT, %lld < %lld < %lld", i->first, current_offset, i->second);
759                         return;
760                 }
761                 if (current_offset < i->first)
762                 {
763                         start = i->first;
764                         size = i->second - i->first;
765                         if (size > max)
766                                 size = max;
767                         eDebug("skip");
768                         return;
769                 }
770         }
771         
772         start = current_offset;
773         size = max;
774         eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
775         
776         if (size < 4096)
777                 eFatal("blub");
778         return;
779 }
780
781 void eDVBChannel::AddUse()
782 {
783         ++m_use_count;
784 }
785
786 void eDVBChannel::ReleaseUse()
787 {
788         if (!--m_use_count)
789         {
790                 m_state = state_release;
791                 m_stateChanged(this);
792         }
793 }
794
795 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
796 {
797         if (m_channel_id)
798                 m_mgr->removeChannel(this);
799                 
800         if (!channelid)
801                 return 0;
802
803         if (!m_frontend)
804         {
805                 eDebug("no frontend to tune!");
806                 return -ENODEV;
807         }
808         
809         m_channel_id = channelid;
810         m_mgr->addChannel(channelid, this);
811         m_state = state_tuning;
812                         /* if tuning fails, shutdown the channel immediately. */
813         int res;
814         res = m_frontend->get().tune(*feparm);
815         m_feparm = feparm;
816         
817         if (res)
818         {
819                 m_state = state_release;
820                 m_stateChanged(this);
821                 return res;
822         }
823         
824         return 0;
825 }
826
827 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
828 {
829         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
830         return 0;
831 }
832
833 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
834 {
835         connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
836         return 0;
837 }
838
839 RESULT eDVBChannel::getState(int &state)
840 {
841         state = m_state;
842         return 0;
843 }
844
845 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
846 {
847         return -1;
848 }
849
850 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
851 {
852         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
853         
854         if (!our_demux)
855         {
856                 demux = 0;
857                 
858                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
859                         return -1;
860         }
861         
862         demux = *our_demux;
863                 /* don't hold a reference to the decoding demux, we don't need it. */
864         if (cap & capDecode)
865                 our_demux = 0;
866         return 0;
867 }
868
869 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
870 {
871         frontend = &m_frontend->get();
872         if (frontend)
873                 return 0;
874         else
875                 return -ENODEV;
876 }
877
878 RESULT eDVBChannel::playFile(const char *file)
879 {
880         ASSERT(!m_frontend);
881         if (m_pvr_thread)
882         {
883                 m_pvr_thread->stop();
884                 delete m_pvr_thread;
885                 m_pvr_thread = 0;
886         }
887         
888         m_tstools.openFile(file);
889         
890                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
891                    THEN DO A REAL FIX HERE! */
892         
893                 /* (this codepath needs to be improved anyway.) */
894         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
895         if (m_pvr_fd_dst < 0)
896         {
897                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
898                 return -ENODEV;
899         }
900         
901         m_pvr_fd_src = open(file, O_RDONLY|O_LARGEFILE);
902         if (m_pvr_fd_src < 0)
903         {
904                 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
905                 close(m_pvr_fd_dst);
906                 return -ENOENT;
907         }
908         
909         m_state = state_ok;
910         m_stateChanged(this);
911         
912         m_pvr_thread = new eFilePushThread();
913         m_pvr_thread->enablePVRCommit(1);
914         m_pvr_thread->setScatterGather(this);
915
916         m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
917         CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
918
919         return 0;
920 }
921
922 void eDVBChannel::stopFile()
923 {
924         if (m_pvr_thread)
925         {
926                 m_pvr_thread->stop();
927                 ::close(m_pvr_fd_src);
928                 ::close(m_pvr_fd_dst);
929                 delete m_pvr_thread;
930                 m_pvr_thread = 0;
931         }
932 }
933
934 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
935 {
936         m_conn_cueSheetEvent = 0;
937         m_cue = cuesheet;
938         if (m_cue)
939                 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
940 }
941
942 RESULT eDVBChannel::getLength(pts_t &len)
943 {
944         return m_tstools.calcLen(len);
945 }
946
947 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
948 {
949         if (!decoding_demux)
950                 return -1;
951         
952         off_t begin = 0;
953                 /* getPTS for offset 0 is cached, so it doesn't harm. */
954         int r = m_tstools.getPTS(begin, pos);
955         if (r)
956         {
957                 eDebug("tstools getpts(0) failed!");
958                 return r;
959         }
960         
961         pts_t now;
962         
963                         /* TODO: this is a gross hack. */
964         r = decoding_demux->getSTC(now, mode ? 128 : 0);
965
966         if (r)
967         {
968                 eDebug("demux getSTC failed");
969                 return -1;
970         }
971         
972 //      eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
973                 /* when we are less than 10 seconds before the start, return 0. */
974                 /* (we're just waiting for the timespam to start) */
975         if ((now < pos) && ((pos - now) < 90000 * 10))
976         {
977                 pos = 0;
978                 return 0;
979         }
980         
981         if (now < pos) /* wrap around */
982                 pos = now + ((pts_t)1)<<33 - pos;
983         else
984                 pos = now - pos;
985         
986         return 0;
987 }
988
989 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
990 {
991                         /* when seeking, we have to ensure that all buffers are flushed.
992                            there are basically 3 buffers:
993                            a.) the filepush's internal buffer
994                            b.) the PVR buffer (before demux)
995                            c.) the ratebuffer (after demux)
996                            
997                            it's important to clear them in the correct order, otherwise
998                            the ratebuffer (for example) would immediately refill from
999                            the not-yet-flushed PVR buffer.
1000                         */
1001
1002         m_pvr_thread->pause();
1003                 /* flush internal filepush buffer */
1004         m_pvr_thread->flush();
1005                 /* HACK: flush PVR buffer */
1006         ::ioctl(m_pvr_fd_dst, 0);
1007         
1008                 /* flush ratebuffers (video, audio) */
1009         if (decoding_demux)
1010                 decoding_demux->flush();
1011
1012                 /* demux will also flush all decoder.. */
1013                 /* resume will re-query the SG */
1014         m_pvr_thread->resume();
1015 }
1016
1017 DEFINE_REF(eCueSheet);
1018
1019 eCueSheet::eCueSheet()
1020 {
1021         m_skipmode_ratio = 0;
1022 }
1023
1024 void eCueSheet::seekTo(int relative, const pts_t &pts)
1025 {
1026         {
1027                 eSingleLock l(m_lock);
1028                 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1029         }
1030         m_event(evtSeek);
1031 }
1032         
1033 void eCueSheet::clear()
1034 {
1035         eSingleLock l(m_lock);
1036         m_spans.clear();
1037 }
1038
1039 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1040 {
1041         {
1042                 eSingleLock l(m_lock);
1043                 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1044         }
1045         m_event(evtSpanChanged);
1046 }
1047
1048 void eCueSheet::setSkipmode(const pts_t &ratio)
1049 {
1050         {
1051                 eSingleLock l(m_lock);
1052                 m_skipmode_ratio = ratio;
1053         }
1054         m_event(evtSkipmode);
1055 }
1056
1057 void eCueSheet::setDecodingDemux(iDVBDemux *demux)
1058 {
1059         m_decoding_demux = demux;
1060 }
1061
1062 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1063 {
1064         connection = new eConnection(this, m_event.connect(event));
1065         return 0;
1066 }