add cue sheets
[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                 /* we need proper locking here! */
634         eDebug("CUE SHEET EVENT %d", event);
635         
636         switch (event)
637         {
638         case eCueSheet::evtSeek:
639                 eDebug("seek.");
640                 flushPVR(m_cue->m_decoding_demux);
641                 break;
642         case eCueSheet::evtSkipmode:
643         {
644                 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
645                 if (m_cue->m_skipmode_ratio)
646                 {
647                         int bitrate = m_tstools.calcBitrate(); /* in bits/s */
648                         eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
649                                         /* i agree that this might look a bit like black magic. */
650                         m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
651                         m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio;
652
653                         eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
654                         
655                         if (abs(m_skipmode_m) < abs(m_skipmode_n))
656                         {
657                                 eFatal("damn, something is wrong with this calculation");
658                                 m_skipmode_n = m_skipmode_m = 0;
659                         }
660                         
661                 } else
662                 {
663                         eDebug("skipmode ratio is 0, normal play");
664                         m_skipmode_n = m_skipmode_m = 0;
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         if (!m_cue->m_decoding_demux)
690         {
691                 start = current_offset;
692                 size = max;
693                 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
694                 return;
695         }
696         
697         if (m_skipmode_n)
698         {
699                 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
700                 max = m_skipmode_n;
701         }
702         
703         eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
704         
705         if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
706         {
707                 eDebug("reached SOF");
708                 m_skipmode_m = 0;
709                 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
710         }
711         
712         current_offset += m_skipmode_m;
713         
714         while (!m_cue->m_seek_requests.empty())
715         {
716                 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
717                 m_cue->m_seek_requests.pop_front();
718                 int relative = seek.first;
719                 pts_t pts = seek.second;
720
721                 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
722         
723                 if (bitrate == -1)
724                         continue;
725         
726                 if (relative)
727                 {
728                         pts_t now;
729                                         /* we're using the decoder's timestamp here. this 
730                                            won't work for radio (ouch). */
731                         if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
732                         {
733                                 eDebug("seekTo: getCurrentPosition failed!");
734                                 continue;
735                         }
736                         pts += now;
737                 }
738         
739                 if (pts < 0)
740                         pts = 0;
741         
742                 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
743                 
744                 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
745                 current_offset = offset;
746         }
747         
748         for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
749         {
750                 if ((current_offset >= i->first) && (current_offset < i->second))
751                 {
752                         start = current_offset;
753                         size = i->second - current_offset;
754                         if (size > max)
755                                 size = max;
756                         eDebug("HIT, %lld < %lld < %lld", i->first, current_offset, i->second);
757                         return;
758                 }
759                 if (current_offset < i->first)
760                 {
761                         start = i->first;
762                         size = i->second - i->first;
763                         if (size > max)
764                                 size = max;
765                         eDebug("skip");
766                         return;
767                 }
768         }
769         
770         start = current_offset;
771         size = max;
772         eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
773         
774         if (size < 4096)
775                 eFatal("blub");
776         return;
777 }
778
779 void eDVBChannel::AddUse()
780 {
781         ++m_use_count;
782 }
783
784 void eDVBChannel::ReleaseUse()
785 {
786         if (!--m_use_count)
787         {
788                 m_state = state_release;
789                 m_stateChanged(this);
790         }
791 }
792
793 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
794 {
795         if (m_channel_id)
796                 m_mgr->removeChannel(this);
797                 
798         if (!channelid)
799                 return 0;
800
801         if (!m_frontend)
802         {
803                 eDebug("no frontend to tune!");
804                 return -ENODEV;
805         }
806         
807         m_channel_id = channelid;
808         m_mgr->addChannel(channelid, this);
809         m_state = state_tuning;
810                         /* if tuning fails, shutdown the channel immediately. */
811         int res;
812         res = m_frontend->get().tune(*feparm);
813         m_feparm = feparm;
814         
815         if (res)
816         {
817                 m_state = state_release;
818                 m_stateChanged(this);
819                 return res;
820         }
821         
822         return 0;
823 }
824
825 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
826 {
827         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
828         return 0;
829 }
830
831 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
832 {
833         connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
834         return 0;
835 }
836
837 RESULT eDVBChannel::getState(int &state)
838 {
839         state = m_state;
840         return 0;
841 }
842
843 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
844 {
845         return -1;
846 }
847
848 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
849 {
850         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
851         
852         if (!our_demux)
853         {
854                 demux = 0;
855                 
856                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
857                         return -1;
858         }
859         
860         demux = *our_demux;
861                 /* don't hold a reference to the decoding demux, we don't need it. */
862         if (cap & capDecode)
863                 our_demux = 0;
864         return 0;
865 }
866
867 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
868 {
869         frontend = &m_frontend->get();
870         if (frontend)
871                 return 0;
872         else
873                 return -ENODEV;
874 }
875
876 RESULT eDVBChannel::playFile(const char *file)
877 {
878         ASSERT(!m_frontend);
879         if (m_pvr_thread)
880         {
881                 m_pvr_thread->stop();
882                 delete m_pvr_thread;
883                 m_pvr_thread = 0;
884         }
885         
886         m_tstools.openFile(file);
887         
888                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
889                    THEN DO A REAL FIX HERE! */
890         
891                 /* (this codepath needs to be improved anyway.) */
892         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
893         if (m_pvr_fd_dst < 0)
894         {
895                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
896                 return -ENODEV;
897         }
898         
899         m_pvr_fd_src = open(file, O_RDONLY|O_LARGEFILE);
900         if (m_pvr_fd_src < 0)
901         {
902                 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
903                 close(m_pvr_fd_dst);
904                 return -ENOENT;
905         }
906         
907         m_state = state_ok;
908         m_stateChanged(this);
909         
910         m_pvr_thread = new eFilePushThread();
911         m_pvr_thread->enablePVRCommit(1);
912         m_pvr_thread->setScatterGather(this);
913
914         m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
915         CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
916
917         return 0;
918 }
919
920 void eDVBChannel::stopFile()
921 {
922         if (m_pvr_thread)
923         {
924                 m_pvr_thread->stop();
925                 ::close(m_pvr_fd_src);
926                 ::close(m_pvr_fd_dst);
927                 delete m_pvr_thread;
928                 m_pvr_thread = 0;
929         }
930 }
931
932 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
933 {
934         m_conn_cueSheetEvent = 0;
935         m_cue = cuesheet;
936         if (m_cue)
937                 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
938 }
939
940 RESULT eDVBChannel::getLength(pts_t &len)
941 {
942         return m_tstools.calcLen(len);
943 }
944
945 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
946 {
947         if (!decoding_demux)
948                 return -1;
949         
950         off_t begin = 0;
951                 /* getPTS for offset 0 is cached, so it doesn't harm. */
952         int r = m_tstools.getPTS(begin, pos);
953         if (r)
954         {
955                 eDebug("tstools getpts(0) failed!");
956                 return r;
957         }
958         
959         pts_t now;
960         
961                         /* TODO: this is a gross hack. */
962         r = decoding_demux->getSTC(now, mode ? 128 : 0);
963
964         if (r)
965         {
966                 eDebug("demux getSTC failed");
967                 return -1;
968         }
969         
970 //      eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
971                 /* when we are less than 10 seconds before the start, return 0. */
972                 /* (we're just waiting for the timespam to start) */
973         if ((now < pos) && ((pos - now) < 90000 * 10))
974         {
975                 pos = 0;
976                 return 0;
977         }
978         
979         if (now < pos) /* wrap around */
980                 pos = now + ((pts_t)1)<<33 - pos;
981         else
982                 pos = now - pos;
983         
984         return 0;
985 }
986
987 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
988 {
989                         /* when seeking, we have to ensure that all buffers are flushed.
990                            there are basically 3 buffers:
991                            a.) the filepush's internal buffer
992                            b.) the PVR buffer (before demux)
993                            c.) the ratebuffer (after demux)
994                            
995                            it's important to clear them in the correct order, otherwise
996                            the ratebuffer (for example) would immediately refill from
997                            the not-yet-flushed PVR buffer.
998                         */
999
1000         m_pvr_thread->pause();
1001                 /* flush internal filepush buffer */
1002         m_pvr_thread->flush();
1003                 /* HACK: flush PVR buffer */
1004         ::ioctl(m_pvr_fd_dst, 0);
1005         
1006                 /* flush ratebuffers (video, audio) */
1007         if (decoding_demux)
1008                 decoding_demux->flush();
1009
1010                 /* demux will also flush all decoder.. */
1011                 /* resume will re-query the SG */
1012         m_pvr_thread->resume();
1013 }
1014
1015 DEFINE_REF(eCueSheet);
1016
1017 eCueSheet::eCueSheet()
1018 {
1019         m_skipmode_ratio = 0;
1020 }
1021
1022 void eCueSheet::seekTo(int relative, const pts_t &pts)
1023 {
1024         m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1025         m_event(evtSeek);
1026 }
1027         
1028 void eCueSheet::clear()
1029 {
1030         m_spans.clear();
1031 }
1032
1033 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1034 {
1035         m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1036         m_event(evtSpanChanged);
1037 }
1038
1039 void eCueSheet::setSkipmode(const pts_t &ratio)
1040 {
1041         m_skipmode_ratio = ratio;
1042         m_event(evtSkipmode);
1043 }
1044
1045 void eCueSheet::setDecodingDemux(iDVBDemux *demux)
1046 {
1047         m_decoding_demux = demux;
1048 }
1049
1050 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1051 {
1052         connection = new eConnection(this, m_event.connect(event));
1053         return 0;
1054 }