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 eDVBResourceManager::eDVBResourceManager()
49 m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
53 /* search available adapters... */
58 while (eDVBAdapterLinux::exist(num_adapter))
60 addAdapter(new eDVBAdapterLinux(num_adapter));
64 eDebug("found %d adapter, %d frontends and %d demux",
65 m_adapter.size(), m_frontend.size(), m_demux.size());
69 DEFINE_REF(eDVBAdapterLinux);
70 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
75 eDebug("scanning for frontends..");
80 #if HAVE_DVB_API_VERSION < 3
81 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
83 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
85 if (stat(filename, &s))
87 ePtr<eDVBFrontend> fe;
90 fe = new eDVBFrontend(m_nr, num_fe, ok);
92 m_frontend.push_back(fe);
102 #if HAVE_DVB_API_VERSION < 3
103 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
105 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
107 if (stat(filename, &s))
109 ePtr<eDVBDemux> demux;
111 demux = new eDVBDemux(m_nr, num_demux);
112 m_demux.push_back(demux);
118 int eDVBAdapterLinux::getNumDemux()
120 return m_demux.size();
123 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
125 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
126 while (nr && (i != m_demux.end()))
132 if (i != m_demux.end())
140 int eDVBAdapterLinux::getNumFrontends()
142 return m_frontend.size();
145 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
147 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
148 while (nr && (i != m_frontend.end()))
154 if (i != m_frontend.end())
162 int eDVBAdapterLinux::exist(int nr)
166 #if HAVE_DVB_API_VERSION < 3
167 sprintf(filename, "/dev/dvb/card%d", nr);
169 sprintf(filename, "/dev/dvb/adapter%d", nr);
171 if (!stat(filename, &s))
176 eDVBResourceManager::~eDVBResourceManager()
178 if (instance == this)
182 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
184 int num_fe = adapter->getNumFrontends();
185 int num_demux = adapter->getNumDemux();
187 m_adapter.push_back(adapter);
190 for (i=0; i<num_demux; ++i)
192 ePtr<eDVBDemux> demux;
193 if (!adapter->getDemux(demux, i))
194 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
197 for (i=0; i<num_fe; ++i)
199 ePtr<eDVBFrontend> frontend;
201 if (!adapter->getFrontend(frontend, i))
203 frontend->setSEC(m_sec);
204 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
209 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
211 ePtr<eDVBRegisteredFrontend> best;
214 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
217 int c = i->m_frontend->isCompatibleWith(feparm);
227 fe = new eDVBAllocatedFrontend(best);
236 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
238 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
239 if ((!nr) && !i->m_inuse)
241 fe = new eDVBAllocatedFrontend(i);
249 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
251 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
252 never use the first one unless we need a decoding demux. */
254 eDebug("allocate demux");
255 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
257 if (i == m_demux.end())
261 /* FIXME: hardware demux policy */
262 if (!(cap & iDVBChannel::capDecode))
265 for (; i != m_demux.end(); ++i, ++n)
266 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
268 if ((cap & iDVBChannel::capDecode) && n)
271 demux = new eDVBAllocatedDemux(i);
273 demux->get().setSourceFrontend(fe->m_frontend->getID());
275 demux->get().setSourcePVR(0);
278 eDebug("demux not found");
282 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
288 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
297 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
299 /* first, check if a channel is already existing. */
301 if (m_cached_channel)
303 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
304 if(channelid==cache_chan->getChannelID())
306 eDebug("use cached_channel");
307 channel = m_cached_channel;
308 m_cached_channel->recheckFrontendState();
314 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
315 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
317 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
318 if (i->m_channel_id == channelid)
320 // eDebug("found shared channel..");
321 channel = i->m_channel;
326 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
330 eDebug("no channel list set!");
334 ePtr<iDVBFrontendParameters> feparm;
335 if (m_list->getChannelFrontendData(channelid, feparm))
337 eDebug("channel not found!");
341 /* allocate a frontend. */
343 ePtr<eDVBAllocatedFrontend> fe;
345 if (allocateFrontend(fe, feparm))
346 return errNoFrontend;
349 ePtr<eDVBChannel> ch;
350 ch = new eDVBChannel(this, fe);
352 res = ch->setChannel(channelid, feparm);
356 return errChidNotFound;
358 m_cached_channel = channel = ch;
363 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
365 ePtr<eDVBAllocatedFrontend> fe;
367 if (m_cached_channel)
370 if (allocateFrontendByIndex(fe, frontend_index))
371 return errNoFrontend;
374 ch = new eDVBChannel(this, fe);
381 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
383 ePtr<eDVBAllocatedDemux> demux;
385 if (m_cached_channel)
389 ch = new eDVBChannel(this, 0);
395 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
397 m_active_channels.push_back(active_channel(chid, ch));
398 /* emit */ m_channelAdded(ch);
402 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
405 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
407 if (i->m_channel == ch)
409 i = m_active_channels.erase(i);
420 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
422 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
426 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
428 ePtr<eDVBRegisteredFrontend> best;
431 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
434 int c = i->m_frontend->isCompatibleWith(feparm);
442 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
445 if (m_cached_channel)
447 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
448 if(channelid==cache_chan->getChannelID())
452 /* first, check if a channel is already existing. */
453 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
454 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
456 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
457 if (i->m_channel_id == channelid)
459 // eDebug("found shared channel..");
464 int *decremented_cached_channel_fe_usecount=NULL,
465 *decremented_fe_usecount=NULL;
467 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
469 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
470 if (i->m_channel_id == ignore)
472 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
473 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
475 ePtr<iDVBFrontend> fe;
476 if (!i->m_channel->getFrontend(fe))
478 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
480 if ( &(*fe) == &(*ii->m_frontend) )
483 decremented_fe_usecount = &ii->m_inuse;
484 if (channel == &(*m_cached_channel))
485 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
495 if (!decremented_cached_channel_fe_usecount)
497 if (m_cached_channel)
499 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
500 if (channel->getUseCount() == 1)
502 ePtr<iDVBFrontend> fe;
503 if (!channel->getFrontend(fe))
505 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
507 if ( &(*fe) == &(*ii->m_frontend) )
510 decremented_cached_channel_fe_usecount = &ii->m_inuse;
519 decremented_cached_channel_fe_usecount=NULL;
521 ePtr<iDVBFrontendParameters> feparm;
525 eDebug("no channel list set!");
530 if (m_list->getChannelFrontendData(channelid, feparm))
532 eDebug("channel not found!");
537 ret = canAllocateFrontend(feparm);
540 if (decremented_fe_usecount)
541 ++(*decremented_fe_usecount);
542 if (decremented_cached_channel_fe_usecount)
543 ++(*decremented_cached_channel_fe_usecount);
548 DEFINE_REF(eDVBChannel);
550 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
552 m_frontend = frontend;
557 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
560 eDVBChannel::~eDVBChannel()
563 m_mgr->removeChannel(this);
567 m_pvr_thread->stop();
568 ::close(m_pvr_fd_src);
569 ::close(m_pvr_fd_dst);
574 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
576 int state, ourstate = 0;
578 /* if we are already in shutdown, don't change state. */
579 if (m_state == state_release)
582 if (fe->getState(state))
585 if (state == iDVBFrontend::stateLock)
587 eDebug("OURSTATE: ok");
589 } else if (state == iDVBFrontend::stateTuning)
591 eDebug("OURSTATE: tuning");
592 ourstate = state_tuning;
593 } else if (state == iDVBFrontend::stateLostLock)
595 /* on managed channels, we try to retune in order to re-acquire lock. */
598 eDebug("OURSTATE: lost lock, trying to retune");
599 ourstate = state_tuning;
600 m_frontend->get().tune(*m_feparm);
602 /* on unmanaged channels, we don't do this. the client will do this. */
604 eDebug("OURSTATE: lost lock, unavailable now.")
605 ourstate = state_unavailable;
607 } else if (state == iDVBFrontend::stateFailed)
609 eDebug("OURSTATE: failed");
610 ourstate = state_failed;
612 eFatal("state unknown");
614 if (ourstate != m_state)
617 m_stateChanged(this);
621 void eDVBChannel::pvrEvent(int event)
625 case eFilePushThread::evtEOF:
626 eDebug("eDVBChannel: End of file!");
627 m_event(this, evtEOF);
632 void eDVBChannel::AddUse()
637 void eDVBChannel::ReleaseUse()
641 m_state = state_release;
642 m_stateChanged(this);
646 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
649 m_mgr->removeChannel(this);
656 eDebug("no frontend to tune!");
660 m_channel_id = channelid;
661 m_mgr->addChannel(channelid, this);
662 m_state = state_tuning;
663 /* if tuning fails, shutdown the channel immediately. */
665 res = m_frontend->get().tune(*feparm);
670 m_state = state_release;
671 m_stateChanged(this);
678 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
680 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
684 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
686 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
690 RESULT eDVBChannel::getState(int &state)
696 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
701 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
703 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
709 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
714 /* don't hold a reference to the decoding demux, we don't need it. */
720 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
722 frontend = &m_frontend->get();
729 RESULT eDVBChannel::playFile(const char *file)
734 m_pvr_thread->stop();
739 m_tstools.openFile(file);
741 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
742 THEN DO A REAL FIX HERE! */
744 /* (this codepath needs to be improved anyway.) */
745 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
746 if (m_pvr_fd_dst < 0)
748 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
752 m_pvr_fd_src = open(file, O_RDONLY|O_LARGEFILE);
753 if (m_pvr_fd_src < 0)
755 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
761 m_stateChanged(this);
763 m_pvr_thread = new eFilePushThread();
764 m_pvr_thread->enablePVRCommit(1);
765 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
766 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
771 RESULT eDVBChannel::getLength(pts_t &len)
773 return m_tstools.calcLen(len);
776 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
782 /* getPTS for offset 0 is cached, so it doesn't harm. */
783 int r = m_tstools.getPTS(begin, pos);
786 eDebug("tstools getpts(0) failed!");
792 /* TODO: this is a gross hack. */
793 r = decoding_demux->getSTC(now, mode ? 128 : 0);
797 eDebug("demux getSTC failed");
801 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
802 /* when we are less than 10 seconds before the start, return 0. */
803 /* (we're just waiting for the timespam to start) */
804 if ((now < pos) && ((pos - now) < 90000 * 10))
810 if (now < pos) /* wrap around */
811 pos = now + ((pts_t)1)<<33 - pos;
818 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
820 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
828 if (getCurrentPosition(decoding_demux, now, 0))
830 eDebug("seekTo: getCurrentPosition failed!");
839 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
841 seekToPosition(decoding_demux, offset);
845 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
847 /* when seeking, we have to ensure that all buffers are flushed.
848 there are basically 3 buffers:
849 a.) the filepush's internal buffer
850 b.) the PVR buffer (before demux)
851 c.) the ratebuffer (after demux)
853 it's important to clear them in the correct order, otherwise
854 the ratebuffer (for example) would immediately refill from
855 the not-yet-flushed PVR buffer.
857 eDebug("eDVBChannel: seekToPosition .. %llx", r);
858 m_pvr_thread->pause();
860 /* flush internal filepush buffer */
861 m_pvr_thread->flush();
863 /* HACK: flush PVR buffer */
864 ::ioctl(m_pvr_fd_dst, 0);
866 /* flush ratebuffers (video, audio) */
868 decoding_demux->flush();
870 /* demux will also flush all decoder.. */
871 m_pvr_thread->seek(SEEK_SET, r);
872 m_pvr_thread->resume();