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);
81 void eDVBResourceManager::feStateChanged()
84 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
86 mask |= ( 1 << i->m_frontend->getID() );
87 /* emit */ frontendUseMaskChanged(mask);
90 DEFINE_REF(eDVBAdapterLinux);
91 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
96 eDebug("scanning for frontends..");
101 #if HAVE_DVB_API_VERSION < 3
102 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
104 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
106 if (stat(filename, &s))
108 ePtr<eDVBFrontend> fe;
111 fe = new eDVBFrontend(m_nr, num_fe, ok);
113 m_frontend.push_back(fe);
123 #if HAVE_DVB_API_VERSION < 3
124 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
126 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
128 if (stat(filename, &s))
130 ePtr<eDVBDemux> demux;
132 demux = new eDVBDemux(m_nr, num_demux);
133 m_demux.push_back(demux);
139 int eDVBAdapterLinux::getNumDemux()
141 return m_demux.size();
144 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
146 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
147 while (nr && (i != m_demux.end()))
153 if (i != m_demux.end())
161 int eDVBAdapterLinux::getNumFrontends()
163 return m_frontend.size();
166 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
168 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
169 while (nr && (i != m_frontend.end()))
175 if (i != m_frontend.end())
183 int eDVBAdapterLinux::exist(int nr)
187 #if HAVE_DVB_API_VERSION < 3
188 sprintf(filename, "/dev/dvb/card%d", nr);
190 sprintf(filename, "/dev/dvb/adapter%d", nr);
192 if (!stat(filename, &s))
197 eDVBResourceManager::~eDVBResourceManager()
199 if (instance == this)
203 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
205 int num_fe = adapter->getNumFrontends();
206 int num_demux = adapter->getNumDemux();
208 m_adapter.push_back(adapter);
211 for (i=0; i<num_demux; ++i)
213 ePtr<eDVBDemux> demux;
214 if (!adapter->getDemux(demux, i))
215 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
218 for (i=0; i<num_fe; ++i)
220 ePtr<eDVBFrontend> frontend;
222 if (!adapter->getFrontend(frontend, i))
224 frontend->setSEC(m_sec);
225 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
226 CONNECT(m_frontend.back()->stateChanged, eDVBResourceManager::feStateChanged);
231 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
233 ePtr<eDVBRegisteredFrontend> best;
236 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
239 int c = i->m_frontend->isCompatibleWith(feparm);
249 fe = new eDVBAllocatedFrontend(best);
258 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
260 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
261 if ((!nr) && !i->m_inuse)
263 fe = new eDVBAllocatedFrontend(i);
271 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
273 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
274 never use the first one unless we need a decoding demux. */
276 eDebug("allocate demux");
277 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
279 if (i == m_demux.end())
283 /* FIXME: hardware demux policy */
284 if (!(cap & iDVBChannel::capDecode))
286 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
293 for (; i != m_demux.end(); ++i, ++n)
295 int is_decode = n < 2;
297 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
299 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
301 if ((cap & iDVBChannel::capDecode) && !is_decode)
304 demux = new eDVBAllocatedDemux(i);
306 demux->get().setSourceFrontend(fe->m_frontend->getID());
308 demux->get().setSourcePVR(0);
312 eDebug("demux not found");
316 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
322 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
331 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
333 /* first, check if a channel is already existing. */
335 if (m_cached_channel)
337 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
338 if(channelid==cache_chan->getChannelID())
340 eDebug("use cached_channel");
341 channel = m_cached_channel;
344 m_cached_channel_state_changed_conn.disconnect();
346 m_releaseCachedChannelTimer.stop();
349 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
350 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
352 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
353 if (i->m_channel_id == channelid)
355 // eDebug("found shared channel..");
356 channel = i->m_channel;
361 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
365 eDebug("no channel list set!");
369 ePtr<iDVBFrontendParameters> feparm;
370 if (m_list->getChannelFrontendData(channelid, feparm))
372 eDebug("channel not found!");
376 /* allocate a frontend. */
378 ePtr<eDVBAllocatedFrontend> fe;
380 if (allocateFrontend(fe, feparm))
381 return errNoFrontend;
384 ePtr<eDVBChannel> ch;
385 ch = new eDVBChannel(this, fe);
387 res = ch->setChannel(channelid, feparm);
391 return errChidNotFound;
393 m_cached_channel = channel = ch;
394 m_cached_channel_state_changed_conn =
395 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
400 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
403 chan->getState(state);
406 case iDVBChannel::state_release:
407 case iDVBChannel::state_ok:
409 eDebug("stop release channel timer");
410 m_releaseCachedChannelTimer.stop();
413 case iDVBChannel::state_last_instance:
415 eDebug("start release channel timer");
416 m_releaseCachedChannelTimer.start(3000, true);
419 default: // ignore all other events
424 void eDVBResourceManager::releaseCachedChannel()
426 eDebug("release cached channel (timer timeout)");
430 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
432 ePtr<eDVBAllocatedFrontend> fe;
434 if (m_cached_channel)
436 m_cached_channel_state_changed_conn.disconnect();
438 m_releaseCachedChannelTimer.stop();
441 if (allocateFrontendByIndex(fe, frontend_index))
442 return errNoFrontend;
445 ch = new eDVBChannel(this, fe);
452 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
454 ePtr<eDVBAllocatedDemux> demux;
456 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
458 m_cached_channel_state_changed_conn.disconnect();
460 m_releaseCachedChannelTimer.stop();
464 ch = new eDVBChannel(this, 0);
470 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
472 m_active_channels.push_back(active_channel(chid, ch));
473 /* emit */ m_channelAdded(ch);
477 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
480 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
482 if (i->m_channel == ch)
484 i = m_active_channels.erase(i);
495 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
497 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
501 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
503 ePtr<eDVBRegisteredFrontend> best;
506 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
509 int c = i->m_frontend->isCompatibleWith(feparm);
517 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
520 if (m_cached_channel)
522 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
523 if(channelid==cache_chan->getChannelID())
527 /* first, check if a channel is already existing. */
528 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
529 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
531 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
532 if (i->m_channel_id == channelid)
534 // eDebug("found shared channel..");
539 int *decremented_cached_channel_fe_usecount=NULL,
540 *decremented_fe_usecount=NULL;
542 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
544 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
545 if (i->m_channel_id == ignore)
547 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
548 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
549 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
550 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
551 // or 2 when the cached channel is not equal to the compared channel
552 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
554 ePtr<iDVBFrontend> fe;
555 if (!i->m_channel->getFrontend(fe))
557 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
559 if ( &(*fe) == &(*ii->m_frontend) )
562 decremented_fe_usecount = &ii->m_inuse;
563 if (channel == &(*m_cached_channel))
564 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
574 if (!decremented_cached_channel_fe_usecount)
576 if (m_cached_channel)
578 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
579 if (channel->getUseCount() == 1)
581 ePtr<iDVBFrontend> fe;
582 if (!channel->getFrontend(fe))
584 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
586 if ( &(*fe) == &(*ii->m_frontend) )
589 decremented_cached_channel_fe_usecount = &ii->m_inuse;
598 decremented_cached_channel_fe_usecount=NULL;
600 ePtr<iDVBFrontendParameters> feparm;
604 eDebug("no channel list set!");
609 if (m_list->getChannelFrontendData(channelid, feparm))
611 eDebug("channel not found!");
616 ret = canAllocateFrontend(feparm);
619 if (decremented_fe_usecount)
620 ++(*decremented_fe_usecount);
621 if (decremented_cached_channel_fe_usecount)
622 ++(*decremented_cached_channel_fe_usecount);
627 DEFINE_REF(eDVBChannel);
629 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
631 m_frontend = frontend;
635 m_skipmode_n = m_skipmode_m = 0;
638 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
641 eDVBChannel::~eDVBChannel()
644 m_mgr->removeChannel(this);
649 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
651 int state, ourstate = 0;
653 /* if we are already in shutdown, don't change state. */
654 if (m_state == state_release)
657 if (fe->getState(state))
660 if (state == iDVBFrontend::stateLock)
662 eDebug("OURSTATE: ok");
664 } else if (state == iDVBFrontend::stateTuning)
666 eDebug("OURSTATE: tuning");
667 ourstate = state_tuning;
668 } else if (state == iDVBFrontend::stateLostLock)
670 /* on managed channels, we try to retune in order to re-acquire lock. */
671 if (m_current_frontend_parameters)
673 eDebug("OURSTATE: lost lock, trying to retune");
674 ourstate = state_tuning;
675 m_frontend->get().tune(*m_current_frontend_parameters);
677 /* on unmanaged channels, we don't do this. the client will do this. */
679 eDebug("OURSTATE: lost lock, unavailable now.");
680 ourstate = state_unavailable;
682 } else if (state == iDVBFrontend::stateFailed)
684 eDebug("OURSTATE: failed");
685 ourstate = state_failed;
687 eFatal("state unknown");
689 if (ourstate != m_state)
692 m_stateChanged(this);
696 void eDVBChannel::pvrEvent(int event)
700 case eFilePushThread::evtEOF:
701 eDebug("eDVBChannel: End of file!");
702 m_event(this, evtEOF);
704 case eFilePushThread::evtUser: /* start */
706 m_event(this, evtSOF);
711 void eDVBChannel::cueSheetEvent(int event)
715 case eCueSheet::evtSeek:
717 flushPVR(m_cue->m_decoding_demux);
719 case eCueSheet::evtSkipmode:
722 eSingleLocker l(m_cue->m_lock);
723 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
724 if (m_cue->m_skipmode_ratio)
726 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
727 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
728 /* i agree that this might look a bit like black magic. */
729 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
730 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
732 if (m_cue->m_skipmode_ratio < 0)
733 m_skipmode_m -= m_skipmode_n;
735 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
737 if (abs(m_skipmode_m) < abs(m_skipmode_n))
739 eWarning("something is wrong with this calculation");
740 m_skipmode_n = m_skipmode_m = 0;
745 eDebug("skipmode ratio is 0, normal play");
746 m_skipmode_n = m_skipmode_m = 0;
749 flushPVR(m_cue->m_decoding_demux);
752 case eCueSheet::evtSpanChanged:
754 m_source_span.clear();
755 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
757 off_t offset_in, offset_out;
758 pts_t pts_in = i->first, pts_out = i->second;
759 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
761 eDebug("span translation failed.\n");
764 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
765 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
772 /* remember, this gets called from another thread. */
773 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
775 unsigned int max = 10*1024*1024;
779 eDebug("no cue sheet. forcing normal play");
780 start = current_offset;
785 eSingleLocker l(m_cue->m_lock);
787 if (!m_cue->m_decoding_demux)
789 start = current_offset;
791 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
797 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
801 eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
803 current_offset += m_skipmode_m;
805 while (!m_cue->m_seek_requests.empty())
807 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
808 m_cue->m_seek_requests.pop_front();
809 int relative = seek.first;
810 pts_t pts = seek.second;
815 if (!m_cue->m_decoder)
817 eDebug("no decoder - can't seek relative");
820 if (m_cue->m_decoder->getPTS(0, now))
822 eDebug("decoder getPTS failed, can't seek relative");
825 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
827 eDebug("seekTo: getCurrentPosition failed!");
832 if (relative == 1) /* pts relative */
843 if (relative == 2) /* AP relative */
845 eDebug("AP relative seeking: %lld, at %lld", pts, now);
847 if (m_tstools.getNextAccessPoint(nextap, now, pts))
850 eDebug("AP relative seeking failed!");
853 eDebug("next ap is %llx\n", pts);
859 if (m_tstools.getOffset(offset, pts))
862 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
863 current_offset = offset;
866 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
868 if ((current_offset >= i->first) && (current_offset < i->second))
870 start = current_offset;
871 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
872 if ((i->second - current_offset) > max)
875 size = i->second - current_offset;
876 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
879 if (current_offset < i->first)
881 /* ok, our current offset is in an 'out' zone. */
882 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
884 /* in normal playback, just start at the next zone. */
887 /* size is not 64bit! */
888 if ((i->second - i->first) > max)
891 size = i->second - i->first;
894 if (m_skipmode_m < 0)
896 eDebug("reached SOF");
899 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
903 /* when skipping reverse, however, choose the zone before. */
905 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
908 if ((i->second - i->first) > max)
911 len = i->second - i->first;
913 start = i->second - len;
914 eDebug("skipping to %llx, %d", start, len);
920 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
922 eDebug("reached SOF");
924 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
927 start = current_offset;
929 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
933 void eDVBChannel::AddUse()
935 if (++m_use_count > 1 && m_state == state_last_instance)
938 m_stateChanged(this);
942 void eDVBChannel::ReleaseUse()
946 m_state = state_release;
947 m_stateChanged(this);
949 else if (m_use_count == 1)
951 m_state = state_last_instance;
952 m_stateChanged(this);
956 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
959 m_mgr->removeChannel(this);
966 eDebug("no frontend to tune!");
970 m_channel_id = channelid;
971 m_mgr->addChannel(channelid, this);
972 m_state = state_tuning;
973 /* if tuning fails, shutdown the channel immediately. */
975 res = m_frontend->get().tune(*feparm);
976 m_current_frontend_parameters = feparm;
980 m_state = state_release;
981 m_stateChanged(this);
988 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
990 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
994 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
996 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1000 RESULT eDVBChannel::getState(int &state)
1006 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1011 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1013 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1019 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1024 /* don't hold a reference to the decoding demux, we don't need it. */
1026 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1027 the refcount is lost. thus, decoding demuxes are never allocated.
1029 this poses a big problem for PiP. */
1030 if (cap & capDecode)
1035 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1040 frontend = &m_frontend->get();
1046 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1048 param = m_current_frontend_parameters;
1052 RESULT eDVBChannel::playFile(const char *file)
1054 ASSERT(!m_frontend);
1057 m_pvr_thread->stop();
1058 delete m_pvr_thread;
1062 m_tstools.openFile(file);
1064 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1065 THEN DO A REAL FIX HERE! */
1067 /* (this codepath needs to be improved anyway.) */
1068 #if HAVE_DVB_API_VERSION < 3
1069 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1071 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1073 if (m_pvr_fd_dst < 0)
1075 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1079 m_pvr_thread = new eFilePushThread();
1080 m_pvr_thread->enablePVRCommit(1);
1081 m_pvr_thread->setScatterGather(this);
1083 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1085 delete m_pvr_thread;
1087 eDebug("can't open PVR file %s (%m)", file);
1090 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1093 m_stateChanged(this);
1098 void eDVBChannel::stopFile()
1102 m_pvr_thread->stop();
1103 ::close(m_pvr_fd_dst);
1104 delete m_pvr_thread;
1109 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1111 m_conn_cueSheetEvent = 0;
1114 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1117 RESULT eDVBChannel::getLength(pts_t &len)
1119 return m_tstools.calcLen(len);
1122 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1124 if (!decoding_demux)
1131 if (mode == 0) /* demux */
1133 r = decoding_demux->getSTC(now, 0);
1136 eDebug("demux getSTC failed");
1140 now = pos; /* fixup supplied */
1142 off_t off = 0; /* TODO: fixme */
1143 r = m_tstools.fixupPTS(off, now);
1146 eDebug("fixup PTS failed");
1155 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1157 /* when seeking, we have to ensure that all buffers are flushed.
1158 there are basically 3 buffers:
1159 a.) the filepush's internal buffer
1160 b.) the PVR buffer (before demux)
1161 c.) the ratebuffer (after demux)
1163 it's important to clear them in the correct order, otherwise
1164 the ratebuffer (for example) would immediately refill from
1165 the not-yet-flushed PVR buffer.
1168 m_pvr_thread->pause();
1169 /* flush internal filepush buffer */
1170 m_pvr_thread->flush();
1171 /* HACK: flush PVR buffer */
1172 ::ioctl(m_pvr_fd_dst, 0);
1174 /* flush ratebuffers (video, audio) */
1176 decoding_demux->flush();
1178 /* demux will also flush all decoder.. */
1179 /* resume will re-query the SG */
1180 m_pvr_thread->resume();
1183 DEFINE_REF(eCueSheet);
1185 eCueSheet::eCueSheet()
1187 m_skipmode_ratio = 0;
1190 void eCueSheet::seekTo(int relative, const pts_t &pts)
1193 eSingleLock l(m_lock);
1194 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1199 void eCueSheet::clear()
1201 eSingleLock l(m_lock);
1205 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1208 eSingleLock l(m_lock);
1209 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1213 void eCueSheet::commitSpans()
1215 m_event(evtSpanChanged);
1218 void eCueSheet::setSkipmode(const pts_t &ratio)
1221 eSingleLock l(m_lock);
1222 m_skipmode_ratio = ratio;
1224 m_event(evtSkipmode);
1227 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1229 m_decoding_demux = demux;
1230 m_decoder = decoder;
1233 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1235 connection = new eConnection(this, m_event.connect(event));