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/pmt.h>
6 #include <lib/dvb/sec.h>
7 #include <lib/dvb/specs.h>
10 #include <sys/types.h>
14 #include <sys/ioctl.h>
16 DEFINE_REF(eDVBRegisteredFrontend);
17 DEFINE_REF(eDVBRegisteredDemux);
19 DEFINE_REF(eDVBAllocatedFrontend);
21 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
26 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
31 DEFINE_REF(eDVBAllocatedDemux);
33 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
38 eDVBAllocatedDemux::~eDVBAllocatedDemux()
43 DEFINE_REF(eDVBResourceManager);
45 eDVBResourceManager *eDVBResourceManager::instance;
47 RESULT eDVBResourceManager::getInstance(ePtr<eDVBResourceManager> &ptr)
57 ePtr<eDVBResourceManager> NewResourceManagerPtr(void)
59 ePtr<eDVBResourceManager> ptr;
60 eDVBResourceManager::getInstance(ptr);
64 eDVBResourceManager::eDVBResourceManager()
65 :m_releaseCachedChannelTimer(eTimer::create(eApp))
69 m_sec = new eDVBSatelliteEquipmentControl(m_frontend, m_simulate_frontend);
74 /* search available adapters... */
79 while (eDVBAdapterLinux::exist(num_adapter))
81 addAdapter(new eDVBAdapterLinux(num_adapter));
85 eDebug("found %d adapter, %d frontends(%d sim) and %d demux",
86 m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size());
88 eDVBCAService::registerChannelCallback(this);
90 CONNECT(m_releaseCachedChannelTimer->timeout, eDVBResourceManager::releaseCachedChannel);
93 void eDVBResourceManager::feStateChanged()
96 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
98 mask |= ( 1 << i->m_frontend->getSlotID() );
99 /* emit */ frontendUseMaskChanged(mask);
102 DEFINE_REF(eDVBAdapterLinux);
103 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
108 eDebug("scanning for frontends..");
113 #if HAVE_DVB_API_VERSION < 3
114 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
116 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
118 if (stat(filename, &s))
120 ePtr<eDVBFrontend> fe;
124 fe = new eDVBFrontend(m_nr, num_fe, ok);
126 m_frontend.push_back(fe);
130 fe = new eDVBFrontend(m_nr, num_fe, ok, true);
132 m_simulate_frontend.push_back(fe);
143 #if HAVE_DVB_API_VERSION < 3
144 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
146 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
148 if (stat(filename, &s))
150 ePtr<eDVBDemux> demux;
152 demux = new eDVBDemux(m_nr, num_demux);
153 m_demux.push_back(demux);
159 int eDVBAdapterLinux::getNumDemux()
161 return m_demux.size();
164 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
166 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
167 while (nr && (i != m_demux.end()))
173 if (i != m_demux.end())
181 int eDVBAdapterLinux::getNumFrontends()
183 return m_frontend.size();
186 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr, bool simulate)
188 eSmartPtrList<eDVBFrontend>::iterator i(simulate ? m_simulate_frontend.begin() : m_frontend.begin());
189 while (nr && (i != m_frontend.end()))
195 if (i != m_frontend.end())
203 int eDVBAdapterLinux::exist(int nr)
207 #if HAVE_DVB_API_VERSION < 3
208 sprintf(filename, "/dev/dvb/card%d", nr);
210 sprintf(filename, "/dev/dvb/adapter%d", nr);
212 if (!stat(filename, &s))
217 eDVBResourceManager::~eDVBResourceManager()
219 if (instance == this)
223 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
225 int num_fe = adapter->getNumFrontends();
226 int num_demux = adapter->getNumDemux();
228 m_adapter.push_back(adapter);
231 for (i=0; i<num_demux; ++i)
233 ePtr<eDVBDemux> demux;
234 if (!adapter->getDemux(demux, i))
235 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
238 ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
239 for (i=0; i<num_fe; ++i)
241 ePtr<eDVBFrontend> frontend;
242 if (!adapter->getFrontend(frontend, i))
245 frontend->getFrontendType(frontendType);
246 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
247 CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
248 m_frontend.push_back(new_fe);
249 frontend->setSEC(m_sec);
250 // we must link all dvb-t frontends ( for active antenna voltage )
251 if (frontendType == iDVBFrontend::feTerrestrial)
253 if (prev_dvbt_frontend)
255 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe);
256 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend));
258 prev_dvbt_frontend = new_fe;
263 prev_dvbt_frontend = 0;
264 for (i=0; i<num_fe; ++i)
266 ePtr<eDVBFrontend> frontend;
267 if (!adapter->getFrontend(frontend, i, true))
270 frontend->getFrontendType(frontendType);
271 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
272 // CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
273 m_simulate_frontend.push_back(new_fe);
274 frontend->setSEC(m_sec);
275 // we must link all dvb-t frontends ( for active antenna voltage )
276 if (frontendType == iDVBFrontend::feTerrestrial)
278 if (prev_dvbt_frontend)
280 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe);
281 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend));
283 prev_dvbt_frontend = new_fe;
290 PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
292 if (!PyList_Check(list))
294 PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
297 if ((unsigned int)PyList_Size(list) != m_frontend.size())
300 sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist",
301 m_frontend.size(), PyList_Size(list));
302 PyErr_SetString(PyExc_StandardError, blasel);
306 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
308 ePyObject obj = PyList_GET_ITEM(list, pos++);
309 if (!i->m_frontend->setSlotInfo(obj))
313 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_simulate_frontend.begin()); i != m_simulate_frontend.end(); ++i)
315 ePyObject obj = PyList_GET_ITEM(list, pos++);
316 if (!i->m_frontend->setSlotInfo(obj))
322 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm, bool simulate)
324 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
325 ePtr<eDVBRegisteredFrontend> best;
329 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
331 int c = i->m_frontend->isCompatibleWith(feparm);
333 if (c) /* if we have at least one frontend which is compatible with the source, flag this. */
338 // eDebug("Slot %d, score %d", i->m_frontend->getSlotID(), c);
346 // eDebug("Slot %d, score %d... but BUSY!!!!!!!!!!!", i->m_frontend->getSlotID(), c);
351 fe = new eDVBAllocatedFrontend(best);
358 return errAllSourcesBusy;
360 return errNoSourceFound;
363 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index)
365 int err = errNoSourceFound;
366 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
367 if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index)
369 // check if another slot linked to this is in use
371 i->m_frontend->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, tmp);
374 eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend *)tmp;
375 if (satpos_depends_to_fe->m_inuse)
377 eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!");
378 err = errAllSourcesBusy;
379 goto alloc_fe_by_id_not_possible;
382 else // check linked tuners
384 i->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, tmp);
387 eDVBRegisteredFrontend *next = (eDVBRegisteredFrontend *) tmp;
390 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
391 err = errAllSourcesBusy;
392 goto alloc_fe_by_id_not_possible;
394 next->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, tmp);
396 i->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp);
399 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *) tmp;
402 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
403 err = errAllSourcesBusy;
404 goto alloc_fe_by_id_not_possible;
406 prev->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp);
409 fe = new eDVBAllocatedFrontend(i);
412 alloc_fe_by_id_not_possible:
417 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
419 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
420 never use the first one unless we need a decoding demux. */
422 eDebug("allocate demux");
423 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
427 if (i == m_demux.end())
430 ePtr<eDVBRegisteredDemux> unused;
432 if (m_demux.size() < 5)
434 /* FIXME: hardware demux policy */
435 if (!(cap & iDVBChannel::capDecode))
437 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
444 for (; i != m_demux.end(); ++i, ++n)
446 int is_decode = n < 2;
448 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
450 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
452 if ((cap & iDVBChannel::capDecode) && !is_decode)
459 else // we asume dm8000
461 for (; i != m_demux.end(); ++i, ++n)
470 else if (i->m_adapter == fe->m_adapter &&
471 i->m_demux->getSource() == fe->m_frontend->getDVBID())
473 demux = new eDVBAllocatedDemux(i);
477 else if (n == 4) // always use demux4 for PVR (demux 4 can not descramble...)
480 demux = new eDVBAllocatedDemux(i);
490 demux = new eDVBAllocatedDemux(unused);
492 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
494 demux->get().setSourcePVR(0);
498 eDebug("demux not found");
502 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
508 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
517 #define eDebugNoSimulate(x...) \
524 // eDebugNoNewLine("SIMULATE:"); \
529 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate)
531 /* first, check if a channel is already existing. */
532 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
534 if (!simulate && m_cached_channel)
536 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
537 if(channelid==cache_chan->getChannelID())
539 eDebug("use cached_channel");
540 channel = m_cached_channel;
543 m_cached_channel_state_changed_conn.disconnect();
545 m_releaseCachedChannelTimer->stop();
548 eDebugNoSimulate("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
549 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
551 eDebugNoSimulate("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
552 if (i->m_channel_id == channelid)
554 eDebugNoSimulate("found shared channel..");
555 channel = i->m_channel;
560 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
564 eDebugNoSimulate("no channel list set!");
565 return errNoChannelList;
568 ePtr<iDVBFrontendParameters> feparm;
569 if (m_list->getChannelFrontendData(channelid, feparm))
571 eDebugNoSimulate("channel not found!");
572 return errChannelNotInList;
575 /* allocate a frontend. */
577 ePtr<eDVBAllocatedFrontend> fe;
579 int err = allocateFrontend(fe, feparm, simulate);
584 ePtr<eDVBChannel> ch = new eDVBChannel(this, fe);
586 res = ch->setChannel(channelid, feparm);
590 return errChidNotFound;
597 m_cached_channel = channel = ch;
598 m_cached_channel_state_changed_conn =
599 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
605 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
608 chan->getState(state);
611 case iDVBChannel::state_release:
612 case iDVBChannel::state_ok:
614 eDebug("stop release channel timer");
615 m_releaseCachedChannelTimer->stop();
618 case iDVBChannel::state_last_instance:
620 eDebug("start release channel timer");
621 m_releaseCachedChannelTimer->start(3000, true);
624 default: // ignore all other events
629 void eDVBResourceManager::releaseCachedChannel()
631 eDebug("release cached channel (timer timeout)");
635 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
637 ePtr<eDVBAllocatedFrontend> fe;
639 if (m_cached_channel)
641 m_cached_channel_state_changed_conn.disconnect();
643 m_releaseCachedChannelTimer->stop();
646 int err = allocateFrontendByIndex(fe, slot_index);
650 channel = new eDVBChannel(this, fe);
655 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
657 ePtr<eDVBAllocatedDemux> demux;
659 if (m_cached_channel && m_releaseCachedChannelTimer->isActive())
661 m_cached_channel_state_changed_conn.disconnect();
663 m_releaseCachedChannelTimer->stop();
666 channel = new eDVBChannel(this, 0);
670 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
672 ePtr<iDVBFrontend> fe;
673 if (!ch->getFrontend(fe))
675 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
676 if (frontend->is_simulate())
677 m_active_simulate_channels.push_back(active_channel(chid, ch));
680 m_active_channels.push_back(active_channel(chid, ch));
681 /* emit */ m_channelAdded(ch);
687 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
689 ePtr<iDVBFrontend> fe;
690 if (!ch->getFrontend(fe))
692 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
693 std::list<active_channel> &active_channels = frontend->is_simulate() ? m_active_simulate_channels : m_active_channels;
695 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end();)
697 if (i->m_channel == ch)
699 i = active_channels.erase(i);
711 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
713 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
717 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm, bool simulate)
719 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
720 ePtr<eDVBRegisteredFrontend> best;
723 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
726 int c = i->m_frontend->isCompatibleWith(feparm);
733 int tuner_type_channel_default(ePtr<iDVBChannelList> &channellist, const eDVBChannelID &chid)
737 ePtr<iDVBFrontendParameters> feparm;
738 if (!channellist->getChannelFrontendData(chid, feparm))
741 if (!feparm->getSystem(system))
745 case iDVBFrontend::feSatellite:
747 case iDVBFrontend::feCable:
749 case iDVBFrontend::feTerrestrial:
760 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, bool simulate)
762 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
764 if (!simulate && m_cached_channel)
766 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
767 if(channelid==cache_chan->getChannelID())
768 return tuner_type_channel_default(m_list, channelid);
771 /* first, check if a channel is already existing. */
772 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
773 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
775 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
776 if (i->m_channel_id == channelid)
778 // eDebug("found shared channel..");
779 return tuner_type_channel_default(m_list, channelid);
783 int *decremented_cached_channel_fe_usecount=NULL,
784 *decremented_fe_usecount=NULL;
786 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
788 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
789 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
790 if (i->m_channel_id == ignore)
792 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
793 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
794 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
795 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
796 // or 2 when the cached channel is not equal to the compared channel
797 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
799 ePtr<iDVBFrontend> fe;
800 if (!i->m_channel->getFrontend(fe))
802 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
804 if ( &(*fe) == &(*ii->m_frontend) )
807 decremented_fe_usecount = &ii->m_inuse;
808 if (channel == &(*m_cached_channel))
809 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
819 if (!decremented_cached_channel_fe_usecount)
821 if (m_cached_channel)
823 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
824 if (channel->getUseCount() == 1)
826 ePtr<iDVBFrontend> fe;
827 if (!channel->getFrontend(fe))
829 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
830 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
832 if ( &(*fe) == &(*ii->m_frontend) )
835 decremented_cached_channel_fe_usecount = &ii->m_inuse;
844 decremented_cached_channel_fe_usecount=NULL;
846 ePtr<iDVBFrontendParameters> feparm;
850 eDebug("no channel list set!");
854 if (m_list->getChannelFrontendData(channelid, feparm))
856 eDebug("channel not found!");
860 ret = canAllocateFrontend(feparm, simulate);
863 if (decremented_fe_usecount)
864 ++(*decremented_fe_usecount);
865 if (decremented_cached_channel_fe_usecount)
866 ++(*decremented_cached_channel_fe_usecount);
871 bool eDVBResourceManager::canMeasureFrontendInputPower()
873 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
875 return i->m_frontend->readInputpower() >= 0;
880 class eDVBChannelFilePush: public eFilePushThread
883 eDVBChannelFilePush() { setIFrameSearch(0); setTimebaseChange(0); }
884 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
886 /* "timebase change" is for doing trickmode playback at an exact speed, even when pictures are skipped. */
887 /* you need to set it to 1/16 if you want 16x playback, for example. you need video master sync. */
888 void setTimebaseChange(int ratio) { m_timebase_change = ratio; } /* 16bit fixpoint, 0 for disable */
890 int m_iframe_search, m_iframe_state, m_pid;
891 int m_timebase_change;
892 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
895 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
898 if (m_timebase_change)
900 eDebug("timebase change: %d", m_timebase_change);
902 for (offset = 0; offset < len; offset += 188)
904 unsigned char *pkt = (unsigned char*)_data + offset;
905 if (pkt[1] & 0x40) /* pusi */
907 if (pkt[3] & 0x20) // adaption field present?
908 pkt += pkt[4] + 4 + 1; /* skip adaption field and header */
910 pkt += 4; /* skip header */
911 if (pkt[0] || pkt[1] || (pkt[2] != 1))
913 eWarning("broken startcode");
919 if (pkt[7] & 0x80) // PTS present?
921 pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29;
922 pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22;
923 pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14;
924 pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7;
925 pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1;
929 RESULT r = m_tstools.fixupPTS(off, pts);
931 eWarning("fixup PTS while trickmode playback failed.\n");
934 int sec = pts / 90000;
935 int frm = pts % 90000;
943 // eDebug("original, fixed pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
946 pts *= m_timebase_change;
958 // eDebug("new pts (after timebase change): %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
966 pkt[9] |= (pts >> 29) & 0xE;
967 pkt[10] |= (pts >> 22) & 0xFF;
968 pkt[11] |= (pts >> 14) & 0xFE;
969 pkt[12] |= (pts >> 7) & 0xFF;
970 pkt[13] |= (pts << 1) & 0xFE;
978 if (!m_iframe_search)
981 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
983 // eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
985 unsigned char *d = data;
986 while ((d + 3 < data + len) && (d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
988 int offset = d - data;
989 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
990 unsigned char *ts = data + ts_offset;
991 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
993 if ((d[3] == 0) && (m_pid == pid)) /* picture start */
995 int picture_type = (d[5] >> 3) & 7;
998 // eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
1000 if (m_iframe_state == 1)
1002 /* we are allowing data, and stop allowing data on the next frame.
1003 we now found a frame. so stop here. */
1004 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
1005 current_span_remaining = 0;
1007 unsigned char *fts = ts + 188;
1008 while (fts < (data + len))
1011 fts[2] |= 0xff; /* drop packet */
1015 return len; // ts_offset + 188; /* deliver this packet, but not more. */
1018 if (picture_type != 1) /* we are only interested in I frames */
1021 unsigned char *fts = data;
1025 fts[2] |= 0xff; /* drop packet */
1032 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
1036 eDebug("now locked to pid %04x", pid);
1042 d += 4; /* ignore */
1046 if (m_iframe_state == 1)
1049 return 0; /* we need find an iframe first */
1055 DEFINE_REF(eDVBChannel);
1057 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1059 m_frontend = frontend;
1063 m_skipmode_n = m_skipmode_m = 0;
1066 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1069 eDVBChannel::~eDVBChannel()
1072 m_mgr->removeChannel(this);
1077 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1079 int state, ourstate = 0;
1081 /* if we are already in shutdown, don't change state. */
1082 if (m_state == state_release)
1085 if (fe->getState(state))
1088 if (state == iDVBFrontend::stateLock)
1090 eDebug("OURSTATE: ok");
1091 ourstate = state_ok;
1092 } else if (state == iDVBFrontend::stateTuning)
1094 eDebug("OURSTATE: tuning");
1095 ourstate = state_tuning;
1096 } else if (state == iDVBFrontend::stateLostLock)
1098 /* on managed channels, we try to retune in order to re-acquire lock. */
1099 if (m_current_frontend_parameters)
1101 eDebug("OURSTATE: lost lock, trying to retune");
1102 ourstate = state_tuning;
1103 m_frontend->get().tune(*m_current_frontend_parameters);
1105 /* on unmanaged channels, we don't do this. the client will do this. */
1107 eDebug("OURSTATE: lost lock, unavailable now.");
1108 ourstate = state_unavailable;
1110 } else if (state == iDVBFrontend::stateFailed)
1112 eDebug("OURSTATE: failed");
1113 ourstate = state_failed;
1115 eFatal("state unknown");
1117 if (ourstate != m_state)
1120 m_stateChanged(this);
1124 void eDVBChannel::pvrEvent(int event)
1128 case eFilePushThread::evtEOF:
1129 eDebug("eDVBChannel: End of file!");
1130 m_event(this, evtEOF);
1132 case eFilePushThread::evtUser: /* start */
1134 m_event(this, evtSOF);
1139 void eDVBChannel::cueSheetEvent(int event)
1141 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1146 case eCueSheet::evtSeek:
1148 flushPVR(m_cue->m_decoding_demux);
1150 case eCueSheet::evtSkipmode:
1153 m_cue->m_lock.WrLock();
1154 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1155 m_cue->m_lock.Unlock();
1156 eRdLocker l(m_cue->m_lock);
1157 if (m_cue->m_skipmode_ratio)
1159 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1160 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1161 /* i agree that this might look a bit like black magic. */
1162 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1163 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1165 if (m_cue->m_skipmode_ratio < 0)
1166 m_skipmode_m -= m_skipmode_n;
1168 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1170 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1172 eWarning("something is wrong with this calculation");
1173 m_skipmode_n = m_skipmode_m = 0;
1177 eDebug("skipmode ratio is 0, normal play");
1178 m_skipmode_n = m_skipmode_m = 0;
1181 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1182 if (m_cue->m_skipmode_ratio != 0)
1183 m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1185 m_pvr_thread->setTimebaseChange(0); /* normal playback */
1186 eDebug("flush pvr");
1187 flushPVR(m_cue->m_decoding_demux);
1191 case eCueSheet::evtSpanChanged:
1193 m_source_span.clear();
1194 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1196 off_t offset_in, offset_out;
1197 pts_t pts_in = i->first, pts_out = i->second;
1198 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
1200 eDebug("span translation failed.\n");
1203 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
1204 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1211 /* align toward zero */
1212 static inline long long align(long long x, int align)
1227 /* remember, this gets called from another thread. */
1228 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
1230 const int blocksize = 188;
1231 unsigned int max = align(10*1024*1024, blocksize);
1232 current_offset = align(current_offset, blocksize);
1236 eDebug("no cue sheet. forcing normal play");
1237 start = current_offset;
1242 m_cue->m_lock.RdLock();
1243 if (!m_cue->m_decoding_demux)
1245 start = current_offset;
1247 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
1248 m_cue->m_lock.Unlock();
1254 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
1255 max = align(m_skipmode_n, blocksize);
1258 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1260 current_offset += align(m_skipmode_m, blocksize);
1262 while (!m_cue->m_seek_requests.empty())
1264 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1265 m_cue->m_lock.Unlock();
1266 m_cue->m_lock.WrLock();
1267 m_cue->m_seek_requests.pop_front();
1268 m_cue->m_lock.Unlock();
1269 m_cue->m_lock.RdLock();
1270 int relative = seek.first;
1271 pts_t pts = seek.second;
1276 if (!m_cue->m_decoder)
1278 eDebug("no decoder - can't seek relative");
1281 if (m_cue->m_decoder->getPTS(0, now))
1283 eDebug("decoder getPTS failed, can't seek relative");
1286 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1288 eDebug("seekTo: getCurrentPosition failed!");
1291 } else if (pts < 0) /* seek relative to end */
1294 if (!getLength(len))
1296 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1300 eWarning("getLength failed - can't seek relative to end!");
1305 if (relative == 1) /* pts relative */
1316 if (relative == 2) /* AP relative */
1318 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1320 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1322 pts = now - 90000; /* approx. 1s */
1323 eDebug("AP relative seeking failed!");
1326 eDebug("next ap is %llx\n", pts);
1332 if (m_tstools.getOffset(offset, pts))
1334 eDebug("get offset for pts=%lld failed!", pts);
1338 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1339 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1342 m_cue->m_lock.Unlock();
1344 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1346 long long aligned_start = align(i->first, blocksize);
1347 long long aligned_end = align(i->second, blocksize);
1349 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1351 start = current_offset;
1352 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1353 if ((aligned_end - current_offset) > max)
1356 size = aligned_end - current_offset;
1357 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1360 if (current_offset < aligned_start)
1362 /* ok, our current offset is in an 'out' zone. */
1363 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1365 /* in normal playback, just start at the next zone. */
1368 /* size is not 64bit! */
1369 if ((i->second - i->first) > max)
1372 size = aligned_end - aligned_start;
1375 if (m_skipmode_m < 0)
1377 eDebug("reached SOF");
1380 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1384 /* when skipping reverse, however, choose the zone before. */
1386 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1389 aligned_start = align(i->first, blocksize);
1390 aligned_end = align(i->second, blocksize);
1392 if ((aligned_end - aligned_start) > max)
1395 len = aligned_end - aligned_start;
1397 start = aligned_end - len;
1398 eDebug("skipping to %llx, %d", start, len);
1401 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1406 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1408 eDebug("reached SOF");
1410 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1413 start = current_offset;
1416 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
1420 void eDVBChannel::AddUse()
1422 if (++m_use_count > 1 && m_state == state_last_instance)
1425 m_stateChanged(this);
1429 void eDVBChannel::ReleaseUse()
1433 m_state = state_release;
1434 m_stateChanged(this);
1436 else if (m_use_count == 1)
1438 m_state = state_last_instance;
1439 m_stateChanged(this);
1443 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1446 m_mgr->removeChannel(this);
1453 eDebug("no frontend to tune!");
1457 m_channel_id = channelid;
1458 m_mgr->addChannel(channelid, this);
1459 m_state = state_tuning;
1460 /* if tuning fails, shutdown the channel immediately. */
1462 res = m_frontend->get().tune(*feparm);
1463 m_current_frontend_parameters = feparm;
1467 m_state = state_release;
1468 m_stateChanged(this);
1475 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1477 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1481 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1483 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1487 RESULT eDVBChannel::getState(int &state)
1493 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1498 void eDVBChannel::SDTready(int result)
1500 ePyObject args = PyTuple_New(2), ret;
1504 for (std::vector<ServiceDescriptionSection*>::const_iterator i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
1507 PyTuple_SET_ITEM(args, 0, PyInt_FromLong((*i)->getTransportStreamId()));
1508 PyTuple_SET_ITEM(args, 1, PyInt_FromLong((*i)->getOriginalNetworkId()));
1514 PyTuple_SET_ITEM(args, 0, Py_None);
1515 PyTuple_SET_ITEM(args, 1, Py_None);
1519 ret = PyObject_CallObject(m_tsid_onid_callback, args);
1523 Py_DECREF(m_tsid_onid_callback);
1524 m_tsid_onid_callback = ePyObject();
1525 m_tsid_onid_demux = 0;
1529 RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
1531 if (PyCallable_Check(callback))
1533 if (!getDemux(m_tsid_onid_demux, 0))
1535 m_SDT = new eTable<ServiceDescriptionSection>;
1536 CONNECT(m_SDT->tableReady, eDVBChannel::SDTready);
1537 if (m_SDT->start(m_tsid_onid_demux, eDVBSDTSpec()))
1539 m_tsid_onid_demux = 0;
1544 Py_INCREF(callback);
1545 m_tsid_onid_callback = callback;
1553 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1555 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1561 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1566 /* don't hold a reference to the decoding demux, we don't need it. */
1568 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1569 the refcount is lost. thus, decoding demuxes are never allocated.
1571 this poses a big problem for PiP. */
1572 if (cap & capDecode)
1577 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1582 frontend = &m_frontend->get();
1588 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1590 param = m_current_frontend_parameters;
1594 RESULT eDVBChannel::playFile(const char *file)
1596 ASSERT(!m_frontend);
1599 m_pvr_thread->stop();
1600 delete m_pvr_thread;
1604 m_tstools.openFile(file);
1606 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1607 THEN DO A REAL FIX HERE! */
1609 /* (this codepath needs to be improved anyway.) */
1610 #if HAVE_DVB_API_VERSION < 3
1611 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1613 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1615 if (m_pvr_fd_dst < 0)
1617 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1621 m_pvr_thread = new eDVBChannelFilePush();
1622 m_pvr_thread->enablePVRCommit(1);
1623 m_pvr_thread->setStreamMode(1);
1624 m_pvr_thread->setScatterGather(this);
1626 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1628 delete m_pvr_thread;
1630 eDebug("can't open PVR file %s (%m)", file);
1633 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1636 m_stateChanged(this);
1641 void eDVBChannel::stopFile()
1645 m_pvr_thread->stop();
1646 ::close(m_pvr_fd_dst);
1647 delete m_pvr_thread;
1652 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1654 m_conn_cueSheetEvent = 0;
1657 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1660 RESULT eDVBChannel::getLength(pts_t &len)
1662 return m_tstools.calcLen(len);
1665 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1667 if (!decoding_demux)
1674 if (mode == 0) /* demux */
1676 r = decoding_demux->getSTC(now, 0);
1679 eDebug("demux getSTC failed");
1683 now = pos; /* fixup supplied */
1685 off_t off = 0; /* TODO: fixme */
1686 r = m_tstools.fixupPTS(off, now);
1689 eDebug("fixup PTS failed");
1698 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1700 /* when seeking, we have to ensure that all buffers are flushed.
1701 there are basically 3 buffers:
1702 a.) the filepush's internal buffer
1703 b.) the PVR buffer (before demux)
1704 c.) the ratebuffer (after demux)
1706 it's important to clear them in the correct order, otherwise
1707 the ratebuffer (for example) would immediately refill from
1708 the not-yet-flushed PVR buffer.
1711 m_pvr_thread->pause();
1712 /* flush internal filepush buffer */
1713 m_pvr_thread->flush();
1714 /* HACK: flush PVR buffer */
1715 ::ioctl(m_pvr_fd_dst, 0);
1717 /* flush ratebuffers (video, audio) */
1719 decoding_demux->flush();
1721 /* demux will also flush all decoder.. */
1722 /* resume will re-query the SG */
1723 m_pvr_thread->resume();
1726 DEFINE_REF(eCueSheet);
1728 eCueSheet::eCueSheet()
1730 m_skipmode_ratio = 0;
1733 void eCueSheet::seekTo(int relative, const pts_t &pts)
1736 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1741 void eCueSheet::clear()
1748 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1750 assert(begin < end);
1752 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1756 void eCueSheet::commitSpans()
1758 m_event(evtSpanChanged);
1761 void eCueSheet::setSkipmode(const pts_t &ratio)
1764 m_skipmode_ratio = ratio;
1766 m_event(evtSkipmode);
1769 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1771 m_decoding_demux = demux;
1772 m_decoder = decoder;
1775 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1777 connection = new eConnection(this, m_event.connect(event));