show terrestrial frontend infos in ServiceInfo dialog
[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                         if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1)  // channel only used once..
540                         {
541                                 ePtr<iDVBFrontend> fe;
542                                 if (!i->m_channel->getFrontend(fe))
543                                 {
544                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
545                                         {
546                                                 if ( &(*fe) == &(*ii->m_frontend) )
547                                                 {
548                                                         --ii->m_inuse;
549                                                         decremented_fe_usecount = &ii->m_inuse;
550                                                         if (channel == &(*m_cached_channel))
551                                                                 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
552                                                         break;
553                                                 }
554                                         }
555                                 }
556                         }
557                         break;
558                 }
559         }
560
561         if (!decremented_cached_channel_fe_usecount)
562         {
563                 if (m_cached_channel)
564                 {
565                         eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
566                         if (channel->getUseCount() == 1)
567                         {
568                                 ePtr<iDVBFrontend> fe;
569                                 if (!channel->getFrontend(fe))
570                                 {
571                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
572                                         {
573                                                 if ( &(*fe) == &(*ii->m_frontend) )
574                                                 {
575                                                         --ii->m_inuse;
576                                                         decremented_cached_channel_fe_usecount = &ii->m_inuse;
577                                                         break;
578                                                 }
579                                         }
580                                 }
581                         }
582                 }
583         }
584         else
585                 decremented_cached_channel_fe_usecount=NULL;
586
587         ePtr<iDVBFrontendParameters> feparm;
588
589         if (!m_list)
590         {
591                 eDebug("no channel list set!");
592                 ret = false;
593                 goto error;
594         }
595
596         if (m_list->getChannelFrontendData(channelid, feparm))
597         {
598                 eDebug("channel not found!");
599                 ret = false;
600                 goto error;
601         }
602
603         ret = canAllocateFrontend(feparm);
604
605 error:
606         if (decremented_fe_usecount)
607                 ++(*decremented_fe_usecount);
608         if (decremented_cached_channel_fe_usecount)
609                 ++(*decremented_cached_channel_fe_usecount);
610
611         return ret;
612 }
613
614 DEFINE_REF(eDVBChannel);
615
616 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
617 {
618         m_frontend = frontend;
619
620         m_pvr_thread = 0;
621         
622         m_skipmode_n = m_skipmode_m = 0;
623         
624         if (m_frontend)
625                 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
626 }
627
628 eDVBChannel::~eDVBChannel()
629 {
630         if (m_channel_id)
631                 m_mgr->removeChannel(this);
632
633         stopFile();
634 }
635
636 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
637 {
638         int state, ourstate = 0;
639         
640                 /* if we are already in shutdown, don't change state. */
641         if (m_state == state_release)
642                 return;
643         
644         if (fe->getState(state))
645                 return;
646         
647         if (state == iDVBFrontend::stateLock)
648         {
649                 eDebug("OURSTATE: ok");
650                 ourstate = state_ok;
651         } else if (state == iDVBFrontend::stateTuning)
652         {
653                 eDebug("OURSTATE: tuning");
654                 ourstate = state_tuning;
655         } else if (state == iDVBFrontend::stateLostLock)
656         {
657                         /* on managed channels, we try to retune in order to re-acquire lock. */
658                 if (m_current_frontend_parameters)
659                 {
660                         eDebug("OURSTATE: lost lock, trying to retune");
661                         ourstate = state_tuning;
662                         m_frontend->get().tune(*m_current_frontend_parameters);
663                 } else
664                         /* on unmanaged channels, we don't do this. the client will do this. */
665                 {
666                         eDebug("OURSTATE: lost lock, unavailable now.");
667                         ourstate = state_unavailable;
668                 }
669         } else if (state == iDVBFrontend::stateFailed)
670         {
671                 eDebug("OURSTATE: failed");
672                 ourstate = state_failed;
673         } else
674                 eFatal("state unknown");
675         
676         if (ourstate != m_state)
677         {
678                 m_state = ourstate;
679                 m_stateChanged(this);
680         }
681 }
682
683 void eDVBChannel::pvrEvent(int event)
684 {
685         switch (event)
686         {
687         case eFilePushThread::evtEOF:
688                 eDebug("eDVBChannel: End of file!");
689                 m_event(this, evtEOF);
690                 break;
691         case eFilePushThread::evtUser: /* start */
692                 eDebug("SOF");
693                 m_event(this, evtSOF);
694                 break;
695         }
696 }
697
698 void eDVBChannel::cueSheetEvent(int event)
699 {
700         switch (event)
701         {
702         case eCueSheet::evtSeek:
703                 eDebug("seek.");
704                 flushPVR(m_cue->m_decoding_demux);
705                 break;
706         case eCueSheet::evtSkipmode:
707         {
708                 {
709                         eSingleLocker l(m_cue->m_lock);
710                         m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
711                         if (m_cue->m_skipmode_ratio)
712                         {
713                                 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
714                                 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
715                                                 /* i agree that this might look a bit like black magic. */
716                                 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
717                                 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
718                                 
719                                 if (m_cue->m_skipmode_ratio < 0)
720                                         m_skipmode_m -= m_skipmode_n;
721         
722                                 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
723                                 
724                                 if (abs(m_skipmode_m) < abs(m_skipmode_n))
725                                 {
726                                         eWarning("something is wrong with this calculation");
727                                         m_skipmode_n = m_skipmode_m = 0;
728                                 }
729                                 
730                         } else
731                         {
732                                 eDebug("skipmode ratio is 0, normal play");
733                                 m_skipmode_n = m_skipmode_m = 0;
734                         }
735                 }
736                 flushPVR(m_cue->m_decoding_demux);
737                 break;
738         }
739         case eCueSheet::evtSpanChanged:
740         {
741                 m_source_span.clear();
742                 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
743                 {
744                         off_t offset_in, offset_out;
745                         pts_t pts_in = i->first, pts_out = i->second;
746                         if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
747                         {
748                                 eDebug("span translation failed.\n");
749                                 continue;
750                         }
751                         eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
752                         m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
753                 }
754                 break;
755         }
756         }
757 }
758
759         /* remember, this gets called from another thread. */
760 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
761 {
762         unsigned int max = 10*1024*1024;
763         
764         if (!m_cue)
765         {
766                 eDebug("no cue sheet. forcing normal play");
767                 start = current_offset;
768                 size = max;
769                 return;
770         }
771
772         eSingleLocker l(m_cue->m_lock);
773         
774         if (!m_cue->m_decoding_demux)
775         {
776                 start = current_offset;
777                 size = max;
778                 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
779                 return;
780         }
781         
782         if (m_skipmode_n)
783         {
784                 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
785                 max = m_skipmode_n;
786         }
787         
788         eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
789         
790         current_offset += m_skipmode_m;
791         
792         while (!m_cue->m_seek_requests.empty())
793         {
794                 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
795                 m_cue->m_seek_requests.pop_front();
796                 int relative = seek.first;
797                 pts_t pts = seek.second;
798
799                 pts_t now = 0;
800                 if (relative)
801                 {
802                         if (!m_cue->m_decoder)
803                         {
804                                 eDebug("no decoder - can't seek relative");
805                                 continue;
806                         }
807                         if (m_cue->m_decoder->getPTS(0, now))
808                         {
809                                 eDebug("decoder getPTS failed, can't seek relative");
810                                 continue;
811                         }
812                         if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
813                         {
814                                 eDebug("seekTo: getCurrentPosition failed!");
815                                 continue;
816                         }
817                 }
818                 
819                 if (relative == 1) /* pts relative */
820                 {
821                         pts += now;
822                         if (pts < 0)
823                                 pts = 0;
824                 }
825
826                 if (relative != 2)
827                         if (pts < 0)
828                                 pts = 0;
829                 
830                 if (relative == 2) /* AP relative */
831                 {
832                         eDebug("AP relative seeking: %lld, at %lld", pts, now);
833                         pts_t nextap;
834                         if (m_tstools.getNextAccessPoint(nextap, now, pts))
835                         {
836                                 pts = now;
837                                 eDebug("AP relative seeking failed!");
838                         } else
839                         {
840                                 eDebug("next ap is %llx\n", pts);
841                                 pts = nextap;
842                         }
843                 }
844                 
845                 off_t offset = 0;
846                 if (m_tstools.getOffset(offset, pts))
847                         continue;
848
849                 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
850                 current_offset = offset;
851         }
852         
853         for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
854         {
855                 if ((current_offset >= i->first) && (current_offset < i->second))
856                 {
857                         start = current_offset;
858                                 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
859                         if ((i->second - current_offset) > max)
860                                 size = max;
861                         else
862                                 size = i->second - current_offset;
863                         eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
864                         return;
865                 }
866                 if (current_offset < i->first)
867                 {
868                                 /* ok, our current offset is in an 'out' zone. */
869                         if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
870                         {
871                                         /* in normal playback, just start at the next zone. */
872                                 start = i->first;
873                                 
874                                         /* size is not 64bit! */
875                                 if ((i->second - i->first) > max)
876                                         size = max;
877                                 else
878                                         size = i->second - i->first;
879
880                                 eDebug("skip");
881                                 if (m_skipmode_m < 0)
882                                 {
883                                         eDebug("reached SOF");
884                                                 /* reached SOF */
885                                         m_skipmode_m = 0;
886                                         m_pvr_thread->sendEvent(eFilePushThread::evtUser);
887                                 }
888                         } else
889                         {
890                                         /* when skipping reverse, however, choose the zone before. */
891                                 --i;
892                                 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
893                                 size_t len;
894                                 
895                                 if ((i->second - i->first) > max)
896                                         len = max;
897                                 else
898                                         len = i->second - i->first;
899
900                                 start = i->second - len;
901                                 eDebug("skipping to %llx, %d", start, len);
902                         }
903                         return;
904                 }
905         }
906         
907         if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
908         {
909                 eDebug("reached SOF");
910                 m_skipmode_m = 0;
911                 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
912         }
913         
914         start = current_offset;
915         size = max;
916         eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
917         return;
918 }
919
920 void eDVBChannel::AddUse()
921 {
922         if (++m_use_count > 1 && m_state == state_last_instance)
923         {
924                 m_state = state_ok;
925                 m_stateChanged(this);
926         }
927 }
928
929 void eDVBChannel::ReleaseUse()
930 {
931         if (!--m_use_count)
932         {
933                 m_state = state_release;
934                 m_stateChanged(this);
935         }
936         else if (m_use_count == 1)
937         {
938                 m_state = state_last_instance;
939                 m_stateChanged(this);
940         }
941 }
942
943 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
944 {
945         if (m_channel_id)
946                 m_mgr->removeChannel(this);
947                 
948         if (!channelid)
949                 return 0;
950
951         if (!m_frontend)
952         {
953                 eDebug("no frontend to tune!");
954                 return -ENODEV;
955         }
956         
957         m_channel_id = channelid;
958         m_mgr->addChannel(channelid, this);
959         m_state = state_tuning;
960                         /* if tuning fails, shutdown the channel immediately. */
961         int res;
962         res = m_frontend->get().tune(*feparm);
963         m_current_frontend_parameters = feparm;
964         
965         if (res)
966         {
967                 m_state = state_release;
968                 m_stateChanged(this);
969                 return res;
970         }
971         
972         return 0;
973 }
974
975 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
976 {
977         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
978         return 0;
979 }
980
981 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
982 {
983         connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
984         return 0;
985 }
986
987 RESULT eDVBChannel::getState(int &state)
988 {
989         state = m_state;
990         return 0;
991 }
992
993 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
994 {
995         return -1;
996 }
997
998 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
999 {
1000         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1001         
1002         if (!our_demux)
1003         {
1004                 demux = 0;
1005                 
1006                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1007                         return -1;
1008         }
1009         
1010         demux = *our_demux;
1011                 /* don't hold a reference to the decoding demux, we don't need it. */
1012                 
1013                 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1014                    the refcount is lost. thus, decoding demuxes are never allocated. 
1015                    
1016                    this poses a big problem for PiP. */
1017         if (cap & capDecode)
1018                 our_demux = 0;
1019         return 0;
1020 }
1021
1022 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1023 {
1024         frontend = 0;
1025         if (!m_frontend)
1026                 return -ENODEV;
1027         frontend = &m_frontend->get();
1028         if (frontend)
1029                 return 0;
1030         return -ENODEV;
1031 }
1032
1033 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &param)
1034 {
1035         param = m_current_frontend_parameters;
1036         return 0;
1037 }
1038
1039 RESULT eDVBChannel::playFile(const char *file)
1040 {
1041         ASSERT(!m_frontend);
1042         if (m_pvr_thread)
1043         {
1044                 m_pvr_thread->stop();
1045                 delete m_pvr_thread;
1046                 m_pvr_thread = 0;
1047         }
1048         
1049         m_tstools.openFile(file);
1050         
1051                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1052                    THEN DO A REAL FIX HERE! */
1053         
1054                 /* (this codepath needs to be improved anyway.) */
1055 #if HAVE_DVB_API_VERSION < 3
1056         m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1057 #else
1058         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1059 #endif
1060         if (m_pvr_fd_dst < 0)
1061         {
1062                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1063                 return -ENODEV;
1064         }
1065
1066         m_pvr_thread = new eFilePushThread();
1067         m_pvr_thread->enablePVRCommit(1);
1068         m_pvr_thread->setScatterGather(this);
1069
1070         if (m_pvr_thread->start(file, m_pvr_fd_dst))
1071         {
1072                 delete m_pvr_thread;
1073                 m_pvr_thread = 0;
1074                 eDebug("can't open PVR file %s (%m)", file);
1075                 return -ENOENT;
1076         }
1077         CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1078
1079         m_state = state_ok;
1080         m_stateChanged(this);
1081
1082         return 0;
1083 }
1084
1085 void eDVBChannel::stopFile()
1086 {
1087         if (m_pvr_thread)
1088         {
1089                 m_pvr_thread->stop();
1090                 ::close(m_pvr_fd_dst);
1091                 delete m_pvr_thread;
1092                 m_pvr_thread = 0;
1093         }
1094 }
1095
1096 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1097 {
1098         m_conn_cueSheetEvent = 0;
1099         m_cue = cuesheet;
1100         if (m_cue)
1101                 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1102 }
1103
1104 RESULT eDVBChannel::getLength(pts_t &len)
1105 {
1106         return m_tstools.calcLen(len);
1107 }
1108
1109 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1110 {
1111         if (!decoding_demux)
1112                 return -1;
1113         
1114         pts_t now;
1115         
1116         int r;
1117         
1118         if (mode == 0) /* demux */
1119         {
1120                 r = decoding_demux->getSTC(now, 0);
1121                 if (r)
1122                 {
1123                         eDebug("demux getSTC failed");
1124                         return -1;
1125                 }
1126         } else
1127                 now = pos; /* fixup supplied */
1128         
1129         off_t off = 0; /* TODO: fixme */
1130         r = m_tstools.fixupPTS(off, now);
1131         if (r)
1132         {
1133                 eDebug("fixup PTS failed");
1134                 return -1;
1135         }
1136         
1137         pos = now;
1138         
1139         return 0;
1140 }
1141
1142 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1143 {
1144                         /* when seeking, we have to ensure that all buffers are flushed.
1145                            there are basically 3 buffers:
1146                            a.) the filepush's internal buffer
1147                            b.) the PVR buffer (before demux)
1148                            c.) the ratebuffer (after demux)
1149                            
1150                            it's important to clear them in the correct order, otherwise
1151                            the ratebuffer (for example) would immediately refill from
1152                            the not-yet-flushed PVR buffer.
1153                         */
1154
1155         m_pvr_thread->pause();
1156                 /* flush internal filepush buffer */
1157         m_pvr_thread->flush();
1158                 /* HACK: flush PVR buffer */
1159         ::ioctl(m_pvr_fd_dst, 0);
1160         
1161                 /* flush ratebuffers (video, audio) */
1162         if (decoding_demux)
1163                 decoding_demux->flush();
1164
1165                 /* demux will also flush all decoder.. */
1166                 /* resume will re-query the SG */
1167         m_pvr_thread->resume();
1168 }
1169
1170 DEFINE_REF(eCueSheet);
1171
1172 eCueSheet::eCueSheet()
1173 {
1174         m_skipmode_ratio = 0;
1175 }
1176
1177 void eCueSheet::seekTo(int relative, const pts_t &pts)
1178 {
1179         {
1180                 eSingleLock l(m_lock);
1181                 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1182         }
1183         m_event(evtSeek);
1184 }
1185         
1186 void eCueSheet::clear()
1187 {
1188         eSingleLock l(m_lock);
1189         m_spans.clear();
1190 }
1191
1192 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1193 {
1194         {
1195                 eSingleLock l(m_lock);
1196                 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1197         }
1198 }
1199
1200 void eCueSheet::commitSpans()
1201 {
1202         m_event(evtSpanChanged);
1203 }
1204
1205 void eCueSheet::setSkipmode(const pts_t &ratio)
1206 {
1207         {
1208                 eSingleLock l(m_lock);
1209                 m_skipmode_ratio = ratio;
1210         }
1211         m_event(evtSkipmode);
1212 }
1213
1214 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1215 {
1216         m_decoding_demux = demux;
1217         m_decoder = decoder;
1218 }
1219
1220 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1221 {
1222         connection = new eConnection(this, m_event.connect(event));
1223         return 0;
1224 }