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->setTone(iDVBFrontend::toneOff);
204 frontend->setVoltage(iDVBFrontend::voltageOff);
205 frontend->setSEC(m_sec);
206 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
211 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
213 ePtr<eDVBRegisteredFrontend> best;
216 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
219 int c = i->m_frontend->isCompatibleWith(feparm);
229 fe = new eDVBAllocatedFrontend(best);
238 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
240 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
241 if ((!nr) && !i->m_inuse)
243 fe = new eDVBAllocatedFrontend(i);
251 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
253 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
254 never use the first one unless we need a decoding demux. */
256 eDebug("allocate demux");
257 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
259 if (i == m_demux.end())
263 /* FIXME: hardware demux policy */
264 if (!(cap & iDVBChannel::capDecode))
267 for (; i != m_demux.end(); ++i, ++n)
268 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
270 if ((cap & iDVBChannel::capDecode) && n)
273 demux = new eDVBAllocatedDemux(i);
275 demux->get().setSourceFrontend(fe->m_frontend->getID());
277 demux->get().setSourcePVR(0);
280 eDebug("demux not found");
284 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
290 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
299 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
301 /* first, check if a channel is already existing. */
303 if (m_cached_channel)
305 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
306 if(channelid==cache_chan->getChannelID())
308 eDebug("use cached_channel");
309 channel=m_cached_channel;
315 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
316 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
318 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
319 if (i->m_channel_id == channelid)
321 // eDebug("found shared channel..");
322 channel = i->m_channel;
327 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
331 eDebug("no channel list set!");
335 ePtr<iDVBFrontendParameters> feparm;
336 if (m_list->getChannelFrontendData(channelid, feparm))
338 eDebug("channel not found!");
342 /* allocate a frontend. */
344 ePtr<eDVBAllocatedFrontend> fe;
346 if (allocateFrontend(fe, feparm))
347 return errNoFrontend;
350 ePtr<eDVBChannel> ch;
351 ch = new eDVBChannel(this, fe);
353 res = ch->setChannel(channelid, feparm);
357 return errChidNotFound;
359 m_cached_channel = channel = ch;
364 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
366 ePtr<eDVBAllocatedFrontend> fe;
368 if (allocateFrontendByIndex(fe, frontend_index))
369 return errNoFrontend;
372 ch = new eDVBChannel(this, fe);
379 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
381 ePtr<eDVBAllocatedDemux> demux;
384 ch = new eDVBChannel(this, 0);
390 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
392 m_active_channels.push_back(active_channel(chid, ch));
393 /* emit */ m_channelAdded(ch);
397 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
400 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
402 if (i->m_channel == ch)
404 i = m_active_channels.erase(i);
415 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
417 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
421 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
423 ePtr<eDVBRegisteredFrontend> best;
426 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
429 int c = i->m_frontend->isCompatibleWith(feparm);
437 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
439 /* first, check if a channel is already existing. */
440 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
441 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
443 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
444 if (i->m_channel_id == channelid)
446 // eDebug("found shared channel..");
451 int *decremented_fe_usecount=NULL;
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 == ignore)
458 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
459 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
461 ePtr<iDVBFrontend> fe;
462 if (!i->m_channel->getFrontend(fe))
464 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
466 if ( &(*fe) == &(*ii->m_frontend) )
469 decremented_fe_usecount = &ii->m_inuse;
481 eDebug("no channel list set!");
485 ePtr<iDVBFrontendParameters> feparm;
486 if (m_list->getChannelFrontendData(channelid, feparm))
488 eDebug("channel not found!");
492 bool ret = canAllocateFrontend(feparm);
494 if (decremented_fe_usecount)
495 ++(*decremented_fe_usecount);
500 DEFINE_REF(eDVBChannel);
502 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
504 m_frontend = frontend;
509 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
512 eDVBChannel::~eDVBChannel()
515 m_mgr->removeChannel(this);
519 m_pvr_thread->stop();
520 ::close(m_pvr_fd_src);
521 ::close(m_pvr_fd_dst);
526 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
528 int state, ourstate = 0;
530 /* if we are already in shutdown, don't change state. */
531 if (m_state == state_release)
534 if (fe->getState(state))
537 if (state == iDVBFrontend::stateLock)
539 eDebug("OURSTATE: ok");
541 } else if (state == iDVBFrontend::stateTuning)
543 eDebug("OURSTATE: tuning");
544 ourstate = state_tuning;
545 } else if (state == iDVBFrontend::stateLostLock)
547 eDebug("OURSTATE: lost lock");
548 ourstate = state_unavailable;
549 } else if (state == iDVBFrontend::stateFailed)
551 eDebug("OURSTATE: failed");
552 ourstate = state_failed;
554 eFatal("state unknown");
556 if (ourstate != m_state)
559 m_stateChanged(this);
563 void eDVBChannel::AddUse()
568 void eDVBChannel::ReleaseUse()
572 m_state = state_release;
573 m_stateChanged(this);
577 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
580 m_mgr->removeChannel(this);
587 eDebug("no frontend to tune!");
591 m_channel_id = channelid;
592 m_mgr->addChannel(channelid, this);
593 m_state = state_tuning;
594 /* if tuning fails, shutdown the channel immediately. */
596 res = m_frontend->get().tune(*feparm);
600 m_state = state_release;
601 m_stateChanged(this);
608 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
610 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
614 RESULT eDVBChannel::getState(int &state)
620 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
625 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
627 eDebug("get %d demux", cap);
628 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
634 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
647 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
649 frontend = &m_frontend->get();
656 RESULT eDVBChannel::playFile(const char *file)
661 m_pvr_thread->stop();
666 m_tstools.openFile(file);
668 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
669 THEN DO A REAL FIX HERE! */
671 /* (this codepath needs to be improved anyway.) */
672 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
673 if (m_pvr_fd_dst < 0)
675 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
679 m_pvr_fd_src = open(file, O_RDONLY);
680 if (m_pvr_fd_src < 0)
682 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
688 m_stateChanged(this);
690 m_pvr_thread = new eFilePushThread();
691 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
696 RESULT eDVBChannel::getLength(pts_t &len)
698 return m_tstools.calcLen(len);
701 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
707 /* getPTS for offset 0 is cached, so it doesn't harm. */
708 int r = m_tstools.getPTS(begin, pos);
711 eDebug("tstools getpts(0) failed!");
717 r = decoding_demux->getSTC(now);
721 eDebug("demux getSTC failed");
725 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
726 /* when we are less than 10 seconds before the start, return 0. */
727 /* (we're just waiting for the timespam to start) */
728 if ((now < pos) && ((pos - now) < 90000 * 10))
734 if (now < pos) /* wrap around */
735 pos = now + ((pts_t)1)<<33 - pos;
742 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
744 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
752 if (getCurrentPosition(decoding_demux, now))
754 eDebug("seekTo: getCurrentPosition failed!");
763 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
765 seekToPosition(decoding_demux, offset);
769 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
771 /* when seeking, we have to ensure that all buffers are flushed.
772 there are basically 3 buffers:
773 a.) the filepush's internal buffer
774 b.) the PVR buffer (before demux)
775 c.) the ratebuffer (after demux)
777 it's important to clear them in the correct order, otherwise
778 the ratebuffer (for example) would immediately refill from
779 the not-yet-flushed PVR buffer.
781 eDebug("eDVBChannel: seekToPosition .. %llx", r);
782 m_pvr_thread->pause();
784 /* flush internal filepush buffer */
785 m_pvr_thread->flush();
787 /* HACK: flush PVR buffer */
788 ::ioctl(m_pvr_fd_dst, 0);
790 /* flush ratebuffers (video, audio) */
792 decoding_demux->flush();
794 /* demux will also flush all decoder.. */
795 m_pvr_thread->seek(SEEK_SET, r);
796 m_pvr_thread->resume();