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 (allocateFrontendByIndex(fe, frontend_index))
367 return errNoFrontend;
370 ch = new eDVBChannel(this, fe);
377 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
379 ePtr<eDVBAllocatedDemux> demux;
382 ch = new eDVBChannel(this, 0);
388 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
390 m_active_channels.push_back(active_channel(chid, ch));
391 /* emit */ m_channelAdded(ch);
395 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
398 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
400 if (i->m_channel == ch)
402 i = m_active_channels.erase(i);
413 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
415 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
419 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
421 ePtr<eDVBRegisteredFrontend> best;
424 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
427 int c = i->m_frontend->isCompatibleWith(feparm);
435 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
437 /* first, check if a channel is already existing. */
438 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
439 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
441 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
442 if (i->m_channel_id == channelid)
444 // eDebug("found shared channel..");
449 int *decremented_fe_usecount=NULL;
451 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
453 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
454 if (i->m_channel_id == ignore)
456 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
457 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
459 ePtr<iDVBFrontend> fe;
460 if (!i->m_channel->getFrontend(fe))
462 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
464 if ( &(*fe) == &(*ii->m_frontend) )
467 decremented_fe_usecount = &ii->m_inuse;
479 eDebug("no channel list set!");
483 ePtr<iDVBFrontendParameters> feparm;
484 if (m_list->getChannelFrontendData(channelid, feparm))
486 eDebug("channel not found!");
490 bool ret = canAllocateFrontend(feparm);
492 if (decremented_fe_usecount)
493 ++(*decremented_fe_usecount);
498 DEFINE_REF(eDVBChannel);
500 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
502 m_frontend = frontend;
507 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
510 eDVBChannel::~eDVBChannel()
513 m_mgr->removeChannel(this);
517 m_pvr_thread->stop();
518 ::close(m_pvr_fd_src);
519 ::close(m_pvr_fd_dst);
524 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
526 int state, ourstate = 0;
528 /* if we are already in shutdown, don't change state. */
529 if (m_state == state_release)
532 if (fe->getState(state))
535 if (state == iDVBFrontend::stateLock)
537 eDebug("OURSTATE: ok");
539 } else if (state == iDVBFrontend::stateTuning)
541 eDebug("OURSTATE: tuning");
542 ourstate = state_tuning;
543 } else if (state == iDVBFrontend::stateLostLock)
545 eDebug("OURSTATE: lost lock");
546 ourstate = state_unavailable;
547 } else if (state == iDVBFrontend::stateFailed)
549 eDebug("OURSTATE: failed");
550 ourstate = state_failed;
552 eFatal("state unknown");
554 if (ourstate != m_state)
557 m_stateChanged(this);
561 void eDVBChannel::AddUse()
566 void eDVBChannel::ReleaseUse()
570 m_state = state_release;
571 m_stateChanged(this);
575 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
578 m_mgr->removeChannel(this);
585 eDebug("no frontend to tune!");
589 m_channel_id = channelid;
590 m_mgr->addChannel(channelid, this);
591 m_state = state_tuning;
592 /* if tuning fails, shutdown the channel immediately. */
594 res = m_frontend->get().tune(*feparm);
598 m_state = state_release;
599 m_stateChanged(this);
606 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
608 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
612 RESULT eDVBChannel::getState(int &state)
618 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
623 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
625 eDebug("get %d demux", cap);
626 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
632 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
645 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
647 frontend = &m_frontend->get();
654 RESULT eDVBChannel::playFile(const char *file)
659 m_pvr_thread->stop();
664 m_tstools.openFile(file);
666 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
667 THEN DO A REAL FIX HERE! */
669 /* (this codepath needs to be improved anyway.) */
670 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
671 if (m_pvr_fd_dst < 0)
673 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
677 m_pvr_fd_src = open(file, O_RDONLY);
678 if (m_pvr_fd_src < 0)
680 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
686 m_stateChanged(this);
688 m_pvr_thread = new eFilePushThread();
689 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
694 RESULT eDVBChannel::getLength(pts_t &len)
696 return m_tstools.calcLen(len);
699 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
705 /* getPTS for offset 0 is cached, so it doesn't harm. */
706 int r = m_tstools.getPTS(begin, pos);
709 eDebug("tstools getpts(0) failed!");
715 r = decoding_demux->getSTC(now);
719 eDebug("demux getSTC failed");
723 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
724 /* when we are less than 10 seconds before the start, return 0. */
725 /* (we're just waiting for the timespam to start) */
726 if ((now < pos) && ((pos - now) < 90000 * 10))
732 if (now < pos) /* wrap around */
733 pos = now + ((pts_t)1)<<33 - pos;
740 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
742 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
750 if (getCurrentPosition(decoding_demux, now))
752 eDebug("seekTo: getCurrentPosition failed!");
761 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
763 seekToPosition(decoding_demux, offset);
767 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
769 /* when seeking, we have to ensure that all buffers are flushed.
770 there are basically 3 buffers:
771 a.) the filepush's internal buffer
772 b.) the PVR buffer (before demux)
773 c.) the ratebuffer (after demux)
775 it's important to clear them in the correct order, otherwise
776 the ratebuffer (for example) would immediately refill from
777 the not-yet-flushed PVR buffer.
779 eDebug("eDVBChannel: seekToPosition .. %llx", r);
780 m_pvr_thread->pause();
782 /* flush internal filepush buffer */
783 m_pvr_thread->flush();
785 /* HACK: flush PVR buffer */
786 ::ioctl(m_pvr_fd_dst, 0);
788 /* flush ratebuffers (video, audio) */
790 decoding_demux->flush();
792 /* demux will also flush all decoder.. */
793 m_pvr_thread->seek(SEEK_SET, r);
794 m_pvr_thread->resume();