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;
385 ch = new eDVBChannel(this, 0);
391 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
393 m_active_channels.push_back(active_channel(chid, ch));
394 /* emit */ m_channelAdded(ch);
398 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
401 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
403 if (i->m_channel == ch)
405 i = m_active_channels.erase(i);
416 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
418 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
422 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
424 ePtr<eDVBRegisteredFrontend> best;
427 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
430 int c = i->m_frontend->isCompatibleWith(feparm);
438 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
440 /* first, check if a channel is already existing. */
441 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
442 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
444 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
445 if (i->m_channel_id == channelid)
447 // eDebug("found shared channel..");
452 int *decremented_fe_usecount=NULL;
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 == ignore)
459 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
460 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
462 ePtr<iDVBFrontend> fe;
463 if (!i->m_channel->getFrontend(fe))
465 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
467 if ( &(*fe) == &(*ii->m_frontend) )
470 decremented_fe_usecount = &ii->m_inuse;
482 eDebug("no channel list set!");
486 ePtr<iDVBFrontendParameters> feparm;
487 if (m_list->getChannelFrontendData(channelid, feparm))
489 eDebug("channel not found!");
493 bool ret = canAllocateFrontend(feparm);
495 if (decremented_fe_usecount)
496 ++(*decremented_fe_usecount);
501 DEFINE_REF(eDVBChannel);
503 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
505 m_frontend = frontend;
510 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
513 eDVBChannel::~eDVBChannel()
516 m_mgr->removeChannel(this);
520 m_pvr_thread->stop();
521 ::close(m_pvr_fd_src);
522 ::close(m_pvr_fd_dst);
527 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
529 int state, ourstate = 0;
531 /* if we are already in shutdown, don't change state. */
532 if (m_state == state_release)
535 if (fe->getState(state))
538 if (state == iDVBFrontend::stateLock)
540 eDebug("OURSTATE: ok");
542 } else if (state == iDVBFrontend::stateTuning)
544 eDebug("OURSTATE: tuning");
545 ourstate = state_tuning;
546 } else if (state == iDVBFrontend::stateLostLock)
548 eDebug("OURSTATE: lost lock");
549 ourstate = state_unavailable;
550 } else if (state == iDVBFrontend::stateFailed)
552 eDebug("OURSTATE: failed");
553 ourstate = state_failed;
555 eFatal("state unknown");
557 if (ourstate != m_state)
560 m_stateChanged(this);
564 void eDVBChannel::AddUse()
569 void eDVBChannel::ReleaseUse()
573 m_state = state_release;
574 m_stateChanged(this);
578 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
581 m_mgr->removeChannel(this);
588 eDebug("no frontend to tune!");
592 m_channel_id = channelid;
593 m_mgr->addChannel(channelid, this);
594 m_state = state_tuning;
595 /* if tuning fails, shutdown the channel immediately. */
597 res = m_frontend->get().tune(*feparm);
601 m_state = state_release;
602 m_stateChanged(this);
609 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
611 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
615 RESULT eDVBChannel::getState(int &state)
621 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
626 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
628 eDebug("get %d demux", cap);
629 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
635 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
648 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
650 frontend = &m_frontend->get();
657 RESULT eDVBChannel::playFile(const char *file)
662 m_pvr_thread->stop();
667 m_tstools.openFile(file);
669 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
670 THEN DO A REAL FIX HERE! */
672 /* (this codepath needs to be improved anyway.) */
673 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
674 if (m_pvr_fd_dst < 0)
676 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
680 m_pvr_fd_src = open(file, O_RDONLY);
681 if (m_pvr_fd_src < 0)
683 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
689 m_stateChanged(this);
691 m_pvr_thread = new eFilePushThread();
692 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
697 RESULT eDVBChannel::getLength(pts_t &len)
699 return m_tstools.calcLen(len);
702 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
708 /* getPTS for offset 0 is cached, so it doesn't harm. */
709 int r = m_tstools.getPTS(begin, pos);
712 eDebug("tstools getpts(0) failed!");
718 r = decoding_demux->getSTC(now);
722 eDebug("demux getSTC failed");
726 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
727 /* when we are less than 10 seconds before the start, return 0. */
728 /* (we're just waiting for the timespam to start) */
729 if ((now < pos) && ((pos - now) < 90000 * 10))
735 if (now < pos) /* wrap around */
736 pos = now + ((pts_t)1)<<33 - pos;
743 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
745 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
753 if (getCurrentPosition(decoding_demux, now))
755 eDebug("seekTo: getCurrentPosition failed!");
764 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
766 seekToPosition(decoding_demux, offset);
770 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
772 /* when seeking, we have to ensure that all buffers are flushed.
773 there are basically 3 buffers:
774 a.) the filepush's internal buffer
775 b.) the PVR buffer (before demux)
776 c.) the ratebuffer (after demux)
778 it's important to clear them in the correct order, otherwise
779 the ratebuffer (for example) would immediately refill from
780 the not-yet-flushed PVR buffer.
782 eDebug("eDVBChannel: seekToPosition .. %llx", r);
783 m_pvr_thread->pause();
785 /* flush internal filepush buffer */
786 m_pvr_thread->flush();
788 /* HACK: flush PVR buffer */
789 ::ioctl(m_pvr_fd_dst, 0);
791 /* flush ratebuffers (video, audio) */
793 decoding_demux->flush();
795 /* demux will also flush all decoder.. */
796 m_pvr_thread->seek(SEEK_SET, r);
797 m_pvr_thread->resume();