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