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;
313 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
314 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
316 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
317 if (i->m_channel_id == channelid)
319 // eDebug("found shared channel..");
320 channel = i->m_channel;
325 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
329 eDebug("no channel list set!");
333 ePtr<iDVBFrontendParameters> feparm;
334 if (m_list->getChannelFrontendData(channelid, feparm))
336 eDebug("channel not found!");
340 /* allocate a frontend. */
342 ePtr<eDVBAllocatedFrontend> fe;
344 if (allocateFrontend(fe, feparm))
345 return errNoFrontend;
348 ePtr<eDVBChannel> ch;
349 ch = new eDVBChannel(this, fe);
351 res = ch->setChannel(channelid, feparm);
355 return errChidNotFound;
357 m_cached_channel = channel = ch;
362 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
364 ePtr<eDVBAllocatedFrontend> fe;
366 if (m_cached_channel)
369 if (allocateFrontendByIndex(fe, frontend_index))
370 return errNoFrontend;
373 ch = new eDVBChannel(this, fe);
380 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
382 ePtr<eDVBAllocatedDemux> demux;
384 if (m_cached_channel)
388 ch = new eDVBChannel(this, 0);
394 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
396 m_active_channels.push_back(active_channel(chid, ch));
397 /* emit */ m_channelAdded(ch);
401 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
404 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
406 if (i->m_channel == ch)
408 i = m_active_channels.erase(i);
419 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
421 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
425 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
427 ePtr<eDVBRegisteredFrontend> best;
430 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
433 int c = i->m_frontend->isCompatibleWith(feparm);
441 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
444 if (m_cached_channel)
446 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
447 if(channelid==cache_chan->getChannelID())
451 /* first, check if a channel is already existing. */
452 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
453 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
455 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
456 if (i->m_channel_id == channelid)
458 // eDebug("found shared channel..");
463 int *decremented_cached_channel_fe_usecount=NULL,
464 *decremented_fe_usecount=NULL;
466 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
468 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
469 if (i->m_channel_id == ignore)
471 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
472 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
474 ePtr<iDVBFrontend> fe;
475 if (!i->m_channel->getFrontend(fe))
477 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
479 if ( &(*fe) == &(*ii->m_frontend) )
482 decremented_fe_usecount = &ii->m_inuse;
483 if (channel == &(*m_cached_channel))
484 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
494 if (!decremented_cached_channel_fe_usecount)
496 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
497 if (channel->getUseCount() == 1)
499 ePtr<iDVBFrontend> fe;
500 if (!channel->getFrontend(fe))
502 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
504 if ( &(*fe) == &(*ii->m_frontend) )
507 decremented_cached_channel_fe_usecount = &ii->m_inuse;
515 decremented_cached_channel_fe_usecount=NULL;
517 ePtr<iDVBFrontendParameters> feparm;
521 eDebug("no channel list set!");
526 if (m_list->getChannelFrontendData(channelid, feparm))
528 eDebug("channel not found!");
533 ret = canAllocateFrontend(feparm);
536 if (decremented_fe_usecount)
537 ++(*decremented_fe_usecount);
538 if (decremented_cached_channel_fe_usecount)
539 ++(*decremented_cached_channel_fe_usecount);
544 DEFINE_REF(eDVBChannel);
546 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
548 m_frontend = frontend;
553 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
556 eDVBChannel::~eDVBChannel()
559 m_mgr->removeChannel(this);
563 m_pvr_thread->stop();
564 ::close(m_pvr_fd_src);
565 ::close(m_pvr_fd_dst);
570 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
572 int state, ourstate = 0;
574 /* if we are already in shutdown, don't change state. */
575 if (m_state == state_release)
578 if (fe->getState(state))
581 if (state == iDVBFrontend::stateLock)
583 eDebug("OURSTATE: ok");
585 } else if (state == iDVBFrontend::stateTuning)
587 eDebug("OURSTATE: tuning");
588 ourstate = state_tuning;
589 } else if (state == iDVBFrontend::stateLostLock)
591 eDebug("OURSTATE: lost lock");
592 ourstate = state_unavailable;
593 } else if (state == iDVBFrontend::stateFailed)
595 eDebug("OURSTATE: failed");
596 ourstate = state_failed;
598 eFatal("state unknown");
600 if (ourstate != m_state)
603 m_stateChanged(this);
607 void eDVBChannel::AddUse()
612 void eDVBChannel::ReleaseUse()
616 m_state = state_release;
617 m_stateChanged(this);
621 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
624 m_mgr->removeChannel(this);
631 eDebug("no frontend to tune!");
635 m_channel_id = channelid;
636 m_mgr->addChannel(channelid, this);
637 m_state = state_tuning;
638 /* if tuning fails, shutdown the channel immediately. */
640 res = m_frontend->get().tune(*feparm);
644 m_state = state_release;
645 m_stateChanged(this);
652 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
654 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
658 RESULT eDVBChannel::getState(int &state)
664 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
669 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
671 eDebug("get %d demux", cap);
672 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
678 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
691 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
693 frontend = &m_frontend->get();
700 RESULT eDVBChannel::playFile(const char *file)
705 m_pvr_thread->stop();
710 m_tstools.openFile(file);
712 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
713 THEN DO A REAL FIX HERE! */
715 /* (this codepath needs to be improved anyway.) */
716 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
717 if (m_pvr_fd_dst < 0)
719 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
723 m_pvr_fd_src = open(file, O_RDONLY|O_LARGEFILE);
724 if (m_pvr_fd_src < 0)
726 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
732 m_stateChanged(this);
734 m_pvr_thread = new eFilePushThread();
735 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
740 RESULT eDVBChannel::getLength(pts_t &len)
742 return m_tstools.calcLen(len);
745 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
751 /* getPTS for offset 0 is cached, so it doesn't harm. */
752 int r = m_tstools.getPTS(begin, pos);
755 eDebug("tstools getpts(0) failed!");
761 /* TODO: this is a gross hack. */
762 r = decoding_demux->getSTC(now, mode ? 128 : 0);
766 eDebug("demux getSTC failed");
770 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
771 /* when we are less than 10 seconds before the start, return 0. */
772 /* (we're just waiting for the timespam to start) */
773 if ((now < pos) && ((pos - now) < 90000 * 10))
779 if (now < pos) /* wrap around */
780 pos = now + ((pts_t)1)<<33 - pos;
787 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
789 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
797 if (getCurrentPosition(decoding_demux, now, 0))
799 eDebug("seekTo: getCurrentPosition failed!");
808 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
810 seekToPosition(decoding_demux, offset);
814 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
816 /* when seeking, we have to ensure that all buffers are flushed.
817 there are basically 3 buffers:
818 a.) the filepush's internal buffer
819 b.) the PVR buffer (before demux)
820 c.) the ratebuffer (after demux)
822 it's important to clear them in the correct order, otherwise
823 the ratebuffer (for example) would immediately refill from
824 the not-yet-flushed PVR buffer.
826 eDebug("eDVBChannel: seekToPosition .. %llx", r);
827 m_pvr_thread->pause();
829 /* flush internal filepush buffer */
830 m_pvr_thread->flush();
832 /* HACK: flush PVR buffer */
833 ::ioctl(m_pvr_fd_dst, 0);
835 /* flush ratebuffers (video, audio) */
837 decoding_demux->flush();
839 /* demux will also flush all decoder.. */
840 m_pvr_thread->seek(SEEK_SET, r);
841 m_pvr_thread->resume();