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