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)
300 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
302 /* first, check if a channel is already existing. */
304 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
305 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
307 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
308 if (i->m_channel_id == channelid)
310 // eDebug("found shared channel..");
311 channel = i->m_channel;
316 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
320 eDebug("no channel list set!");
324 ePtr<iDVBFrontendParameters> feparm;
325 if (m_list->getChannelFrontendData(channelid, feparm))
327 eDebug("channel not found!");
331 /* allocate a frontend. */
333 ePtr<eDVBAllocatedFrontend> fe;
335 if (allocateFrontend(fe, feparm))
336 return errNoFrontend;
339 ePtr<eDVBChannel> ch;
340 ch = new eDVBChannel(this, fe);
342 res = ch->setChannel(channelid, feparm);
346 return errChidNotFound;
353 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
355 ePtr<eDVBAllocatedFrontend> fe;
357 if (allocateFrontendByIndex(fe, frontend_index))
358 return errNoFrontend;
361 ch = new eDVBChannel(this, fe);
368 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
370 ePtr<eDVBAllocatedDemux> demux;
373 ch = new eDVBChannel(this, 0);
379 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
381 m_active_channels.push_back(active_channel(chid, ch));
382 /* emit */ m_channelAdded(ch);
386 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
389 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
391 if (i->m_channel == ch)
393 i = m_active_channels.erase(i);
404 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
406 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
410 DEFINE_REF(eDVBChannel);
412 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
414 m_frontend = frontend;
419 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
422 eDVBChannel::~eDVBChannel()
425 m_mgr->removeChannel(this);
429 m_pvr_thread->stop();
430 ::close(m_pvr_fd_src);
431 ::close(m_pvr_fd_dst);
436 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
438 int state, ourstate = 0;
440 /* if we are already in shutdown, don't change state. */
441 if (m_state == state_release)
444 if (fe->getState(state))
447 if (state == iDVBFrontend::stateLock)
449 eDebug("OURSTATE: ok");
451 } else if (state == iDVBFrontend::stateTuning)
453 eDebug("OURSTATE: tuning");
454 ourstate = state_tuning;
455 } else if (state == iDVBFrontend::stateLostLock)
457 eDebug("OURSTATE: lost lock");
458 ourstate = state_unavailable;
459 } else if (state == iDVBFrontend::stateFailed)
461 eDebug("OURSTATE: failed");
462 ourstate = state_failed;
464 eFatal("state unknown");
466 if (ourstate != m_state)
469 m_stateChanged(this);
473 void eDVBChannel::AddUse()
478 void eDVBChannel::ReleaseUse()
482 m_state = state_release;
483 m_stateChanged(this);
487 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
490 m_mgr->removeChannel(this);
497 eDebug("no frontend to tune!");
501 m_channel_id = channelid;
502 m_mgr->addChannel(channelid, this);
503 m_state = state_tuning;
504 /* if tuning fails, shutdown the channel immediately. */
506 res = m_frontend->get().tune(*feparm);
510 m_state = state_release;
511 m_stateChanged(this);
518 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
520 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
524 RESULT eDVBChannel::getState(int &state)
530 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
535 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
537 eDebug("get %d demux", cap);
538 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
544 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
557 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
559 frontend = &m_frontend->get();
566 RESULT eDVBChannel::playFile(const char *file)
571 m_pvr_thread->stop();
576 m_tstools.openFile(file);
578 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
579 THEN DO A REAL FIX HERE! */
581 /* (this codepath needs to be improved anyway.) */
582 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
583 if (m_pvr_fd_dst < 0)
585 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
589 m_pvr_fd_src = open(file, O_RDONLY);
590 if (m_pvr_fd_src < 0)
592 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
598 m_stateChanged(this);
600 m_pvr_thread = new eFilePushThread();
601 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
606 RESULT eDVBChannel::getLength(pts_t &len)
608 return m_tstools.calcLen(len);
611 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
617 /* getPTS for offset 0 is cached, so it doesn't harm. */
618 int r = m_tstools.getPTS(begin, pos);
621 eDebug("tstools getpts(0) failed!");
627 r = decoding_demux->getSTC(now);
631 eDebug("demux getSTC failed");
635 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
636 /* when we are less than 10 seconds before the start, return 0. */
637 /* (we're just waiting for the timespam to start) */
638 if ((now < pos) && ((pos - now) < 90000 * 10))
644 if (now < pos) /* wrap around */
645 pos = now + ((pts_t)1)<<33 - pos;
652 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
654 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
662 if (getCurrentPosition(decoding_demux, now))
664 eDebug("seekTo: getCurrentPosition failed!");
673 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
675 seekToPosition(decoding_demux, offset);
679 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
681 /* when seeking, we have to ensure that all buffers are flushed.
682 there are basically 3 buffers:
683 a.) the filepush's internal buffer
684 b.) the PVR buffer (before demux)
685 c.) the ratebuffer (after demux)
687 it's important to clear them in the correct order, otherwise
688 the ratebuffer (for example) would immediately refill from
689 the not-yet-flushed PVR buffer.
691 eDebug("eDVBChannel: seekToPosition .. %llx", r);
692 m_pvr_thread->pause();
694 /* flush internal filepush buffer */
695 m_pvr_thread->flush();
697 /* HACK: flush PVR buffer */
698 ::ioctl(m_pvr_fd_dst, 0);
700 /* flush ratebuffers (video, audio) */
702 decoding_demux->flush();
704 /* demux will also flush all decoder.. */
705 m_pvr_thread->seek(SEEK_SET, r);
706 m_pvr_thread->resume();