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 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
541 ePtr<iDVBFrontend> fe;
542 if (!i->m_channel->getFrontend(fe))
544 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
546 if ( &(*fe) == &(*ii->m_frontend) )
549 decremented_fe_usecount = &ii->m_inuse;
550 if (channel == &(*m_cached_channel))
551 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
561 if (!decremented_cached_channel_fe_usecount)
563 if (m_cached_channel)
565 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
566 if (channel->getUseCount() == 1)
568 ePtr<iDVBFrontend> fe;
569 if (!channel->getFrontend(fe))
571 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
573 if ( &(*fe) == &(*ii->m_frontend) )
576 decremented_cached_channel_fe_usecount = &ii->m_inuse;
585 decremented_cached_channel_fe_usecount=NULL;
587 ePtr<iDVBFrontendParameters> feparm;
591 eDebug("no channel list set!");
596 if (m_list->getChannelFrontendData(channelid, feparm))
598 eDebug("channel not found!");
603 ret = canAllocateFrontend(feparm);
606 if (decremented_fe_usecount)
607 ++(*decremented_fe_usecount);
608 if (decremented_cached_channel_fe_usecount)
609 ++(*decremented_cached_channel_fe_usecount);
614 DEFINE_REF(eDVBChannel);
616 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
618 m_frontend = frontend;
622 m_skipmode_n = m_skipmode_m = 0;
625 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
628 eDVBChannel::~eDVBChannel()
631 m_mgr->removeChannel(this);
636 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
638 int state, ourstate = 0;
640 /* if we are already in shutdown, don't change state. */
641 if (m_state == state_release)
644 if (fe->getState(state))
647 if (state == iDVBFrontend::stateLock)
649 eDebug("OURSTATE: ok");
651 } else if (state == iDVBFrontend::stateTuning)
653 eDebug("OURSTATE: tuning");
654 ourstate = state_tuning;
655 } else if (state == iDVBFrontend::stateLostLock)
657 /* on managed channels, we try to retune in order to re-acquire lock. */
658 if (m_current_frontend_parameters)
660 eDebug("OURSTATE: lost lock, trying to retune");
661 ourstate = state_tuning;
662 m_frontend->get().tune(*m_current_frontend_parameters);
664 /* on unmanaged channels, we don't do this. the client will do this. */
666 eDebug("OURSTATE: lost lock, unavailable now.");
667 ourstate = state_unavailable;
669 } else if (state == iDVBFrontend::stateFailed)
671 eDebug("OURSTATE: failed");
672 ourstate = state_failed;
674 eFatal("state unknown");
676 if (ourstate != m_state)
679 m_stateChanged(this);
683 void eDVBChannel::pvrEvent(int event)
687 case eFilePushThread::evtEOF:
688 eDebug("eDVBChannel: End of file!");
689 m_event(this, evtEOF);
691 case eFilePushThread::evtUser: /* start */
693 m_event(this, evtSOF);
698 void eDVBChannel::cueSheetEvent(int event)
702 case eCueSheet::evtSeek:
704 flushPVR(m_cue->m_decoding_demux);
706 case eCueSheet::evtSkipmode:
709 eSingleLocker l(m_cue->m_lock);
710 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
711 if (m_cue->m_skipmode_ratio)
713 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
714 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
715 /* i agree that this might look a bit like black magic. */
716 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
717 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
719 if (m_cue->m_skipmode_ratio < 0)
720 m_skipmode_m -= m_skipmode_n;
722 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
724 if (abs(m_skipmode_m) < abs(m_skipmode_n))
726 eWarning("something is wrong with this calculation");
727 m_skipmode_n = m_skipmode_m = 0;
732 eDebug("skipmode ratio is 0, normal play");
733 m_skipmode_n = m_skipmode_m = 0;
736 flushPVR(m_cue->m_decoding_demux);
739 case eCueSheet::evtSpanChanged:
741 m_source_span.clear();
742 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
744 off_t offset_in, offset_out;
745 pts_t pts_in = i->first, pts_out = i->second;
746 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
748 eDebug("span translation failed.\n");
751 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
752 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
759 /* remember, this gets called from another thread. */
760 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
762 unsigned int max = 10*1024*1024;
766 eDebug("no cue sheet. forcing normal play");
767 start = current_offset;
772 eSingleLocker l(m_cue->m_lock);
774 if (!m_cue->m_decoding_demux)
776 start = current_offset;
778 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
784 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
788 eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
790 current_offset += m_skipmode_m;
792 while (!m_cue->m_seek_requests.empty())
794 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
795 m_cue->m_seek_requests.pop_front();
796 int relative = seek.first;
797 pts_t pts = seek.second;
802 if (!m_cue->m_decoder)
804 eDebug("no decoder - can't seek relative");
807 if (m_cue->m_decoder->getPTS(0, now))
809 eDebug("decoder getPTS failed, can't seek relative");
812 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
814 eDebug("seekTo: getCurrentPosition failed!");
819 if (relative == 1) /* pts relative */
830 if (relative == 2) /* AP relative */
832 eDebug("AP relative seeking: %lld, at %lld", pts, now);
834 if (m_tstools.getNextAccessPoint(nextap, now, pts))
837 eDebug("AP relative seeking failed!");
840 eDebug("next ap is %llx\n", pts);
846 if (m_tstools.getOffset(offset, pts))
849 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
850 current_offset = offset;
853 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
855 if ((current_offset >= i->first) && (current_offset < i->second))
857 start = current_offset;
858 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
859 if ((i->second - current_offset) > max)
862 size = i->second - current_offset;
863 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
866 if (current_offset < i->first)
868 /* ok, our current offset is in an 'out' zone. */
869 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
871 /* in normal playback, just start at the next zone. */
874 /* size is not 64bit! */
875 if ((i->second - i->first) > max)
878 size = i->second - i->first;
881 if (m_skipmode_m < 0)
883 eDebug("reached SOF");
886 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
890 /* when skipping reverse, however, choose the zone before. */
892 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
895 if ((i->second - i->first) > max)
898 len = i->second - i->first;
900 start = i->second - len;
901 eDebug("skipping to %llx, %d", start, len);
907 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
909 eDebug("reached SOF");
911 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
914 start = current_offset;
916 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
920 void eDVBChannel::AddUse()
922 if (++m_use_count > 1 && m_state == state_last_instance)
925 m_stateChanged(this);
929 void eDVBChannel::ReleaseUse()
933 m_state = state_release;
934 m_stateChanged(this);
936 else if (m_use_count == 1)
938 m_state = state_last_instance;
939 m_stateChanged(this);
943 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
946 m_mgr->removeChannel(this);
953 eDebug("no frontend to tune!");
957 m_channel_id = channelid;
958 m_mgr->addChannel(channelid, this);
959 m_state = state_tuning;
960 /* if tuning fails, shutdown the channel immediately. */
962 res = m_frontend->get().tune(*feparm);
963 m_current_frontend_parameters = feparm;
967 m_state = state_release;
968 m_stateChanged(this);
975 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
977 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
981 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
983 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
987 RESULT eDVBChannel::getState(int &state)
993 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
998 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1000 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1006 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1011 /* don't hold a reference to the decoding demux, we don't need it. */
1013 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1014 the refcount is lost. thus, decoding demuxes are never allocated.
1016 this poses a big problem for PiP. */
1017 if (cap & capDecode)
1022 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1027 frontend = &m_frontend->get();
1033 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1035 param = m_current_frontend_parameters;
1039 RESULT eDVBChannel::playFile(const char *file)
1041 ASSERT(!m_frontend);
1044 m_pvr_thread->stop();
1045 delete m_pvr_thread;
1049 m_tstools.openFile(file);
1051 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1052 THEN DO A REAL FIX HERE! */
1054 /* (this codepath needs to be improved anyway.) */
1055 #if HAVE_DVB_API_VERSION < 3
1056 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1058 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1060 if (m_pvr_fd_dst < 0)
1062 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1066 m_pvr_thread = new eFilePushThread();
1067 m_pvr_thread->enablePVRCommit(1);
1068 m_pvr_thread->setScatterGather(this);
1070 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1072 delete m_pvr_thread;
1074 eDebug("can't open PVR file %s (%m)", file);
1077 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1080 m_stateChanged(this);
1085 void eDVBChannel::stopFile()
1089 m_pvr_thread->stop();
1090 ::close(m_pvr_fd_dst);
1091 delete m_pvr_thread;
1096 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1098 m_conn_cueSheetEvent = 0;
1101 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1104 RESULT eDVBChannel::getLength(pts_t &len)
1106 return m_tstools.calcLen(len);
1109 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1111 if (!decoding_demux)
1118 if (mode == 0) /* demux */
1120 r = decoding_demux->getSTC(now, 0);
1123 eDebug("demux getSTC failed");
1127 now = pos; /* fixup supplied */
1129 off_t off = 0; /* TODO: fixme */
1130 r = m_tstools.fixupPTS(off, now);
1133 eDebug("fixup PTS failed");
1142 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1144 /* when seeking, we have to ensure that all buffers are flushed.
1145 there are basically 3 buffers:
1146 a.) the filepush's internal buffer
1147 b.) the PVR buffer (before demux)
1148 c.) the ratebuffer (after demux)
1150 it's important to clear them in the correct order, otherwise
1151 the ratebuffer (for example) would immediately refill from
1152 the not-yet-flushed PVR buffer.
1155 m_pvr_thread->pause();
1156 /* flush internal filepush buffer */
1157 m_pvr_thread->flush();
1158 /* HACK: flush PVR buffer */
1159 ::ioctl(m_pvr_fd_dst, 0);
1161 /* flush ratebuffers (video, audio) */
1163 decoding_demux->flush();
1165 /* demux will also flush all decoder.. */
1166 /* resume will re-query the SG */
1167 m_pvr_thread->resume();
1170 DEFINE_REF(eCueSheet);
1172 eCueSheet::eCueSheet()
1174 m_skipmode_ratio = 0;
1177 void eCueSheet::seekTo(int relative, const pts_t &pts)
1180 eSingleLock l(m_lock);
1181 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1186 void eCueSheet::clear()
1188 eSingleLock l(m_lock);
1192 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1195 eSingleLock l(m_lock);
1196 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1200 void eCueSheet::commitSpans()
1202 m_event(evtSpanChanged);
1205 void eCueSheet::setSkipmode(const pts_t &ratio)
1208 eSingleLock l(m_lock);
1209 m_skipmode_ratio = ratio;
1211 m_event(evtSkipmode);
1214 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1216 m_decoding_demux = demux;
1217 m_decoder = decoder;
1220 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1222 connection = new eConnection(this, m_event.connect(event));