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;
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->setSEC(m_sec);
204 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
209 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
211 ePtr<eDVBRegisteredFrontend> best;
214 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
217 int c = i->m_frontend->isCompatibleWith(feparm);
227 fe = new eDVBAllocatedFrontend(best);
236 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
238 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
239 if ((!nr) && !i->m_inuse)
241 fe = new eDVBAllocatedFrontend(i);
249 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
251 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
252 never use the first one unless we need a decoding demux. */
254 eDebug("allocate demux");
255 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
257 if (i == m_demux.end())
261 /* FIXME: hardware demux policy */
262 if (!(cap & iDVBChannel::capDecode))
265 for (; i != m_demux.end(); ++i, ++n)
266 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
268 if ((cap & iDVBChannel::capDecode) && n)
271 demux = new eDVBAllocatedDemux(i);
273 demux->get().setSourceFrontend(fe->m_frontend->getID());
275 demux->get().setSourcePVR(0);
278 eDebug("demux not found");
282 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
288 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
298 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
300 /* first, check if a channel is already existing. */
302 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
303 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
305 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
306 if (i->m_channel_id == channelid)
308 // eDebug("found shared channel..");
309 channel = i->m_channel;
314 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
318 eDebug("no channel list set!");
322 ePtr<iDVBFrontendParameters> feparm;
323 if (m_list->getChannelFrontendData(channelid, feparm))
325 eDebug("channel not found!");
329 /* allocate a frontend. */
331 ePtr<eDVBAllocatedFrontend> fe;
333 if (allocateFrontend(fe, feparm))
334 return errNoFrontend;
337 ePtr<eDVBChannel> ch;
338 ch = new eDVBChannel(this, fe);
340 res = ch->setChannel(channelid, feparm);
344 return errChidNotFound;
351 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
353 ePtr<eDVBAllocatedFrontend> fe;
355 if (allocateFrontendByIndex(fe, frontend_index))
356 return errNoFrontend;
359 ch = new eDVBChannel(this, fe);
366 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
368 ePtr<eDVBAllocatedDemux> demux;
371 ch = new eDVBChannel(this, 0);
377 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
379 m_active_channels.push_back(active_channel(chid, ch));
380 /* emit */ m_channelAdded(ch);
384 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
387 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
389 if (i->m_channel == ch)
391 i = m_active_channels.erase(i);
402 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
404 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
408 DEFINE_REF(eDVBChannel);
410 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
412 m_frontend = frontend;
417 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
420 eDVBChannel::~eDVBChannel()
423 m_mgr->removeChannel(this);
427 m_pvr_thread->stop();
428 ::close(m_pvr_fd_src);
429 ::close(m_pvr_fd_dst);
434 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
436 int state, ourstate = 0;
438 /* if we are already in shutdown, don't change state. */
439 if (m_state == state_release)
442 if (fe->getState(state))
445 if (state == iDVBFrontend::stateLock)
447 eDebug("OURSTATE: ok");
449 } else if (state == iDVBFrontend::stateTuning)
451 eDebug("OURSTATE: tuning");
452 ourstate = state_tuning;
453 } else if (state == iDVBFrontend::stateLostLock)
455 eDebug("OURSTATE: lost lock");
456 ourstate = state_unavailable;
457 } else if (state == iDVBFrontend::stateFailed)
459 eDebug("OURSTATE: failed");
460 ourstate = state_failed;
462 eFatal("state unknown");
464 if (ourstate != m_state)
467 m_stateChanged(this);
471 void eDVBChannel::AddUse()
476 void eDVBChannel::ReleaseUse()
480 m_state = state_release;
481 m_stateChanged(this);
485 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
488 m_mgr->removeChannel(this);
495 eDebug("no frontend to tune!");
499 m_channel_id = channelid;
500 m_mgr->addChannel(channelid, this);
501 m_state = state_tuning;
502 /* if tuning fails, shutdown the channel immediately. */
504 res = m_frontend->get().tune(*feparm);
508 m_state = state_release;
509 m_stateChanged(this);
516 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
518 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
522 RESULT eDVBChannel::getState(int &state)
528 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
533 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
535 eDebug("get %d demux", cap);
536 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
542 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
555 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
557 frontend = &m_frontend->get();
564 RESULT eDVBChannel::playFile(const char *file)
569 m_pvr_thread->stop();
574 m_tstools.openFile(file);
576 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
577 THEN DO A REAL FIX HERE! */
579 /* (this codepath needs to be improved anyway.) */
580 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
581 if (m_pvr_fd_dst < 0)
583 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
587 m_pvr_fd_src = open(file, O_RDONLY);
588 if (m_pvr_fd_src < 0)
590 eDebug("can't open PVR m_pvr_fd_src file %s (%m)", file);
596 m_stateChanged(this);
598 m_pvr_thread = new eFilePushThread();
599 m_pvr_thread->start(m_pvr_fd_src, m_pvr_fd_dst);
604 RESULT eDVBChannel::getLength(pts_t &len)
606 return m_tstools.calcLen(len);
609 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos)
615 /* getPTS for offset 0 is cached, so it doesn't harm. */
616 int r = m_tstools.getPTS(begin, pos);
619 eDebug("tstools getpts(0) failed!");
625 r = decoding_demux->getSTC(now);
629 eDebug("demux getSTC failed");
633 // eDebug("STC: %08llx PTS: %08llx, diff %lld", now, pos, now - pos);
634 /* when we are less than 10 seconds before the start, return 0. */
635 /* (we're just waiting for the timespam to start) */
636 if ((now < pos) && ((pos - now) < 90000 * 10))
642 if (now < pos) /* wrap around */
643 pos = now + ((pts_t)1)<<33 - pos;
650 RESULT eDVBChannel::seekTo(iDVBDemux *decoding_demux, int relative, pts_t &pts)
652 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
660 if (getCurrentPosition(decoding_demux, now))
662 eDebug("seekTo: getCurrentPosition failed!");
671 off_t offset = (pts * (pts_t)bitrate) / 8ULL / 90000ULL;
673 seekToPosition(decoding_demux, offset);
677 RESULT eDVBChannel::seekToPosition(iDVBDemux *decoding_demux, const off_t &r)
679 /* when seeking, we have to ensure that all buffers are flushed.
680 there are basically 3 buffers:
681 a.) the filepush's internal buffer
682 b.) the PVR buffer (before demux)
683 c.) the ratebuffer (after demux)
685 it's important to clear them in the correct order, otherwise
686 the ratebuffer (for example) would immediately refill from
687 the not-yet-flushed PVR buffer.
689 eDebug("eDVBChannel: seekToPosition .. %llx", r);
690 m_pvr_thread->pause();
692 /* flush internal filepush buffer */
693 m_pvr_thread->flush();
695 /* HACK: flush PVR buffer */
696 ::ioctl(m_pvr_fd_dst, 0);
698 /* flush ratebuffers (video, audio) */
700 decoding_demux->flush();
702 /* demux will also flush all decoder.. */
703 m_pvr_thread->seek(SEEK_SET, r);
704 m_pvr_thread->resume();