remove old softwareupdate from configure and makefile - new softwareupdate could...
[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                                 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
840                         if ((i->second - current_offset) > max)
841                                 size = max;
842                         else
843                                 size = i->second - current_offset;
844                         eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
845                         return;
846                 }
847                 if (current_offset < i->first)
848                 {
849                                 /* ok, our current offset is in an 'out' zone. */
850                         if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
851                         {
852                                         /* in normal playback, just start at the next zone. */
853                                 start = i->first;
854                                 
855                                         /* size is not 64bit! */
856                                 if ((i->second - i->first) > max)
857                                         size = max;
858                                 else
859                                         size = i->second - i->first;
860
861                                 eDebug("skip");
862                                 if (m_skipmode_m < 0)
863                                 {
864                                         eDebug("reached SOF");
865                                                 /* reached SOF */
866                                         m_skipmode_m = 0;
867                                         m_pvr_thread->sendEvent(eFilePushThread::evtUser);
868                                 }
869                         } else
870                         {
871                                         /* when skipping reverse, however, choose the zone before. */
872                                 --i;
873                                 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
874                                 size_t len;
875                                 
876                                 if ((i->second - i->first) > max)
877                                         len = max;
878                                 else
879                                         len = i->second - i->first;
880
881                                 start = i->second - len;
882                                 eDebug("skipping to %llx, %d", start, len);
883                         }
884                         return;
885                 }
886         }
887         
888         if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
889         {
890                 eDebug("reached SOF");
891                 m_skipmode_m = 0;
892                 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
893         }
894         
895         start = current_offset;
896         size = max;
897         eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
898         return;
899 }
900
901 void eDVBChannel::AddUse()
902 {
903         if (++m_use_count > 1 && m_state == state_last_instance)
904         {
905                 m_state = state_ok;
906                 m_stateChanged(this);
907         }
908 }
909
910 void eDVBChannel::ReleaseUse()
911 {
912         if (!--m_use_count)
913         {
914                 m_state = state_release;
915                 m_stateChanged(this);
916         }
917         else if (m_use_count == 1)
918         {
919                 m_state = state_last_instance;
920                 m_stateChanged(this);
921         }
922 }
923
924 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
925 {
926         if (m_channel_id)
927                 m_mgr->removeChannel(this);
928                 
929         if (!channelid)
930                 return 0;
931
932         if (!m_frontend)
933         {
934                 eDebug("no frontend to tune!");
935                 return -ENODEV;
936         }
937         
938         m_channel_id = channelid;
939         m_mgr->addChannel(channelid, this);
940         m_state = state_tuning;
941                         /* if tuning fails, shutdown the channel immediately. */
942         int res;
943         res = m_frontend->get().tune(*feparm);
944         m_current_frontend_parameters = feparm;
945         
946         if (res)
947         {
948                 m_state = state_release;
949                 m_stateChanged(this);
950                 return res;
951         }
952         
953         return 0;
954 }
955
956 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
957 {
958         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
959         return 0;
960 }
961
962 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
963 {
964         connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
965         return 0;
966 }
967
968 RESULT eDVBChannel::getState(int &state)
969 {
970         state = m_state;
971         return 0;
972 }
973
974 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
975 {
976         return -1;
977 }
978
979 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
980 {
981         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
982         
983         if (!our_demux)
984         {
985                 demux = 0;
986                 
987                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
988                         return -1;
989         }
990         
991         demux = *our_demux;
992                 /* don't hold a reference to the decoding demux, we don't need it. */
993         if (cap & capDecode)
994                 our_demux = 0;
995         return 0;
996 }
997
998 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
999 {
1000         frontend = 0;
1001         if (!m_frontend)
1002                 return -ENODEV;
1003         frontend = &m_frontend->get();
1004         if (frontend)
1005                 return 0;
1006         return -ENODEV;
1007 }
1008
1009 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> &param)
1010 {
1011         param = m_current_frontend_parameters;
1012         return 0;
1013 }
1014
1015 RESULT eDVBChannel::playFile(const char *file)
1016 {
1017         ASSERT(!m_frontend);
1018         if (m_pvr_thread)
1019         {
1020                 m_pvr_thread->stop();
1021                 delete m_pvr_thread;
1022                 m_pvr_thread = 0;
1023         }
1024         
1025         m_tstools.openFile(file);
1026         
1027                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1028                    THEN DO A REAL FIX HERE! */
1029         
1030                 /* (this codepath needs to be improved anyway.) */
1031 #if HAVE_DVB_API_VERSION < 3
1032         m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1033 #else
1034         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1035 #endif
1036         if (m_pvr_fd_dst < 0)
1037         {
1038                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1039                 return -ENODEV;
1040         }
1041         
1042         m_state = state_ok;
1043         m_stateChanged(this);
1044         
1045         m_pvr_thread = new eFilePushThread();
1046         m_pvr_thread->enablePVRCommit(1);
1047         m_pvr_thread->setScatterGather(this);
1048
1049         if (m_pvr_thread->start(file, m_pvr_fd_dst))
1050         {
1051                 delete m_pvr_thread;
1052                 m_pvr_thread = 0;
1053                 eDebug("can't open PVR file %s (%m)", file);
1054                 return -ENOENT;
1055         }
1056         CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1057
1058         return 0;
1059 }
1060
1061 void eDVBChannel::stopFile()
1062 {
1063         if (m_pvr_thread)
1064         {
1065                 m_pvr_thread->stop();
1066                 ::close(m_pvr_fd_dst);
1067                 delete m_pvr_thread;
1068                 m_pvr_thread = 0;
1069         }
1070 }
1071
1072 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1073 {
1074         m_conn_cueSheetEvent = 0;
1075         m_cue = cuesheet;
1076         if (m_cue)
1077                 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1078 }
1079
1080 RESULT eDVBChannel::getLength(pts_t &len)
1081 {
1082         return m_tstools.calcLen(len);
1083 }
1084
1085 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1086 {
1087         if (!decoding_demux)
1088                 return -1;
1089         
1090         pts_t now;
1091         
1092         int r;
1093         
1094         if (mode == 0) /* demux */
1095         {
1096                 r = decoding_demux->getSTC(now, 0);
1097                 if (r)
1098                 {
1099                         eDebug("demux getSTC failed");
1100                         return -1;
1101                 }
1102         } else
1103                 now = pos; /* fixup supplied */
1104         
1105         off_t off = 0; /* TODO: fixme */
1106         r = m_tstools.fixupPTS(off, now);
1107         if (r)
1108         {
1109                 eDebug("fixup PTS failed");
1110                 return -1;
1111         }
1112         
1113         pos = now;
1114         
1115         return 0;
1116 }
1117
1118 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1119 {
1120                         /* when seeking, we have to ensure that all buffers are flushed.
1121                            there are basically 3 buffers:
1122                            a.) the filepush's internal buffer
1123                            b.) the PVR buffer (before demux)
1124                            c.) the ratebuffer (after demux)
1125                            
1126                            it's important to clear them in the correct order, otherwise
1127                            the ratebuffer (for example) would immediately refill from
1128                            the not-yet-flushed PVR buffer.
1129                         */
1130
1131         m_pvr_thread->pause();
1132                 /* flush internal filepush buffer */
1133         m_pvr_thread->flush();
1134                 /* HACK: flush PVR buffer */
1135         ::ioctl(m_pvr_fd_dst, 0);
1136         
1137                 /* flush ratebuffers (video, audio) */
1138         if (decoding_demux)
1139                 decoding_demux->flush();
1140
1141                 /* demux will also flush all decoder.. */
1142                 /* resume will re-query the SG */
1143         m_pvr_thread->resume();
1144 }
1145
1146 DEFINE_REF(eCueSheet);
1147
1148 eCueSheet::eCueSheet()
1149 {
1150         m_skipmode_ratio = 0;
1151 }
1152
1153 void eCueSheet::seekTo(int relative, const pts_t &pts)
1154 {
1155         {
1156                 eSingleLock l(m_lock);
1157                 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1158         }
1159         m_event(evtSeek);
1160 }
1161         
1162 void eCueSheet::clear()
1163 {
1164         eSingleLock l(m_lock);
1165         m_spans.clear();
1166 }
1167
1168 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1169 {
1170         {
1171                 eSingleLock l(m_lock);
1172                 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1173         }
1174 }
1175
1176 void eCueSheet::commitSpans()
1177 {
1178         m_event(evtSpanChanged);
1179 }
1180
1181 void eCueSheet::setSkipmode(const pts_t &ratio)
1182 {
1183         {
1184                 eSingleLock l(m_lock);
1185                 m_skipmode_ratio = ratio;
1186         }
1187         m_event(evtSkipmode);
1188 }
1189
1190 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1191 {
1192         m_decoding_demux = demux;
1193         m_decoder = decoder;
1194 }
1195
1196 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1197 {
1198         connection = new eConnection(this, m_event.connect(event));
1199         return 0;
1200 }