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