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 ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
219 for (i=0; i<num_fe; ++i)
221 ePtr<eDVBFrontend> frontend;
222 if (!adapter->getFrontend(frontend, i))
225 frontend->getFrontendType(frontendType);
226 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
227 CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
228 m_frontend.push_back(new_fe);
229 frontend->setSEC(m_sec);
230 // we must link all dvb-t frontends ( for active antenna voltage )
231 if (frontendType == iDVBFrontend::feTerrestrial)
233 if (prev_dvbt_frontend)
235 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (int)new_fe);
236 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (int)&(*prev_dvbt_frontend));
238 prev_dvbt_frontend = new_fe;
244 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
246 ePtr<eDVBRegisteredFrontend> best;
249 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
252 int c = i->m_frontend->isCompatibleWith(feparm);
262 fe = new eDVBAllocatedFrontend(best);
271 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
273 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
274 if ((!nr) && !i->m_inuse)
276 fe = new eDVBAllocatedFrontend(i);
284 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
286 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
287 never use the first one unless we need a decoding demux. */
289 eDebug("allocate demux");
290 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
292 if (i == m_demux.end())
296 /* FIXME: hardware demux policy */
297 if (!(cap & iDVBChannel::capDecode))
299 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
306 for (; i != m_demux.end(); ++i, ++n)
308 int is_decode = n < 2;
310 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
312 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
314 if ((cap & iDVBChannel::capDecode) && !is_decode)
317 demux = new eDVBAllocatedDemux(i);
319 demux->get().setSourceFrontend(fe->m_frontend->getID());
321 demux->get().setSourcePVR(0);
325 eDebug("demux not found");
329 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
335 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
344 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
346 /* first, check if a channel is already existing. */
348 if (m_cached_channel)
350 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
351 if(channelid==cache_chan->getChannelID())
353 eDebug("use cached_channel");
354 channel = m_cached_channel;
357 m_cached_channel_state_changed_conn.disconnect();
359 m_releaseCachedChannelTimer.stop();
362 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
363 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
365 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
366 if (i->m_channel_id == channelid)
368 // eDebug("found shared channel..");
369 channel = i->m_channel;
374 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
378 eDebug("no channel list set!");
382 ePtr<iDVBFrontendParameters> feparm;
383 if (m_list->getChannelFrontendData(channelid, feparm))
385 eDebug("channel not found!");
389 /* allocate a frontend. */
391 ePtr<eDVBAllocatedFrontend> fe;
393 if (allocateFrontend(fe, feparm))
394 return errNoFrontend;
397 ePtr<eDVBChannel> ch;
398 ch = new eDVBChannel(this, fe);
400 res = ch->setChannel(channelid, feparm);
404 return errChidNotFound;
406 m_cached_channel = channel = ch;
407 m_cached_channel_state_changed_conn =
408 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
413 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
416 chan->getState(state);
419 case iDVBChannel::state_release:
420 case iDVBChannel::state_ok:
422 eDebug("stop release channel timer");
423 m_releaseCachedChannelTimer.stop();
426 case iDVBChannel::state_last_instance:
428 eDebug("start release channel timer");
429 m_releaseCachedChannelTimer.start(3000, true);
432 default: // ignore all other events
437 void eDVBResourceManager::releaseCachedChannel()
439 eDebug("release cached channel (timer timeout)");
443 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
445 ePtr<eDVBAllocatedFrontend> fe;
447 if (m_cached_channel)
449 m_cached_channel_state_changed_conn.disconnect();
451 m_releaseCachedChannelTimer.stop();
454 if (allocateFrontendByIndex(fe, frontend_index))
455 return errNoFrontend;
458 ch = new eDVBChannel(this, fe);
465 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
467 ePtr<eDVBAllocatedDemux> demux;
469 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
471 m_cached_channel_state_changed_conn.disconnect();
473 m_releaseCachedChannelTimer.stop();
477 ch = new eDVBChannel(this, 0);
483 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
485 m_active_channels.push_back(active_channel(chid, ch));
486 /* emit */ m_channelAdded(ch);
490 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
493 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
495 if (i->m_channel == ch)
497 i = m_active_channels.erase(i);
508 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
510 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
514 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
516 ePtr<eDVBRegisteredFrontend> best;
519 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
522 int c = i->m_frontend->isCompatibleWith(feparm);
530 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
533 if (m_cached_channel)
535 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
536 if(channelid==cache_chan->getChannelID())
540 /* first, check if a channel is already existing. */
541 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
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 == channelid)
547 // eDebug("found shared channel..");
552 int *decremented_cached_channel_fe_usecount=NULL,
553 *decremented_fe_usecount=NULL;
555 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
557 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
558 if (i->m_channel_id == ignore)
560 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
561 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
562 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
563 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
564 // or 2 when the cached channel is not equal to the compared channel
565 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
567 ePtr<iDVBFrontend> fe;
568 if (!i->m_channel->getFrontend(fe))
570 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
572 if ( &(*fe) == &(*ii->m_frontend) )
575 decremented_fe_usecount = &ii->m_inuse;
576 if (channel == &(*m_cached_channel))
577 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
587 if (!decremented_cached_channel_fe_usecount)
589 if (m_cached_channel)
591 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
592 if (channel->getUseCount() == 1)
594 ePtr<iDVBFrontend> fe;
595 if (!channel->getFrontend(fe))
597 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
599 if ( &(*fe) == &(*ii->m_frontend) )
602 decremented_cached_channel_fe_usecount = &ii->m_inuse;
611 decremented_cached_channel_fe_usecount=NULL;
613 ePtr<iDVBFrontendParameters> feparm;
617 eDebug("no channel list set!");
622 if (m_list->getChannelFrontendData(channelid, feparm))
624 eDebug("channel not found!");
629 ret = canAllocateFrontend(feparm);
632 if (decremented_fe_usecount)
633 ++(*decremented_fe_usecount);
634 if (decremented_cached_channel_fe_usecount)
635 ++(*decremented_cached_channel_fe_usecount);
640 DEFINE_REF(eDVBChannel);
642 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
644 m_frontend = frontend;
648 m_skipmode_n = m_skipmode_m = 0;
651 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
654 eDVBChannel::~eDVBChannel()
657 m_mgr->removeChannel(this);
662 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
664 int state, ourstate = 0;
666 /* if we are already in shutdown, don't change state. */
667 if (m_state == state_release)
670 if (fe->getState(state))
673 if (state == iDVBFrontend::stateLock)
675 eDebug("OURSTATE: ok");
677 } else if (state == iDVBFrontend::stateTuning)
679 eDebug("OURSTATE: tuning");
680 ourstate = state_tuning;
681 } else if (state == iDVBFrontend::stateLostLock)
683 /* on managed channels, we try to retune in order to re-acquire lock. */
684 if (m_current_frontend_parameters)
686 eDebug("OURSTATE: lost lock, trying to retune");
687 ourstate = state_tuning;
688 m_frontend->get().tune(*m_current_frontend_parameters);
690 /* on unmanaged channels, we don't do this. the client will do this. */
692 eDebug("OURSTATE: lost lock, unavailable now.");
693 ourstate = state_unavailable;
695 } else if (state == iDVBFrontend::stateFailed)
697 eDebug("OURSTATE: failed");
698 ourstate = state_failed;
700 eFatal("state unknown");
702 if (ourstate != m_state)
705 m_stateChanged(this);
709 void eDVBChannel::pvrEvent(int event)
713 case eFilePushThread::evtEOF:
714 eDebug("eDVBChannel: End of file!");
715 m_event(this, evtEOF);
717 case eFilePushThread::evtUser: /* start */
719 m_event(this, evtSOF);
724 void eDVBChannel::cueSheetEvent(int event)
728 case eCueSheet::evtSeek:
730 flushPVR(m_cue->m_decoding_demux);
732 case eCueSheet::evtSkipmode:
735 eSingleLocker l(m_cue->m_lock);
736 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
737 if (m_cue->m_skipmode_ratio)
739 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
740 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
741 /* i agree that this might look a bit like black magic. */
742 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
743 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
745 if (m_cue->m_skipmode_ratio < 0)
746 m_skipmode_m -= m_skipmode_n;
748 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
750 if (abs(m_skipmode_m) < abs(m_skipmode_n))
752 eWarning("something is wrong with this calculation");
753 m_skipmode_n = m_skipmode_m = 0;
758 eDebug("skipmode ratio is 0, normal play");
759 m_skipmode_n = m_skipmode_m = 0;
762 flushPVR(m_cue->m_decoding_demux);
765 case eCueSheet::evtSpanChanged:
767 m_source_span.clear();
768 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
770 off_t offset_in, offset_out;
771 pts_t pts_in = i->first, pts_out = i->second;
772 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
774 eDebug("span translation failed.\n");
777 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
778 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
785 /* remember, this gets called from another thread. */
786 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
788 unsigned int max = 10*1024*1024;
792 eDebug("no cue sheet. forcing normal play");
793 start = current_offset;
798 eSingleLocker l(m_cue->m_lock);
800 if (!m_cue->m_decoding_demux)
802 start = current_offset;
804 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
810 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
814 eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
816 current_offset += m_skipmode_m;
818 while (!m_cue->m_seek_requests.empty())
820 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
821 m_cue->m_seek_requests.pop_front();
822 int relative = seek.first;
823 pts_t pts = seek.second;
828 if (!m_cue->m_decoder)
830 eDebug("no decoder - can't seek relative");
833 if (m_cue->m_decoder->getPTS(0, now))
835 eDebug("decoder getPTS failed, can't seek relative");
838 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
840 eDebug("seekTo: getCurrentPosition failed!");
845 if (relative == 1) /* pts relative */
856 if (relative == 2) /* AP relative */
858 eDebug("AP relative seeking: %lld, at %lld", pts, now);
860 if (m_tstools.getNextAccessPoint(nextap, now, pts))
863 eDebug("AP relative seeking failed!");
866 eDebug("next ap is %llx\n", pts);
872 if (m_tstools.getOffset(offset, pts))
875 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
876 current_offset = offset;
879 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
881 if ((current_offset >= i->first) && (current_offset < i->second))
883 start = current_offset;
884 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
885 if ((i->second - current_offset) > max)
888 size = i->second - current_offset;
889 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
892 if (current_offset < i->first)
894 /* ok, our current offset is in an 'out' zone. */
895 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
897 /* in normal playback, just start at the next zone. */
900 /* size is not 64bit! */
901 if ((i->second - i->first) > max)
904 size = i->second - i->first;
907 if (m_skipmode_m < 0)
909 eDebug("reached SOF");
912 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
916 /* when skipping reverse, however, choose the zone before. */
918 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
921 if ((i->second - i->first) > max)
924 len = i->second - i->first;
926 start = i->second - len;
927 eDebug("skipping to %llx, %d", start, len);
933 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
935 eDebug("reached SOF");
937 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
940 start = current_offset;
942 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
946 void eDVBChannel::AddUse()
948 if (++m_use_count > 1 && m_state == state_last_instance)
951 m_stateChanged(this);
955 void eDVBChannel::ReleaseUse()
959 m_state = state_release;
960 m_stateChanged(this);
962 else if (m_use_count == 1)
964 m_state = state_last_instance;
965 m_stateChanged(this);
969 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
972 m_mgr->removeChannel(this);
979 eDebug("no frontend to tune!");
983 m_channel_id = channelid;
984 m_mgr->addChannel(channelid, this);
985 m_state = state_tuning;
986 /* if tuning fails, shutdown the channel immediately. */
988 res = m_frontend->get().tune(*feparm);
989 m_current_frontend_parameters = feparm;
993 m_state = state_release;
994 m_stateChanged(this);
1001 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1003 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1007 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1009 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1013 RESULT eDVBChannel::getState(int &state)
1019 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1024 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1026 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1032 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1037 /* don't hold a reference to the decoding demux, we don't need it. */
1039 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1040 the refcount is lost. thus, decoding demuxes are never allocated.
1042 this poses a big problem for PiP. */
1043 if (cap & capDecode)
1048 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1053 frontend = &m_frontend->get();
1059 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1061 param = m_current_frontend_parameters;
1065 RESULT eDVBChannel::playFile(const char *file)
1067 ASSERT(!m_frontend);
1070 m_pvr_thread->stop();
1071 delete m_pvr_thread;
1075 m_tstools.openFile(file);
1077 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1078 THEN DO A REAL FIX HERE! */
1080 /* (this codepath needs to be improved anyway.) */
1081 #if HAVE_DVB_API_VERSION < 3
1082 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1084 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1086 if (m_pvr_fd_dst < 0)
1088 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1092 m_pvr_thread = new eFilePushThread();
1093 m_pvr_thread->enablePVRCommit(1);
1094 m_pvr_thread->setScatterGather(this);
1096 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1098 delete m_pvr_thread;
1100 eDebug("can't open PVR file %s (%m)", file);
1103 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1106 m_stateChanged(this);
1111 void eDVBChannel::stopFile()
1115 m_pvr_thread->stop();
1116 ::close(m_pvr_fd_dst);
1117 delete m_pvr_thread;
1122 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1124 m_conn_cueSheetEvent = 0;
1127 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1130 RESULT eDVBChannel::getLength(pts_t &len)
1132 return m_tstools.calcLen(len);
1135 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1137 if (!decoding_demux)
1144 if (mode == 0) /* demux */
1146 r = decoding_demux->getSTC(now, 0);
1149 eDebug("demux getSTC failed");
1153 now = pos; /* fixup supplied */
1155 off_t off = 0; /* TODO: fixme */
1156 r = m_tstools.fixupPTS(off, now);
1159 eDebug("fixup PTS failed");
1168 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1170 /* when seeking, we have to ensure that all buffers are flushed.
1171 there are basically 3 buffers:
1172 a.) the filepush's internal buffer
1173 b.) the PVR buffer (before demux)
1174 c.) the ratebuffer (after demux)
1176 it's important to clear them in the correct order, otherwise
1177 the ratebuffer (for example) would immediately refill from
1178 the not-yet-flushed PVR buffer.
1181 m_pvr_thread->pause();
1182 /* flush internal filepush buffer */
1183 m_pvr_thread->flush();
1184 /* HACK: flush PVR buffer */
1185 ::ioctl(m_pvr_fd_dst, 0);
1187 /* flush ratebuffers (video, audio) */
1189 decoding_demux->flush();
1191 /* demux will also flush all decoder.. */
1192 /* resume will re-query the SG */
1193 m_pvr_thread->resume();
1196 DEFINE_REF(eCueSheet);
1198 eCueSheet::eCueSheet()
1200 m_skipmode_ratio = 0;
1203 void eCueSheet::seekTo(int relative, const pts_t &pts)
1206 eSingleLock l(m_lock);
1207 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1212 void eCueSheet::clear()
1214 eSingleLock l(m_lock);
1218 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1221 eSingleLock l(m_lock);
1222 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1226 void eCueSheet::commitSpans()
1228 m_event(evtSpanChanged);
1231 void eCueSheet::setSkipmode(const pts_t &ratio)
1234 eSingleLock l(m_lock);
1235 m_skipmode_ratio = ratio;
1237 m_event(evtSkipmode);
1240 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1242 m_decoding_demux = demux;
1243 m_decoder = decoder;
1246 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1248 connection = new eConnection(this, m_event.connect(event));