4107c22dc89e65fcfd5f82e2850df56f1a4d16ec
[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->m_inuse++;
22 }
23
24 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
25 {
26         --m_fe->m_inuse;
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->setTone(iDVBFrontend::toneOff);
204                         frontend->setVoltage(iDVBFrontend::voltageOff);
205                         frontend->setSEC(m_sec);
206                         m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
207                 }
208         }
209 }
210
211 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
212 {
213         ePtr<eDVBRegisteredFrontend> best;
214         int bestval = 0;
215
216         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
217                 if (!i->m_inuse)
218                 {
219                         int c = i->m_frontend->isCompatibleWith(feparm);
220                         if (c > bestval)
221                         {
222                                 bestval = c;
223                                 best = i;
224                         }
225                 }
226
227         if (best)
228         {
229                 fe = new eDVBAllocatedFrontend(best);
230                 return 0;
231         }
232         
233         fe = 0;
234         
235         return -1;
236 }
237
238 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
239 {
240         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
241                 if ((!nr) && !i->m_inuse)
242                 {
243                         fe = new eDVBAllocatedFrontend(i);
244                         return 0;
245                 }
246         
247         fe = 0;
248         return -1;
249 }
250
251 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
252 {
253                 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
254                    never use the first one unless we need a decoding demux. */
255
256         eDebug("allocate demux");
257         eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
258         
259         if (i == m_demux.end())
260                 return -1;
261                 
262         int n=0;
263                 /* FIXME: hardware demux policy */
264         if (!(cap & iDVBChannel::capDecode))
265                 ++i, ++n;
266         
267         for (; i != m_demux.end(); ++i, ++n)
268                 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
269                 {
270                         if ((cap & iDVBChannel::capDecode) && n)
271                                 continue;
272                         
273                         demux = new eDVBAllocatedDemux(i);
274                         if (fe)
275                                 demux->get().setSourceFrontend(fe->m_frontend->getID());
276                         else
277                                 demux->get().setSourcePVR(0);
278                         return 0;
279                 }
280         eDebug("demux not found");
281         return -1;
282 }
283
284 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
285 {
286         m_list = list;
287         return 0;
288 }
289
290 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
291 {
292         list = m_list;
293         if (list)
294                 return 0;
295         else
296                 return -ENOENT;
297 }
298
299 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
300 {
301                 /* first, check if a channel is already existing. */
302         
303 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
304         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
305         {
306 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
307                 if (i->m_channel_id == channelid)
308                 {
309 //                      eDebug("found shared channel..");
310                         channel = i->m_channel;
311                         return 0;
312                 }
313         }
314         
315         /* no currently available channel is tuned to this channelid. create a new one, if possible. */
316
317         if (!m_list)
318         {
319                 eDebug("no channel list set!");
320                 return -ENOENT;
321         }
322
323         ePtr<iDVBFrontendParameters> feparm;
324         if (m_list->getChannelFrontendData(channelid, feparm))
325         {
326                 eDebug("channel not found!");
327                 return -ENOENT;
328         }
329
330         /* allocate a frontend. */
331         
332         ePtr<eDVBAllocatedFrontend> fe;
333         
334         if (allocateFrontend(fe, feparm))
335                 return errNoFrontend;
336
337         RESULT res;
338         ePtr<eDVBChannel> ch;
339         ch = new eDVBChannel(this, fe);
340
341         res = ch->setChannel(channelid, feparm);
342         if (res)
343         {
344                 channel = 0;
345                 return errChidNotFound;
346         }
347         channel = ch;
348
349         return 0;
350 }
351
352 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
353 {
354         ePtr<eDVBAllocatedFrontend> fe;
355
356         if (allocateFrontendByIndex(fe, frontend_index))
357                 return errNoFrontend;
358         
359         eDVBChannel *ch;
360         ch = new eDVBChannel(this, fe);
361
362         channel = ch;
363         return 0;
364 }
365
366
367 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
368 {
369         ePtr<eDVBAllocatedDemux> demux;
370         
371         eDVBChannel *ch;
372         ch = new eDVBChannel(this, 0);
373         
374         channel = ch;
375         return 0;
376 }
377
378 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
379 {
380         m_active_channels.push_back(active_channel(chid, ch));
381         /* emit */ m_channelAdded(ch);
382         return 0;
383 }
384
385 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
386 {
387         int cnt = 0;
388         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
389         {
390                 if (i->m_channel == ch)
391                 {
392                         i = m_active_channels.erase(i);
393                         ++cnt;
394                 } else
395                         ++i;
396         }
397         ASSERT(cnt == 1);
398         if (cnt == 1)
399                 return 0;
400         return -ENOENT;
401 }
402
403 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
404 {
405         connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
406         return 0;
407 }
408
409 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm, int used_tuner_mask)
410 {
411         eDebug("canAllocateFrontend mask %08x", used_tuner_mask);
412         ePtr<eDVBRegisteredFrontend> best;
413         int bestval = 0;
414
415         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
416                 if ( !(used_tuner_mask & (1<<i->m_frontend->getID())) )
417                 {
418                         int c = i->m_frontend->isCompatibleWith(feparm);
419                         if (c > bestval)
420                                 bestval = c;
421                 }
422
423         return bestval>0;
424 }
425
426 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid)
427 {
428         return true;
429 #if 0
430         int used_tuner_mask=0;
431
432                 /* first, check if a channel is already existing. */
433 //      eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
434         int cnt=0;
435         for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i, ++cnt)
436         {
437 //              eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
438                 if (i->m_channel_id == channelid)
439                 {
440 //                      eDebug("found shared channel..");
441                         return true;
442                 }
443
444                 eDebug("activeChannel %d, NonDecoderDemux %p, DecoderDemux %p",
445                         cnt, i->m_channel->getNonDecoderDemux(), i->m_channel->getDecoderDemux() );
446                 if ( i->m_channel->getNonDecoderDemux() )
447                 {
448                         ePtr<iDVBFrontend> fe;
449                         if (!i->m_channel->getFrontend(fe))
450                         {
451                                 if (fe)
452                                 {
453                                         for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
454                                         {
455                                                 if ( &(*fe) == &(*ii->m_frontend) )
456                                                 {
457                                                         used_tuner_mask |= (1 << ii->m_frontend->getID());
458                                                         break;
459                                                 }
460                                         }
461                                 }
462                                 else
463                                         eDebug("fe kaputt");
464                         }
465                 }
466         }
467
468         if (!m_list)
469         {
470                 eDebug("no channel list set!");
471                 return false;
472         }
473
474         ePtr<iDVBFrontendParameters> feparm;
475         if (m_list->getChannelFrontendData(channelid, feparm))
476         {
477                 eDebug("channel not found!");
478                 return false;
479         }
480
481         return canAllocateFrontend(feparm, used_tuner_mask);
482 #endif
483 }
484
485 DEFINE_REF(eDVBChannel);
486
487 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
488 {
489         m_frontend = frontend;
490
491         m_pvr_thread = 0;
492         
493         if (m_frontend)
494                 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
495 }
496
497 eDVBChannel::~eDVBChannel()
498 {
499         if (m_channel_id)
500                 m_mgr->removeChannel(this);
501         
502         if (m_pvr_thread)
503         {
504                 m_pvr_thread->stop();
505                 ::close(m_pvr_fd_src);
506                 ::close(m_pvr_fd_dst);
507                 delete m_pvr_thread;
508         }
509 }
510
511 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
512 {
513         int state, ourstate = 0;
514         
515                 /* if we are already in shutdown, don't change state. */
516         if (m_state == state_release)
517                 return;
518         
519         if (fe->getState(state))
520                 return;
521         
522         if (state == iDVBFrontend::stateLock)
523         {
524                 eDebug("OURSTATE: ok");
525                 ourstate = state_ok;
526         } else if (state == iDVBFrontend::stateTuning)
527         {
528                 eDebug("OURSTATE: tuning");
529                 ourstate = state_tuning;
530         } else if (state == iDVBFrontend::stateLostLock)
531         {
532                 eDebug("OURSTATE: lost lock");
533                 ourstate = state_unavailable;
534         } else if (state == iDVBFrontend::stateFailed)
535         {
536                 eDebug("OURSTATE: failed");
537                 ourstate = state_failed;
538         } else
539                 eFatal("state unknown");
540         
541         if (ourstate != m_state)
542         {
543                 m_state = ourstate;
544                 m_stateChanged(this);
545         }
546 }
547
548 void eDVBChannel::AddUse()
549 {
550         ++m_use_count;
551 }
552
553 void eDVBChannel::ReleaseUse()
554 {
555         if (!--m_use_count)
556         {
557                 m_state = state_release;
558                 m_stateChanged(this);
559         }
560 }
561
562 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
563 {
564         if (m_channel_id)
565                 m_mgr->removeChannel(this);
566                 
567         if (!channelid)
568                 return 0;
569
570         if (!m_frontend)
571         {
572                 eDebug("no frontend to tune!");
573                 return -ENODEV;
574         }
575         
576         m_channel_id = channelid;
577         m_mgr->addChannel(channelid, this);
578         m_state = state_tuning;
579                         /* if tuning fails, shutdown the channel immediately. */
580         int res;
581         res = m_frontend->get().tune(*feparm);
582         
583         if (res)
584         {
585                 m_state = state_release;
586                 m_stateChanged(this);
587                 return res;
588         }
589         
590         return 0;
591 }
592
593 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
594 {
595         connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
596         return 0;
597 }
598
599 RESULT eDVBChannel::getState(int &state)
600 {
601         state = m_state;
602         return 0;
603 }
604
605 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
606 {
607         return -1;
608 }
609
610 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
611 {
612         eDebug("get %d demux", cap);
613         ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
614         
615         if (!our_demux)
616         {
617                 demux = 0;
618                 
619                 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
620                         return -1;
621                 
622         }
623         
624         demux = *our_demux;
625         if (cap & capDecode)
626         {
627                 our_demux = 0;
628         }
629         return 0;
630 }
631
632 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
633 {
634         frontend = &m_frontend->get();
635         if (frontend)
636                 return 0;
637         else
638                 return -ENODEV;
639 }
640
641 RESULT eDVBChannel::playFile(const char *file)
642 {
643         ASSERT(!m_frontend);
644         if (m_pvr_thread)
645         {
646                 m_pvr_thread->stop();
647                 delete m_pvr_thread;
648                 m_pvr_thread = 0;
649         }
650         
651         m_tstools.openFile(file);
652         
653                 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
654                    THEN DO A REAL FIX HERE! */
655         
656                 /* (this codepath needs to be improved anyway.) */
657         m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
658         if (m_pvr_fd_dst < 0)
659         {
660                 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
661                 return -ENODEV;
662         }
663         
664         m_pvr_fd_src = open(file, O_RDONLY);
665         if (m_pvr_fd_src < 0)
666         {
667                 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
668                 close(m_pvr_fd_dst);
669                 return -ENOENT;
670         }
671         
672         m_state = state_ok;
673         m_stateChanged(this);
674         
675         m_pvr_thread = new eFilePushThread();
676         m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
677
678         return 0;
679 }
680
681 RESULT eDVBChannel::getLength(pts_t &len)
682 {
683         return m_tstools.calcLen(len);
684 }
685
686 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
687 {
688         if (!decoding_demux)
689                 return -1;
690         
691         off_t begin = 0;
692                 /* getPTS for offset 0 is cached, so it doesn't harm. */
693         int r = m_tstools.getPTS(begin, pos);
694         if (r)
695         {
696                 eDebug("tstools getpts(0) failed!");
697                 return r;
698         }
699         
700         pts_t now;
701         
702         r = decoding_demux->getSTC(now);
703
704         if (r)
705         {
706                 eDebug("demux getSTC failed");
707                 return -1;
708         }
709         
710 //      eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
711                 /* when we are less than 10 seconds before the start, return 0. */
712                 /* (we're just waiting for the timespam to start) */
713         if ((now < pos) && ((pos - now) < 90000 * 10))
714         {
715                 pos = 0;
716                 return 0;
717         }
718         
719         if (now < pos) /* wrap around */
720                 pos = now + ((pts_t)1)<<33 - pos;
721         else
722                 pos = now - pos;
723         
724         return 0;
725 }
726
727 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
728 {
729         int bitrate = m_tstools.calcBitrate(); /* in bits/s */
730         
731         if (bitrate == -1)
732                 return -1;
733         
734         if (relative)
735         {
736                 pts_t now;
737                 if (getCurrentPosition(decoding_demux, now))
738                 {
739                         eDebug("seekTo: getCurrentPosition failed!");
740                         return -1;
741                 }
742                 pts += now;
743         }
744         
745         if (pts < 0)
746                 pts = 0;
747         
748         off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
749         
750         seekToPosition(decoding_demux, offset);
751         return 0;
752 }
753
754 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
755 {
756                         /* when seeking, we have to ensure that all buffers are flushed.
757                            there are basically 3 buffers:
758                            a.) the filepush's internal buffer
759                            b.) the PVR buffer (before demux)
760                            c.) the ratebuffer (after demux)
761                            
762                            it's important to clear them in the correct order, otherwise
763                            the ratebuffer (for example) would immediately refill from
764                            the not-yet-flushed PVR buffer.
765                         */
766         eDebug("eDVBChannel: seekToPosition .. %llx", r);
767         m_pvr_thread->pause();
768
769                 /* flush internal filepush buffer */
770         m_pvr_thread->flush();
771
772                 /* HACK: flush PVR buffer */
773         ::ioctl(m_pvr_fd_dst, 0);
774         
775                 /* flush ratebuffers (video, audio) */
776         if (decoding_demux)
777                 decoding_demux->flush();
778
779                 /* demux will also flush all decoder.. */
780         m_pvr_thread->seek(SEEK_SET, r);
781         m_pvr_thread->resume();
782         return 0;
783 }