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, int used_tuner_mask)
411 eDebug("canAllocateFrontend mask %08x", used_tuner_mask);
412 ePtr<eDVBRegisteredFrontend> best;
415 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
416 if ( !(used_tuner_mask & (1<<i->m_frontend->getID())) )
418 int c = i->m_frontend->isCompatibleWith(feparm);
426 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid)
430 int used_tuner_mask=0;
432 /* first, check if a channel is already existing. */
433 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
435 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i, ++cnt)
437 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
438 if (i->m_channel_id == channelid)
440 // eDebug("found shared channel..");
444 eDebug("activeChannel %d, NonDecoderDemux %p, DecoderDemux %p",
445 cnt, i->m_channel->getNonDecoderDemux(), i->m_channel->getDecoderDemux() );
446 if ( i->m_channel->getNonDecoderDemux() )
448 ePtr<iDVBFrontend> fe;
449 if (!i->m_channel->getFrontend(fe))
453 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
455 if ( &(*fe) == &(*ii->m_frontend) )
457 used_tuner_mask |= (1 << ii->m_frontend->getID());
470 eDebug("no channel list set!");
474 ePtr<iDVBFrontendParameters> feparm;
475 if (m_list->getChannelFrontendData(channelid, feparm))
477 eDebug("channel not found!");
481 return canAllocateFrontend(feparm, used_tuner_mask);
485 DEFINE_REF(eDVBChannel);
487 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
489 m_frontend = frontend;
494 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
497 eDVBChannel::~eDVBChannel()
500 m_mgr->removeChannel(this);
504 m_pvr_thread->stop();
505 ::close(m_pvr_fd_src);
506 ::close(m_pvr_fd_dst);
511 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
513 int state, ourstate = 0;
515 /* if we are already in shutdown, don't change state. */
516 if (m_state == state_release)
519 if (fe->getState(state))
522 if (state == iDVBFrontend::stateLock)
524 eDebug("OURSTATE: ok");
526 } else if (state == iDVBFrontend::stateTuning)
528 eDebug("OURSTATE: tuning");
529 ourstate = state_tuning;
530 } else if (state == iDVBFrontend::stateLostLock)
532 eDebug("OURSTATE: lost lock");
533 ourstate = state_unavailable;
534 } else if (state == iDVBFrontend::stateFailed)
536 eDebug("OURSTATE: failed");
537 ourstate = state_failed;
539 eFatal("state unknown");
541 if (ourstate != m_state)
544 m_stateChanged(this);
548 void eDVBChannel::AddUse()
553 void eDVBChannel::ReleaseUse()
557 m_state = state_release;
558 m_stateChanged(this);
562 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
565 m_mgr->removeChannel(this);
572 eDebug("no frontend to tune!");
576 m_channel_id = channelid;
577 m_mgr->addChannel(channelid, this);
578 m_state = state_tuning;
579 /* if tuning fails, shutdown the channel immediately. */
581 res = m_frontend->get().tune(*feparm);
585 m_state = state_release;
586 m_stateChanged(this);
593 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
595 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
599 RESULT eDVBChannel::getState(int &state)
605 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
610 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
612 eDebug("get %d demux", cap);
613 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
619 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
632 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
634 frontend = &m_frontend->get();
641 RESULT eDVBChannel::playFile(const char *file)
646 m_pvr_thread->stop();
651 m_tstools.openFile(file);
653 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
654 THEN DO A REAL FIX HERE! */
656 /* (this codepath needs to be improved anyway.) */
657 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
658 if (m_pvr_fd_dst < 0)
660 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
664 m_pvr_fd_src = open(file, O_RDONLY);
665 if (m_pvr_fd_src < 0)
667 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
673 m_stateChanged(this);
675 m_pvr_thread = new eFilePushThread();
676 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
681 RESULT eDVBChannel::getLength(pts_t &len)
683 return m_tstools.calcLen(len);
686 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
692 /* getPTS for offset 0 is cached, so it doesn't harm. */
693 int r = m_tstools.getPTS(begin, pos);
696 eDebug("tstools getpts(0) failed!");
702 r = decoding_demux->getSTC(now);
706 eDebug("demux getSTC failed");
710 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
711 /* when we are less than 10 seconds before the start, return 0. */
712 /* (we're just waiting for the timespam to start) */
713 if ((now < pos) && ((pos - now) < 90000 * 10))
719 if (now < pos) /* wrap around */
720 pos = now + ((pts_t)1)<<33 - pos;
727 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
729 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
737 if (getCurrentPosition(decoding_demux, now))
739 eDebug("seekTo: getCurrentPosition failed!");
748 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
750 seekToPosition(decoding_demux, offset);
754 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
756 /* when seeking, we have to ensure that all buffers are flushed.
757 there are basically 3 buffers:
758 a.) the filepush's internal buffer
759 b.) the PVR buffer (before demux)
760 c.) the ratebuffer (after demux)
762 it's important to clear them in the correct order, otherwise
763 the ratebuffer (for example) would immediately refill from
764 the not-yet-flushed PVR buffer.
766 eDebug("eDVBChannel: seekToPosition .. %llx", r);
767 m_pvr_thread->pause();
769 /* flush internal filepush buffer */
770 m_pvr_thread->flush();
772 /* HACK: flush PVR buffer */
773 ::ioctl(m_pvr_fd_dst, 0);
775 /* flush ratebuffers (video, audio) */
777 decoding_demux->flush();
779 /* demux will also flush all decoder.. */
780 m_pvr_thread->seek(SEEK_SET, r);
781 m_pvr_thread->resume();