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 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
304 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
306 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
307 if (i->m_channel_id == channelid)
309 // eDebug("found shared channel..");
310 channel = i->m_channel;
315 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
319 eDebug("no channel list set!");
323 ePtr<iDVBFrontendParameters> feparm;
324 if (m_list->getChannelFrontendData(channelid, feparm))
326 eDebug("channel not found!");
330 /* allocate a frontend. */
332 ePtr<eDVBAllocatedFrontend> fe;
334 if (allocateFrontend(fe, feparm))
335 return errNoFrontend;
338 ePtr<eDVBChannel> ch;
339 ch = new eDVBChannel(this, fe);
341 res = ch->setChannel(channelid, feparm);
345 return errChidNotFound;
352 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
354 ePtr<eDVBAllocatedFrontend> fe;
356 if (allocateFrontendByIndex(fe, frontend_index))
357 return errNoFrontend;
360 ch = new eDVBChannel(this, fe);
367 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
369 ePtr<eDVBAllocatedDemux> demux;
372 ch = new eDVBChannel(this, 0);
378 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
380 m_active_channels.push_back(active_channel(chid, ch));
381 /* emit */ m_channelAdded(ch);
385 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
388 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
390 if (i->m_channel == ch)
392 i = m_active_channels.erase(i);
403 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
405 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
409 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
411 ePtr<eDVBRegisteredFrontend> best;
414 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
417 int c = i->m_frontend->isCompatibleWith(feparm);
425 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
427 /* first, check if a channel is already existing. */
428 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
429 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
431 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
432 if (i->m_channel_id == channelid)
434 // eDebug("found shared channel..");
439 int *decremented_fe_usecount=NULL;
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 == ignore)
446 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
447 if (channel->getUseCount() == 1) // channel only used once..
449 ePtr<iDVBFrontend> fe;
450 if (!i->m_channel->getFrontend(fe))
452 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
454 if ( &(*fe) == &(*ii->m_frontend) )
457 decremented_fe_usecount = &ii->m_inuse;
469 eDebug("no channel list set!");
473 ePtr<iDVBFrontendParameters> feparm;
474 if (m_list->getChannelFrontendData(channelid, feparm))
476 eDebug("channel not found!");
480 bool ret = canAllocateFrontend(feparm);
482 if (decremented_fe_usecount)
483 ++(*decremented_fe_usecount);
488 DEFINE_REF(eDVBChannel);
490 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
492 m_frontend = frontend;
497 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
500 eDVBChannel::~eDVBChannel()
503 m_mgr->removeChannel(this);
507 m_pvr_thread->stop();
508 ::close(m_pvr_fd_src);
509 ::close(m_pvr_fd_dst);
514 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
516 int state, ourstate = 0;
518 /* if we are already in shutdown, don't change state. */
519 if (m_state == state_release)
522 if (fe->getState(state))
525 if (state == iDVBFrontend::stateLock)
527 eDebug("OURSTATE: ok");
529 } else if (state == iDVBFrontend::stateTuning)
531 eDebug("OURSTATE: tuning");
532 ourstate = state_tuning;
533 } else if (state == iDVBFrontend::stateLostLock)
535 eDebug("OURSTATE: lost lock");
536 ourstate = state_unavailable;
537 } else if (state == iDVBFrontend::stateFailed)
539 eDebug("OURSTATE: failed");
540 ourstate = state_failed;
542 eFatal("state unknown");
544 if (ourstate != m_state)
547 m_stateChanged(this);
551 void eDVBChannel::AddUse()
556 void eDVBChannel::ReleaseUse()
560 m_state = state_release;
561 m_stateChanged(this);
565 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
568 m_mgr->removeChannel(this);
575 eDebug("no frontend to tune!");
579 m_channel_id = channelid;
580 m_mgr->addChannel(channelid, this);
581 m_state = state_tuning;
582 /* if tuning fails, shutdown the channel immediately. */
584 res = m_frontend->get().tune(*feparm);
588 m_state = state_release;
589 m_stateChanged(this);
596 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
598 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
602 RESULT eDVBChannel::getState(int &state)
608 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
613 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
615 eDebug("get %d demux", cap);
616 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
622 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
635 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
637 frontend = &m_frontend->get();
644 RESULT eDVBChannel::playFile(const char *file)
649 m_pvr_thread->stop();
654 m_tstools.openFile(file);
656 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
657 THEN DO A REAL FIX HERE! */
659 /* (this codepath needs to be improved anyway.) */
660 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
661 if (m_pvr_fd_dst < 0)
663 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
667 m_pvr_fd_src = open(file, O_RDONLY);
668 if (m_pvr_fd_src < 0)
670 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
676 m_stateChanged(this);
678 m_pvr_thread = new eFilePushThread();
679 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
684 RESULT eDVBChannel::getLength(pts_t &len)
686 return m_tstools.calcLen(len);
689 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
695 /* getPTS for offset 0 is cached, so it doesn't harm. */
696 int r = m_tstools.getPTS(begin, pos);
699 eDebug("tstools getpts(0) failed!");
705 r = decoding_demux->getSTC(now);
709 eDebug("demux getSTC failed");
713 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
714 /* when we are less than 10 seconds before the start, return 0. */
715 /* (we're just waiting for the timespam to start) */
716 if ((now < pos) && ((pos - now) < 90000 * 10))
722 if (now < pos) /* wrap around */
723 pos = now + ((pts_t)1)<<33 - pos;
730 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
732 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
740 if (getCurrentPosition(decoding_demux, now))
742 eDebug("seekTo: getCurrentPosition failed!");
751 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
753 seekToPosition(decoding_demux, offset);
757 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
759 /* when seeking, we have to ensure that all buffers are flushed.
760 there are basically 3 buffers:
761 a.) the filepush's internal buffer
762 b.) the PVR buffer (before demux)
763 c.) the ratebuffer (after demux)
765 it's important to clear them in the correct order, otherwise
766 the ratebuffer (for example) would immediately refill from
767 the not-yet-flushed PVR buffer.
769 eDebug("eDVBChannel: seekToPosition .. %llx", r);
770 m_pvr_thread->pause();
772 /* flush internal filepush buffer */
773 m_pvr_thread->flush();
775 /* HACK: flush PVR buffer */
776 ::ioctl(m_pvr_fd_dst, 0);
778 /* flush ratebuffers (video, audio) */
780 decoding_demux->flush();
782 /* demux will also flush all decoder.. */
783 m_pvr_thread->seek(SEEK_SET, r);
784 m_pvr_thread->resume();