do not delete timer.. (sefault in some situations)
[enigma2.git] / lib / dvb / dvb.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/base/filepush.h>
3 #include <lib/dvb/idvb.h>
4 #include <lib/dvb/dvb.h>
5 #include <lib/dvb/sec.h>
6
7 #include <errno.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <fcntl.h>
12 #include <sys/ioctl.h>
13
14 DEFINE_REF(eDVBRegisteredFrontend);
15 DEFINE_REF(eDVBRegisteredDemux);
16
17 DEFINE_REF(eDVBAllocatedFrontend);
18
19 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
20 {
21         m_fe->inc_use();
22 }
23
24 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
25 {
26         m_fe->dec_use();
27 }
28
29 DEFINE_REF(eDVBAllocatedDemux);
30
31 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
32 {
33         m_demux->m_inuse++;
34 }
35
36 eDVBAllocatedDemux::~eDVBAllocatedDemux()
37 {
38         --m_demux->m_inuse;
39 }
40
41 DEFINE_REF(eDVBResourceManager);
42
43 eDVBResourceManager *eDVBResourceManager::instance;
44
45 eDVBResourceManager::eDVBResourceManager()
46 {
47         avail = 1;
48         busy = 0;
49         m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
50         if (!instance)
51                 instance = this;
52                 
53                 /* search available adapters... */
54
55                 // add linux devices
56         
57         int num_adapter = 0;
58         while (eDVBAdapterLinux::exist(num_adapter))
59         {
60                 addAdapter(new eDVBAdapterLinux(num_adapter));
61                 num_adapter++;
62         }
63         
64         eDebug("found %d adapter, %d frontends and %d demux", 
65                 m_adapter.size(), m_frontend.size(), m_demux.size());
66 }
67
68
69 DEFINE_REF(eDVBAdapterLinux);
70 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
71 {
72                 // scan frontends
73         int num_fe = 0;
74         
75         eDebug("scanning for frontends..");
76         while (1)
77         {
78                 struct stat s;
79                 char filename[128];
80 #if HAVE_DVB_API_VERSION < 3
81                 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
82 #else
83                 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
84 #endif
85                 if (stat(filename, &s))
86                         break;
87                 ePtr<eDVBFrontend> fe;
88
89                 int ok = 0;
90                 fe = new eDVBFrontend(m_nr, num_fe, ok);
91                 if (ok)
92                         m_frontend.push_back(fe);
93                 ++num_fe;
94         }
95         
96                 // scan demux
97         int num_demux = 0;
98         while (1)
99         {
100                 struct stat s;
101                 char filename[128];
102 #if HAVE_DVB_API_VERSION < 3
103                 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
104 #else
105                 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
106 #endif
107                 if (stat(filename, &s))
108                         break;
109                 ePtr<eDVBDemux> demux;
110                 
111                 demux = new eDVBDemux(m_nr, num_demux);
112                 m_demux.push_back(demux);
113                         
114                 ++num_demux;
115         }
116 }
117
118 int eDVBAdapterLinux::getNumDemux()
119 {
120         return m_demux.size();
121 }
122
123 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
124 {
125         eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
126         while (nr && (i != m_demux.end()))
127         {
128                 --nr;
129                 ++i;
130         }
131         
132         if (i != m_demux.end())
133                 demux = *i;
134         else
135                 return -1;
136                 
137         return 0;
138 }
139
140 int eDVBAdapterLinux::getNumFrontends()
141 {
142         return m_frontend.size();
143 }
144
145 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
146 {
147         eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
148         while (nr && (i != m_frontend.end()))
149         {
150                 --nr;
151                 ++i;
152         }
153         
154         if (i != m_frontend.end())
155                 fe = *i;
156         else
157                 return -1;
158                 
159         return 0;
160 }
161
162 int eDVBAdapterLinux::exist(int nr)
163 {
164         struct stat s;
165         char filename[128];
166 #if HAVE_DVB_API_VERSION < 3
167         sprintf(filename, "/dev/dvb/card%d", nr);
168 #else
169         sprintf(filename, "/dev/dvb/adapter%d", nr);
170 #endif
171         if (!stat(filename, &s))
172                 return 1;
173         return 0;
174 }
175
176 eDVBResourceManager::~eDVBResourceManager()
177 {
178         if (instance == this)
179                 instance = 0;
180 }
181
182 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
183 {
184         int num_fe = adapter->getNumFrontends();
185         int num_demux = adapter->getNumDemux();
186         
187         m_adapter.push_back(adapter);
188         
189         int i;
190         for (i=0; i<num_demux; ++i)
191         {
192                 ePtr<eDVBDemux> demux;
193                 if (!adapter->getDemux(demux, i))
194                         m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
195         }
196
197         for (i=0; i<num_fe; ++i)
198         {
199                 ePtr<eDVBFrontend> frontend;
200
201                 if (!adapter->getFrontend(frontend, i))
202                 {
203                         frontend->setSEC(m_sec);
204                         m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
205                 }
206         }
207 }
208
209 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
210 {
211         ePtr<eDVBRegisteredFrontend> best;
212         int bestval = 0;
213
214         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
215                 if (!i->m_inuse)
216                 {
217                         int c = i->m_frontend->isCompatibleWith(feparm);
218                         if (c > bestval)
219                         {
220                                 bestval = c;
221                                 best = i;
222                         }
223                 }
224
225         if (best)
226         {
227                 fe = new eDVBAllocatedFrontend(best);
228                 return 0;
229         }
230         
231         fe = 0;
232         
233         return -1;
234 }
235
236 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
237 {
238         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
239                 if ((!nr) && !i->m_inuse)
240                 {
241                         fe = new eDVBAllocatedFrontend(i);
242                         return 0;
243                 }
244         
245         fe = 0;
246         return -1;
247 }
248
249 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
250 {
251                 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
252                    never use the first one unless we need a decoding demux. */
253
254         eDebug("allocate demux");
255         eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
256         
257         if (i == m_demux.end())
258                 return -1;
259                 
260         int n=0;
261                 /* FIXME: hardware demux policy */
262         if (!(cap & iDVBChannel::capDecode))
263                 ++i, ++n;
264         
265         for (; i != m_demux.end(); ++i, ++n)
266                 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
267                 {
268                         if ((cap & iDVBChannel::capDecode) && n)
269                                 continue;
270                         
271                         demux = new eDVBAllocatedDemux(i);
272                         if (fe)
273                                 demux->get().setSourceFrontend(fe->m_frontend->getID());
274                         else
275                                 demux->get().setSourcePVR(0);
276                         return 0;
277                 }
278         eDebug("demux not found");
279         return -1;
280 }
281
282 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
283 {
284         m_list = list;
285         return 0;
286 }
287
288 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
289 {
290         list = m_list;
291         if (list)
292                 return 0;
293         else
294                 return -ENOENT;
295 }
296
297 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
298 {
299                 /* first, check if a channel is already existing. */
300
301         if (m_cached_channel)
302         {
303                 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
304                 if(channelid==cache_chan->getChannelID())
305                 {
306                         eDebug("use cached_channel");
307                         channel=m_cached_channel;
308                         return 0;
309                 }
310                 m_cached_channel=0;
311         }
312
313 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
314         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
315         {
316 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
317                 if (i->m_channel_id == channelid)
318                 {
319 //                      eDebug("found shared channel..");
320                         channel = i->m_channel;
321                         return 0;
322                 }
323         }
324         
325         /* no currently available channel is tuned to this channelid. create a new one, if possible. */
326
327         if (!m_list)
328         {
329                 eDebug("no channel list set!");
330                 return -ENOENT;
331         }
332
333         ePtr<iDVBFrontendParameters> feparm;
334         if (m_list->getChannelFrontendData(channelid, feparm))
335         {
336                 eDebug("channel not found!");
337                 return -ENOENT;
338         }
339
340         /* allocate a frontend. */
341         
342         ePtr<eDVBAllocatedFrontend> fe;
343         
344         if (allocateFrontend(fe, feparm))
345                 return errNoFrontend;
346
347         RESULT res;
348         ePtr<eDVBChannel> ch;
349         ch = new eDVBChannel(this, fe);
350
351         res = ch->setChannel(channelid, feparm);
352         if (res)
353         {
354                 channel = 0;
355                 return errChidNotFound;
356         }
357         m_cached_channel = channel = ch;
358
359         return 0;
360 }
361
362 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
363 {
364         ePtr<eDVBAllocatedFrontend> fe;
365
366         if (m_cached_channel)
367                 m_cached_channel=0;
368
369         if (allocateFrontendByIndex(fe, frontend_index))
370                 return errNoFrontend;
371         
372         eDVBChannel *ch;
373         ch = new eDVBChannel(this, fe);
374
375         channel = ch;
376         return 0;
377 }
378
379
380 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
381 {
382         ePtr<eDVBAllocatedDemux> demux;
383         
384         eDVBChannel *ch;
385         ch = new eDVBChannel(this, 0);
386         
387         channel = ch;
388         return 0;
389 }
390
391 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
392 {
393         m_active_channels.push_back(active_channel(chid, ch));
394         /* emit */ m_channelAdded(ch);
395         return 0;
396 }
397
398 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
399 {
400         int cnt = 0;
401         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
402         {
403                 if (i->m_channel == ch)
404                 {
405                         i = m_active_channels.erase(i);
406                         ++cnt;
407                 } else
408                         ++i;
409         }
410         ASSERT(cnt == 1);
411         if (cnt == 1)
412                 return 0;
413         return -ENOENT;
414 }
415
416 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
417 {
418         connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
419         return 0;
420 }
421
422 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
423 {
424         ePtr<eDVBRegisteredFrontend> best;
425         int bestval = 0;
426
427         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
428                 if (!i->m_inuse)
429                 {
430                         int c = i->m_frontend->isCompatibleWith(feparm);
431                         if (c > bestval)
432                                 bestval = c;
433                 }
434
435         return bestval>0;
436 }
437
438 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
439 {
440                 /* first, check if a channel is already existing. */
441 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
442         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
443         {
444 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
445                 if (i->m_channel_id == channelid)
446                 {
447 //                      eDebug("found shared channel..");
448                         return true;
449                 }
450         }
451
452         int *decremented_fe_usecount=NULL;
453
454         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
455         {
456 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
457                 if (i->m_channel_id == ignore)
458                 {
459                         eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
460                         if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1)  // channel only used once..
461                         {
462                                 ePtr<iDVBFrontend> fe;
463                                 if (!i->m_channel->getFrontend(fe))
464                                 {
465                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
466                                         {
467                                                 if ( &(*fe) == &(*ii->m_frontend) )
468                                                 {
469                                                         --ii->m_inuse;
470                                                         decremented_fe_usecount = &ii->m_inuse;
471                                                         break;
472                                                 }
473                                         }
474                                 }
475                         }
476                         break;
477                 }
478         }
479
480         if (!m_list)
481         {
482                 eDebug("no channel list set!");
483                 return false;
484         }
485
486         ePtr<iDVBFrontendParameters> feparm;
487         if (m_list->getChannelFrontendData(channelid, feparm))
488         {
489                 eDebug("channel not found!");
490                 return false;
491         }
492
493         bool ret = canAllocateFrontend(feparm);
494
495         if (decremented_fe_usecount)
496                 ++(*decremented_fe_usecount);
497
498         return ret;
499 }
500
501 DEFINE_REF(eDVBChannel);
502
503 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
504 {
505         m_frontend = frontend;
506
507         m_pvr_thread = 0;
508         
509         if (m_frontend)
510                 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
511 }
512
513 eDVBChannel::~eDVBChannel()
514 {
515         if (m_channel_id)
516                 m_mgr->removeChannel(this);
517         
518         if (m_pvr_thread)
519         {
520                 m_pvr_thread->stop();
521                 ::close(m_pvr_fd_src);
522                 ::close(m_pvr_fd_dst);
523                 delete m_pvr_thread;
524         }
525 }
526
527 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
528 {
529         int state, ourstate = 0;
530         
531                 /* if we are already in shutdown, don't change state. */
532         if (m_state == state_release)
533                 return;
534         
535         if (fe->getState(state))
536                 return;
537         
538         if (state == iDVBFrontend::stateLock)
539         {
540                 eDebug("OURSTATE: ok");
541                 ourstate = state_ok;
542         } else if (state == iDVBFrontend::stateTuning)
543         {
544                 eDebug("OURSTATE: tuning");
545                 ourstate = state_tuning;
546         } else if (state == iDVBFrontend::stateLostLock)
547         {
548                 eDebug("OURSTATE: lost lock");
549                 ourstate = state_unavailable;
550         } else if (state == iDVBFrontend::stateFailed)
551         {
552                 eDebug("OURSTATE: failed");
553                 ourstate = state_failed;
554         } else
555                 eFatal("state unknown");
556         
557         if (ourstate != m_state)
558         {
559                 m_state = ourstate;
560                 m_stateChanged(this);
561         }
562 }
563
564 void eDVBChannel::AddUse()
565 {
566         ++m_use_count;
567 }
568
569 void eDVBChannel::ReleaseUse()
570 {
571         if (!--m_use_count)
572         {
573                 m_state = state_release;
574                 m_stateChanged(this);
575         }
576 }
577
578 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
579 {
580         if (m_channel_id)
581                 m_mgr->removeChannel(this);
582                 
583         if (!channelid)
584                 return 0;
585
586         if (!m_frontend)
587         {
588                 eDebug("no frontend to tune!");
589                 return -ENODEV;
590         }
591         
592         m_channel_id = channelid;
593         m_mgr->addChannel(channelid, this);
594         m_state = state_tuning;
595                         /* if tuning fails, shutdown the channel immediately. */
596         int res;
597         res = m_frontend->get().tune(*feparm);
598         
599         if (res)
600         {
601                 m_state = state_release;
602                 m_stateChanged(this);
603                 return res;
604         }
605         
606         return 0;
607 }
608
609 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
610 {
611         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
612         return 0;
613 }
614
615 RESULT eDVBChannel::getState(int &state)
616 {
617         state = m_state;
618         return 0;
619 }
620
621 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
622 {
623         return -1;
624 }
625
626 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
627 {
628         eDebug("get %d demux", cap);
629         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
630         
631         if (!our_demux)
632         {
633                 demux = 0;
634                 
635                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
636                         return -1;
637                 
638         }
639         
640         demux = *our_demux;
641         if (cap & capDecode)
642         {
643                 our_demux = 0;
644         }
645         return 0;
646 }
647
648 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
649 {
650         frontend = &m_frontend->get();
651         if (frontend)
652                 return 0;
653         else
654                 return -ENODEV;
655 }
656
657 RESULT eDVBChannel::playFile(const char *file)
658 {
659         ASSERT(!m_frontend);
660         if (m_pvr_thread)
661         {
662                 m_pvr_thread->stop();
663                 delete m_pvr_thread;
664                 m_pvr_thread = 0;
665         }
666         
667         m_tstools.openFile(file);
668         
669                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
670                    THEN DO A REAL FIX HERE! */
671         
672                 /* (this codepath needs to be improved anyway.) */
673         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
674         if (m_pvr_fd_dst < 0)
675         {
676                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
677                 return -ENODEV;
678         }
679         
680         m_pvr_fd_src = open(file, O_RDONLY);
681         if (m_pvr_fd_src < 0)
682         {
683                 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
684                 close(m_pvr_fd_dst);
685                 return -ENOENT;
686         }
687         
688         m_state = state_ok;
689         m_stateChanged(this);
690         
691         m_pvr_thread = new eFilePushThread();
692         m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
693
694         return 0;
695 }
696
697 RESULT eDVBChannel::getLength(pts_t &len)
698 {
699         return m_tstools.calcLen(len);
700 }
701
702 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
703 {
704         if (!decoding_demux)
705                 return -1;
706         
707         off_t begin = 0;
708                 /* getPTS for offset 0 is cached, so it doesn't harm. */
709         int r = m_tstools.getPTS(begin, pos);
710         if (r)
711         {
712                 eDebug("tstools getpts(0) failed!");
713                 return r;
714         }
715         
716         pts_t now;
717         
718         r = decoding_demux->getSTC(now);
719
720         if (r)
721         {
722                 eDebug("demux getSTC failed");
723                 return -1;
724         }
725         
726 //      eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
727                 /* when we are less than 10 seconds before the start, return 0. */
728                 /* (we're just waiting for the timespam to start) */
729         if ((now < pos) && ((pos - now) < 90000 * 10))
730         {
731                 pos = 0;
732                 return 0;
733         }
734         
735         if (now < pos) /* wrap around */
736                 pos = now + ((pts_t)1)<<33 - pos;
737         else
738                 pos = now - pos;
739         
740         return 0;
741 }
742
743 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
744 {
745         int bitrate = m_tstools.calcBitrate(); /* in bits/s */
746         
747         if (bitrate == -1)
748                 return -1;
749         
750         if (relative)
751         {
752                 pts_t now;
753                 if (getCurrentPosition(decoding_demux, now))
754                 {
755                         eDebug("seekTo: getCurrentPosition failed!");
756                         return -1;
757                 }
758                 pts += now;
759         }
760         
761         if (pts < 0)
762                 pts = 0;
763         
764         off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
765         
766         seekToPosition(decoding_demux, offset);
767         return 0;
768 }
769
770 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
771 {
772                         /* when seeking, we have to ensure that all buffers are flushed.
773                            there are basically 3 buffers:
774                            a.) the filepush's internal buffer
775                            b.) the PVR buffer (before demux)
776                            c.) the ratebuffer (after demux)
777                            
778                            it's important to clear them in the correct order, otherwise
779                            the ratebuffer (for example) would immediately refill from
780                            the not-yet-flushed PVR buffer.
781                         */
782         eDebug("eDVBChannel: seekToPosition .. %llx", r);
783         m_pvr_thread->pause();
784
785                 /* flush internal filepush buffer */
786         m_pvr_thread->flush();
787
788                 /* HACK: flush PVR buffer */
789         ::ioctl(m_pvr_fd_dst, 0);
790         
791                 /* flush ratebuffers (video, audio) */
792         if (decoding_demux)
793                 decoding_demux->flush();
794
795                 /* demux will also flush all decoder.. */
796         m_pvr_thread->seek(SEEK_SET, r);
797         m_pvr_thread->resume();
798         return 0;
799 }