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