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