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