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, bool fake)
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;
341 ePtr<eDVBChannel> ch;
342 ch = new eDVBChannel(this, fe);
344 res = ch->setChannel(channelid, feparm);
348 return errChidNotFound;
356 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
358 ePtr<eDVBAllocatedFrontend> fe;
360 if (allocateFrontendByIndex(fe, frontend_index))
361 return errNoFrontend;
364 ch = new eDVBChannel(this, fe);
371 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
373 ePtr<eDVBAllocatedDemux> demux;
376 ch = new eDVBChannel(this, 0);
382 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
384 m_active_channels.push_back(active_channel(chid, ch));
385 /* emit */ m_channelAdded(ch);
389 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
392 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
394 if (i->m_channel == ch)
396 i = m_active_channels.erase(i);
407 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
409 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
413 DEFINE_REF(eDVBChannel);
415 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
417 m_frontend = frontend;
422 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
425 eDVBChannel::~eDVBChannel()
428 m_mgr->removeChannel(this);
432 m_pvr_thread->stop();
433 ::close(m_pvr_fd_src);
434 ::close(m_pvr_fd_dst);
439 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
441 int state, ourstate = 0;
443 /* if we are already in shutdown, don't change state. */
444 if (m_state == state_release)
447 if (fe->getState(state))
450 if (state == iDVBFrontend::stateLock)
452 eDebug("OURSTATE: ok");
454 } else if (state == iDVBFrontend::stateTuning)
456 eDebug("OURSTATE: tuning");
457 ourstate = state_tuning;
458 } else if (state == iDVBFrontend::stateLostLock)
460 eDebug("OURSTATE: lost lock");
461 ourstate = state_unavailable;
462 } else if (state == iDVBFrontend::stateFailed)
464 eDebug("OURSTATE: failed");
465 ourstate = state_failed;
467 eFatal("state unknown");
469 if (ourstate != m_state)
472 m_stateChanged(this);
476 void eDVBChannel::AddUse()
481 void eDVBChannel::ReleaseUse()
485 m_state = state_release;
486 m_stateChanged(this);
490 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
493 m_mgr->removeChannel(this);
500 eDebug("no frontend to tune!");
504 m_channel_id = channelid;
505 m_mgr->addChannel(channelid, this);
506 m_state = state_tuning;
507 /* if tuning fails, shutdown the channel immediately. */
509 res = m_frontend->get().tune(*feparm);
513 m_state = state_release;
514 m_stateChanged(this);
521 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
523 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
527 RESULT eDVBChannel::getState(int &state)
533 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
538 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
540 eDebug("get %d demux", cap);
541 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
547 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
560 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
562 frontend = &m_frontend->get();
569 RESULT eDVBChannel::playFile(const char *file)
574 m_pvr_thread->stop();
579 m_tstools.openFile(file);
581 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
582 THEN DO A REAL FIX HERE! */
584 /* (this codepath needs to be improved anyway.) */
585 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
586 if (m_pvr_fd_dst < 0)
588 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
592 m_pvr_fd_src = open(file, O_RDONLY);
593 if (m_pvr_fd_src < 0)
595 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
601 m_stateChanged(this);
603 m_pvr_thread = new eFilePushThread();
604 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
609 RESULT eDVBChannel::getLength(pts_t &len)
611 return m_tstools.calcLen(len);
614 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
620 /* getPTS for offset 0 is cached, so it doesn't harm. */
621 int r = m_tstools.getPTS(begin, pos);
624 eDebug("tstools getpts(0) failed!");
630 r = decoding_demux->getSTC(now);
634 eDebug("demux getSTC failed");
638 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
639 /* when we are less than 10 seconds before the start, return 0. */
640 /* (we're just waiting for the timespam to start) */
641 if ((now < pos) && ((pos - now) < 90000 * 10))
647 if (now < pos) /* wrap around */
648 pos = now + ((pts_t)1)<<33 - pos;
655 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
657 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
665 if (getCurrentPosition(decoding_demux, now))
667 eDebug("seekTo: getCurrentPosition failed!");
676 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
678 seekToPosition(decoding_demux, offset);
682 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
684 /* when seeking, we have to ensure that all buffers are flushed.
685 there are basically 3 buffers:
686 a.) the filepush's internal buffer
687 b.) the PVR buffer (before demux)
688 c.) the ratebuffer (after demux)
690 it's important to clear them in the correct order, otherwise
691 the ratebuffer (for example) would immediately refill from
692 the not-yet-flushed PVR buffer.
694 eDebug("eDVBChannel: seekToPosition .. %llx", r);
695 m_pvr_thread->pause();
697 /* flush internal filepush buffer */
698 m_pvr_thread->flush();
700 /* HACK: flush PVR buffer */
701 ::ioctl(m_pvr_fd_dst, 0);
703 /* flush ratebuffers (video, audio) */
705 decoding_demux->flush();
707 /* demux will also flush all decoder.. */
708 m_pvr_thread->seek(SEEK_SET, r);
709 m_pvr_thread->resume();