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>
12 #include <sys/ioctl.h>
14 DEFINE_REF(eDVBRegisteredFrontend);
15 DEFINE_REF(eDVBRegisteredDemux);
17 DEFINE_REF(eDVBAllocatedFrontend);
19 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
24 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
29 DEFINE_REF(eDVBAllocatedDemux);
31 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
36 eDVBAllocatedDemux::~eDVBAllocatedDemux()
41 DEFINE_REF(eDVBResourceManager);
43 eDVBResourceManager *eDVBResourceManager::instance;
45 RESULT eDVBResourceManager::getInstance(ePtr<eDVBResourceManager> &ptr)
55 eDVBResourceManager::eDVBResourceManager()
56 :m_releaseCachedChannelTimer(eApp)
60 m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
64 /* search available adapters... */
69 while (eDVBAdapterLinux::exist(num_adapter))
71 addAdapter(new eDVBAdapterLinux(num_adapter));
75 eDebug("found %d adapter, %d frontends and %d demux",
76 m_adapter.size(), m_frontend.size(), m_demux.size());
78 CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel);
82 DEFINE_REF(eDVBAdapterLinux);
83 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
88 eDebug("scanning for frontends..");
93 #if HAVE_DVB_API_VERSION < 3
94 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
96 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
98 if (stat(filename, &s))
100 ePtr<eDVBFrontend> fe;
103 fe = new eDVBFrontend(m_nr, num_fe, ok);
105 m_frontend.push_back(fe);
115 #if HAVE_DVB_API_VERSION < 3
116 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
118 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
120 if (stat(filename, &s))
122 ePtr<eDVBDemux> demux;
124 demux = new eDVBDemux(m_nr, num_demux);
125 m_demux.push_back(demux);
131 int eDVBAdapterLinux::getNumDemux()
133 return m_demux.size();
136 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
138 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
139 while (nr && (i != m_demux.end()))
145 if (i != m_demux.end())
153 int eDVBAdapterLinux::getNumFrontends()
155 return m_frontend.size();
158 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
160 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
161 while (nr && (i != m_frontend.end()))
167 if (i != m_frontend.end())
175 int eDVBAdapterLinux::exist(int nr)
179 #if HAVE_DVB_API_VERSION < 3
180 sprintf(filename, "/dev/dvb/card%d", nr);
182 sprintf(filename, "/dev/dvb/adapter%d", nr);
184 if (!stat(filename, &s))
189 eDVBResourceManager::~eDVBResourceManager()
191 if (instance == this)
195 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
197 int num_fe = adapter->getNumFrontends();
198 int num_demux = adapter->getNumDemux();
200 m_adapter.push_back(adapter);
203 for (i=0; i<num_demux; ++i)
205 ePtr<eDVBDemux> demux;
206 if (!adapter->getDemux(demux, i))
207 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
210 for (i=0; i<num_fe; ++i)
212 ePtr<eDVBFrontend> frontend;
214 if (!adapter->getFrontend(frontend, i))
216 frontend->setSEC(m_sec);
217 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
222 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
224 ePtr<eDVBRegisteredFrontend> best;
227 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
230 int c = i->m_frontend->isCompatibleWith(feparm);
240 fe = new eDVBAllocatedFrontend(best);
249 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
251 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
252 if ((!nr) && !i->m_inuse)
254 fe = new eDVBAllocatedFrontend(i);
262 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
264 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
265 never use the first one unless we need a decoding demux. */
267 eDebug("allocate demux");
268 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
270 if (i == m_demux.end())
274 /* FIXME: hardware demux policy */
275 if (!(cap & iDVBChannel::capDecode))
277 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
284 for (; i != m_demux.end(); ++i, ++n)
286 int is_decode = n < 2;
288 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
290 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
292 if ((cap & iDVBChannel::capDecode) && !is_decode)
295 demux = new eDVBAllocatedDemux(i);
297 demux->get().setSourceFrontend(fe->m_frontend->getID());
299 demux->get().setSourcePVR(0);
303 eDebug("demux not found");
307 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
313 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
322 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
324 /* first, check if a channel is already existing. */
326 if (m_cached_channel)
328 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
329 if(channelid==cache_chan->getChannelID())
331 eDebug("use cached_channel");
332 channel = m_cached_channel;
335 m_cached_channel_state_changed_conn.disconnect();
337 m_releaseCachedChannelTimer.stop();
340 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
341 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
343 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
344 if (i->m_channel_id == channelid)
346 // eDebug("found shared channel..");
347 channel = i->m_channel;
352 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
356 eDebug("no channel list set!");
360 ePtr<iDVBFrontendParameters> feparm;
361 if (m_list->getChannelFrontendData(channelid, feparm))
363 eDebug("channel not found!");
367 /* allocate a frontend. */
369 ePtr<eDVBAllocatedFrontend> fe;
371 if (allocateFrontend(fe, feparm))
372 return errNoFrontend;
375 ePtr<eDVBChannel> ch;
376 ch = new eDVBChannel(this, fe);
378 res = ch->setChannel(channelid, feparm);
382 return errChidNotFound;
384 m_cached_channel = channel = ch;
385 m_cached_channel_state_changed_conn =
386 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
391 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
394 chan->getState(state);
397 case iDVBChannel::state_release:
398 case iDVBChannel::state_ok:
400 eDebug("stop release channel timer");
401 m_releaseCachedChannelTimer.stop();
404 case iDVBChannel::state_last_instance:
406 eDebug("start release channel timer");
407 m_releaseCachedChannelTimer.start(3000, true);
410 default: // ignore all other events
415 void eDVBResourceManager::releaseCachedChannel()
417 eDebug("release cached channel (timer timeout)");
421 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
423 ePtr<eDVBAllocatedFrontend> fe;
425 if (m_cached_channel)
427 m_cached_channel_state_changed_conn.disconnect();
429 m_releaseCachedChannelTimer.stop();
432 if (allocateFrontendByIndex(fe, frontend_index))
433 return errNoFrontend;
436 ch = new eDVBChannel(this, fe);
443 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
445 ePtr<eDVBAllocatedDemux> demux;
447 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
449 m_cached_channel_state_changed_conn.disconnect();
451 m_releaseCachedChannelTimer.stop();
455 ch = new eDVBChannel(this, 0);
461 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
463 m_active_channels.push_back(active_channel(chid, ch));
464 /* emit */ m_channelAdded(ch);
468 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
471 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
473 if (i->m_channel == ch)
475 i = m_active_channels.erase(i);
486 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
488 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
492 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
494 ePtr<eDVBRegisteredFrontend> best;
497 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
500 int c = i->m_frontend->isCompatibleWith(feparm);
508 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
511 if (m_cached_channel)
513 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
514 if(channelid==cache_chan->getChannelID())
518 /* first, check if a channel is already existing. */
519 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
520 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
522 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
523 if (i->m_channel_id == channelid)
525 // eDebug("found shared channel..");
530 int *decremented_cached_channel_fe_usecount=NULL,
531 *decremented_fe_usecount=NULL;
533 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
535 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
536 if (i->m_channel_id == ignore)
538 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
539 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
540 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
541 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
542 // or 2 when the cached channel is not equal to the compared channel
543 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
545 ePtr<iDVBFrontend> fe;
546 if (!i->m_channel->getFrontend(fe))
548 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
550 if ( &(*fe) == &(*ii->m_frontend) )
553 decremented_fe_usecount = &ii->m_inuse;
554 if (channel == &(*m_cached_channel))
555 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
565 if (!decremented_cached_channel_fe_usecount)
567 if (m_cached_channel)
569 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
570 if (channel->getUseCount() == 1)
572 ePtr<iDVBFrontend> fe;
573 if (!channel->getFrontend(fe))
575 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
577 if ( &(*fe) == &(*ii->m_frontend) )
580 decremented_cached_channel_fe_usecount = &ii->m_inuse;
589 decremented_cached_channel_fe_usecount=NULL;
591 ePtr<iDVBFrontendParameters> feparm;
595 eDebug("no channel list set!");
600 if (m_list->getChannelFrontendData(channelid, feparm))
602 eDebug("channel not found!");
607 ret = canAllocateFrontend(feparm);
610 if (decremented_fe_usecount)
611 ++(*decremented_fe_usecount);
612 if (decremented_cached_channel_fe_usecount)
613 ++(*decremented_cached_channel_fe_usecount);
618 DEFINE_REF(eDVBChannel);
620 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
622 m_frontend = frontend;
626 m_skipmode_n = m_skipmode_m = 0;
629 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
632 eDVBChannel::~eDVBChannel()
635 m_mgr->removeChannel(this);
640 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
642 int state, ourstate = 0;
644 /* if we are already in shutdown, don't change state. */
645 if (m_state == state_release)
648 if (fe->getState(state))
651 if (state == iDVBFrontend::stateLock)
653 eDebug("OURSTATE: ok");
655 } else if (state == iDVBFrontend::stateTuning)
657 eDebug("OURSTATE: tuning");
658 ourstate = state_tuning;
659 } else if (state == iDVBFrontend::stateLostLock)
661 /* on managed channels, we try to retune in order to re-acquire lock. */
662 if (m_current_frontend_parameters)
664 eDebug("OURSTATE: lost lock, trying to retune");
665 ourstate = state_tuning;
666 m_frontend->get().tune(*m_current_frontend_parameters);
668 /* on unmanaged channels, we don't do this. the client will do this. */
670 eDebug("OURSTATE: lost lock, unavailable now.");
671 ourstate = state_unavailable;
673 } else if (state == iDVBFrontend::stateFailed)
675 eDebug("OURSTATE: failed");
676 ourstate = state_failed;
678 eFatal("state unknown");
680 if (ourstate != m_state)
683 m_stateChanged(this);
687 void eDVBChannel::pvrEvent(int event)
691 case eFilePushThread::evtEOF:
692 eDebug("eDVBChannel: End of file!");
693 m_event(this, evtEOF);
695 case eFilePushThread::evtUser: /* start */
697 m_event(this, evtSOF);
702 void eDVBChannel::cueSheetEvent(int event)
706 case eCueSheet::evtSeek:
708 flushPVR(m_cue->m_decoding_demux);
710 case eCueSheet::evtSkipmode:
713 eSingleLocker l(m_cue->m_lock);
714 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
715 if (m_cue->m_skipmode_ratio)
717 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
718 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
719 /* i agree that this might look a bit like black magic. */
720 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
721 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
723 if (m_cue->m_skipmode_ratio < 0)
724 m_skipmode_m -= m_skipmode_n;
726 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
728 if (abs(m_skipmode_m) < abs(m_skipmode_n))
730 eWarning("something is wrong with this calculation");
731 m_skipmode_n = m_skipmode_m = 0;
736 eDebug("skipmode ratio is 0, normal play");
737 m_skipmode_n = m_skipmode_m = 0;
740 flushPVR(m_cue->m_decoding_demux);
743 case eCueSheet::evtSpanChanged:
745 m_source_span.clear();
746 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
748 off_t offset_in, offset_out;
749 pts_t pts_in = i->first, pts_out = i->second;
750 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
752 eDebug("span translation failed.\n");
755 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
756 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
763 /* remember, this gets called from another thread. */
764 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
766 unsigned int max = 10*1024*1024;
770 eDebug("no cue sheet. forcing normal play");
771 start = current_offset;
776 eSingleLocker l(m_cue->m_lock);
778 if (!m_cue->m_decoding_demux)
780 start = current_offset;
782 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
788 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
792 eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
794 current_offset += m_skipmode_m;
796 while (!m_cue->m_seek_requests.empty())
798 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
799 m_cue->m_seek_requests.pop_front();
800 int relative = seek.first;
801 pts_t pts = seek.second;
806 if (!m_cue->m_decoder)
808 eDebug("no decoder - can't seek relative");
811 if (m_cue->m_decoder->getPTS(0, now))
813 eDebug("decoder getPTS failed, can't seek relative");
816 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
818 eDebug("seekTo: getCurrentPosition failed!");
823 if (relative == 1) /* pts relative */
834 if (relative == 2) /* AP relative */
836 eDebug("AP relative seeking: %lld, at %lld", pts, now);
838 if (m_tstools.getNextAccessPoint(nextap, now, pts))
841 eDebug("AP relative seeking failed!");
844 eDebug("next ap is %llx\n", pts);
850 if (m_tstools.getOffset(offset, pts))
853 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
854 current_offset = offset;
857 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
859 if ((current_offset >= i->first) && (current_offset < i->second))
861 start = current_offset;
862 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
863 if ((i->second - current_offset) > max)
866 size = i->second - current_offset;
867 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
870 if (current_offset < i->first)
872 /* ok, our current offset is in an 'out' zone. */
873 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
875 /* in normal playback, just start at the next zone. */
878 /* size is not 64bit! */
879 if ((i->second - i->first) > max)
882 size = i->second - i->first;
885 if (m_skipmode_m < 0)
887 eDebug("reached SOF");
890 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
894 /* when skipping reverse, however, choose the zone before. */
896 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
899 if ((i->second - i->first) > max)
902 len = i->second - i->first;
904 start = i->second - len;
905 eDebug("skipping to %llx, %d", start, len);
911 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
913 eDebug("reached SOF");
915 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
918 start = current_offset;
920 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
924 void eDVBChannel::AddUse()
926 if (++m_use_count > 1 && m_state == state_last_instance)
929 m_stateChanged(this);
933 void eDVBChannel::ReleaseUse()
937 m_state = state_release;
938 m_stateChanged(this);
940 else if (m_use_count == 1)
942 m_state = state_last_instance;
943 m_stateChanged(this);
947 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
950 m_mgr->removeChannel(this);
957 eDebug("no frontend to tune!");
961 m_channel_id = channelid;
962 m_mgr->addChannel(channelid, this);
963 m_state = state_tuning;
964 /* if tuning fails, shutdown the channel immediately. */
966 res = m_frontend->get().tune(*feparm);
967 m_current_frontend_parameters = feparm;
971 m_state = state_release;
972 m_stateChanged(this);
979 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
981 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
985 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
987 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
991 RESULT eDVBChannel::getState(int &state)
997 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1002 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1004 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1010 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1015 /* don't hold a reference to the decoding demux, we don't need it. */
1017 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1018 the refcount is lost. thus, decoding demuxes are never allocated.
1020 this poses a big problem for PiP. */
1021 if (cap & capDecode)
1026 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1031 frontend = &m_frontend->get();
1037 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1039 param = m_current_frontend_parameters;
1043 RESULT eDVBChannel::playFile(const char *file)
1045 ASSERT(!m_frontend);
1048 m_pvr_thread->stop();
1049 delete m_pvr_thread;
1053 m_tstools.openFile(file);
1055 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1056 THEN DO A REAL FIX HERE! */
1058 /* (this codepath needs to be improved anyway.) */
1059 #if HAVE_DVB_API_VERSION < 3
1060 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1062 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1064 if (m_pvr_fd_dst < 0)
1066 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1070 m_pvr_thread = new eFilePushThread();
1071 m_pvr_thread->enablePVRCommit(1);
1072 m_pvr_thread->setScatterGather(this);
1074 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1076 delete m_pvr_thread;
1078 eDebug("can't open PVR file %s (%m)", file);
1081 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1084 m_stateChanged(this);
1089 void eDVBChannel::stopFile()
1093 m_pvr_thread->stop();
1094 ::close(m_pvr_fd_dst);
1095 delete m_pvr_thread;
1100 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1102 m_conn_cueSheetEvent = 0;
1105 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1108 RESULT eDVBChannel::getLength(pts_t &len)
1110 return m_tstools.calcLen(len);
1113 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1115 if (!decoding_demux)
1122 if (mode == 0) /* demux */
1124 r = decoding_demux->getSTC(now, 0);
1127 eDebug("demux getSTC failed");
1131 now = pos; /* fixup supplied */
1133 off_t off = 0; /* TODO: fixme */
1134 r = m_tstools.fixupPTS(off, now);
1137 eDebug("fixup PTS failed");
1146 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1148 /* when seeking, we have to ensure that all buffers are flushed.
1149 there are basically 3 buffers:
1150 a.) the filepush's internal buffer
1151 b.) the PVR buffer (before demux)
1152 c.) the ratebuffer (after demux)
1154 it's important to clear them in the correct order, otherwise
1155 the ratebuffer (for example) would immediately refill from
1156 the not-yet-flushed PVR buffer.
1159 m_pvr_thread->pause();
1160 /* flush internal filepush buffer */
1161 m_pvr_thread->flush();
1162 /* HACK: flush PVR buffer */
1163 ::ioctl(m_pvr_fd_dst, 0);
1165 /* flush ratebuffers (video, audio) */
1167 decoding_demux->flush();
1169 /* demux will also flush all decoder.. */
1170 /* resume will re-query the SG */
1171 m_pvr_thread->resume();
1174 DEFINE_REF(eCueSheet);
1176 eCueSheet::eCueSheet()
1178 m_skipmode_ratio = 0;
1181 void eCueSheet::seekTo(int relative, const pts_t &pts)
1184 eSingleLock l(m_lock);
1185 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1190 void eCueSheet::clear()
1192 eSingleLock l(m_lock);
1196 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1199 eSingleLock l(m_lock);
1200 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1204 void eCueSheet::commitSpans()
1206 m_event(evtSpanChanged);
1209 void eCueSheet::setSkipmode(const pts_t &ratio)
1212 eSingleLock l(m_lock);
1213 m_skipmode_ratio = ratio;
1215 m_event(evtSkipmode);
1218 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1220 m_decoding_demux = demux;
1221 m_decoder = decoder;
1224 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1226 connection = new eConnection(this, m_event.connect(event));