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() == 3) // dm800 / 500hd
434 for (; i != m_demux.end(); ++i, ++n)
441 else if (i->m_adapter == fe->m_adapter &&
442 i->m_demux->getSource() == fe->m_frontend->getDVBID())
444 demux = new eDVBAllocatedDemux(i);
450 else if (m_demux.size() < 5) // ATI
452 /* FIXME: hardware demux policy */
453 if (!(cap & iDVBChannel::capDecode))
455 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
462 for (; i != m_demux.end(); ++i, ++n)
464 int is_decode = n < 2;
466 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
468 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
470 if ((cap & iDVBChannel::capDecode) && !is_decode)
477 else // we asume dm8000
479 for (; i != m_demux.end(); ++i, ++n)
488 else if (i->m_adapter == fe->m_adapter &&
489 i->m_demux->getSource() == fe->m_frontend->getDVBID())
491 demux = new eDVBAllocatedDemux(i);
495 else if (n == 4) // always use demux4 for PVR (demux 4 can not descramble...)
498 demux = new eDVBAllocatedDemux(i);
508 demux = new eDVBAllocatedDemux(unused);
510 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
512 demux->get().setSourcePVR(0);
516 eDebug("demux not found");
520 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
526 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
535 #define eDebugNoSimulate(x...) \
542 // eDebugNoNewLine("SIMULATE:"); \
547 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate)
549 /* first, check if a channel is already existing. */
550 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
552 if (!simulate && m_cached_channel)
554 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
555 if(channelid==cache_chan->getChannelID())
557 eDebug("use cached_channel");
558 channel = m_cached_channel;
561 m_cached_channel_state_changed_conn.disconnect();
563 m_releaseCachedChannelTimer->stop();
566 eDebugNoSimulate("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
567 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
569 eDebugNoSimulate("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
570 if (i->m_channel_id == channelid)
572 eDebugNoSimulate("found shared channel..");
573 channel = i->m_channel;
578 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
582 eDebugNoSimulate("no channel list set!");
583 return errNoChannelList;
586 ePtr<iDVBFrontendParameters> feparm;
587 if (m_list->getChannelFrontendData(channelid, feparm))
589 eDebugNoSimulate("channel not found!");
590 return errChannelNotInList;
593 /* allocate a frontend. */
595 ePtr<eDVBAllocatedFrontend> fe;
597 int err = allocateFrontend(fe, feparm, simulate);
602 ePtr<eDVBChannel> ch = new eDVBChannel(this, fe);
604 res = ch->setChannel(channelid, feparm);
608 return errChidNotFound;
615 m_cached_channel = channel = ch;
616 m_cached_channel_state_changed_conn =
617 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
623 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
626 chan->getState(state);
629 case iDVBChannel::state_release:
630 case iDVBChannel::state_ok:
632 eDebug("stop release channel timer");
633 m_releaseCachedChannelTimer->stop();
636 case iDVBChannel::state_last_instance:
638 eDebug("start release channel timer");
639 m_releaseCachedChannelTimer->start(3000, true);
642 default: // ignore all other events
647 void eDVBResourceManager::releaseCachedChannel()
649 eDebug("release cached channel (timer timeout)");
653 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
655 ePtr<eDVBAllocatedFrontend> fe;
657 if (m_cached_channel)
659 m_cached_channel_state_changed_conn.disconnect();
661 m_releaseCachedChannelTimer->stop();
664 int err = allocateFrontendByIndex(fe, slot_index);
668 channel = new eDVBChannel(this, fe);
673 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
675 ePtr<eDVBAllocatedDemux> demux;
677 if (m_cached_channel && m_releaseCachedChannelTimer->isActive())
679 m_cached_channel_state_changed_conn.disconnect();
681 m_releaseCachedChannelTimer->stop();
684 channel = new eDVBChannel(this, 0);
688 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
690 ePtr<iDVBFrontend> fe;
691 if (!ch->getFrontend(fe))
693 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
694 if (frontend->is_simulate())
695 m_active_simulate_channels.push_back(active_channel(chid, ch));
698 m_active_channels.push_back(active_channel(chid, ch));
699 /* emit */ m_channelAdded(ch);
705 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
707 ePtr<iDVBFrontend> fe;
708 if (!ch->getFrontend(fe))
710 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
711 std::list<active_channel> &active_channels = frontend->is_simulate() ? m_active_simulate_channels : m_active_channels;
713 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end();)
715 if (i->m_channel == ch)
717 i = active_channels.erase(i);
729 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
731 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
735 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm, bool simulate)
737 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
738 ePtr<eDVBRegisteredFrontend> best;
741 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
744 int c = i->m_frontend->isCompatibleWith(feparm);
751 int tuner_type_channel_default(ePtr<iDVBChannelList> &channellist, const eDVBChannelID &chid)
755 ePtr<iDVBFrontendParameters> feparm;
756 if (!channellist->getChannelFrontendData(chid, feparm))
759 if (!feparm->getSystem(system))
763 case iDVBFrontend::feSatellite:
765 case iDVBFrontend::feCable:
767 case iDVBFrontend::feTerrestrial:
778 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, bool simulate)
780 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
782 if (!simulate && m_cached_channel)
784 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
785 if(channelid==cache_chan->getChannelID())
786 return tuner_type_channel_default(m_list, channelid);
789 /* first, check if a channel is already existing. */
790 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
791 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
793 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
794 if (i->m_channel_id == channelid)
796 // eDebug("found shared channel..");
797 return tuner_type_channel_default(m_list, channelid);
801 int *decremented_cached_channel_fe_usecount=NULL,
802 *decremented_fe_usecount=NULL;
804 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
806 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
807 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
808 if (i->m_channel_id == ignore)
810 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
811 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
812 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
813 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
814 // or 2 when the cached channel is not equal to the compared channel
815 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
817 ePtr<iDVBFrontend> fe;
818 if (!i->m_channel->getFrontend(fe))
820 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
822 if ( &(*fe) == &(*ii->m_frontend) )
825 decremented_fe_usecount = &ii->m_inuse;
826 if (channel == &(*m_cached_channel))
827 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
837 if (!decremented_cached_channel_fe_usecount)
839 if (m_cached_channel)
841 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
842 if (channel->getUseCount() == 1)
844 ePtr<iDVBFrontend> fe;
845 if (!channel->getFrontend(fe))
847 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
848 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
850 if ( &(*fe) == &(*ii->m_frontend) )
853 decremented_cached_channel_fe_usecount = &ii->m_inuse;
862 decremented_cached_channel_fe_usecount=NULL;
864 ePtr<iDVBFrontendParameters> feparm;
868 eDebug("no channel list set!");
872 if (m_list->getChannelFrontendData(channelid, feparm))
874 eDebug("channel not found!");
878 ret = canAllocateFrontend(feparm, simulate);
881 if (decremented_fe_usecount)
882 ++(*decremented_fe_usecount);
883 if (decremented_cached_channel_fe_usecount)
884 ++(*decremented_cached_channel_fe_usecount);
889 bool eDVBResourceManager::canMeasureFrontendInputPower()
891 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
893 return i->m_frontend->readInputpower() >= 0;
898 class eDVBChannelFilePush: public eFilePushThread
901 eDVBChannelFilePush() { setIFrameSearch(0); setTimebaseChange(0); }
902 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
904 /* "timebase change" is for doing trickmode playback at an exact speed, even when pictures are skipped. */
905 /* you need to set it to 1/16 if you want 16x playback, for example. you need video master sync. */
906 void setTimebaseChange(int ratio) { m_timebase_change = ratio; } /* 16bit fixpoint, 0 for disable */
908 int m_iframe_search, m_iframe_state, m_pid;
909 int m_timebase_change;
910 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
913 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
916 if (m_timebase_change)
918 eDebug("timebase change: %d", m_timebase_change);
920 for (offset = 0; offset < len; offset += 188)
922 unsigned char *pkt = (unsigned char*)_data + offset;
923 if (pkt[1] & 0x40) /* pusi */
925 if (pkt[3] & 0x20) // adaption field present?
926 pkt += pkt[4] + 4 + 1; /* skip adaption field and header */
928 pkt += 4; /* skip header */
929 if (pkt[0] || pkt[1] || (pkt[2] != 1))
931 eWarning("broken startcode");
937 if (pkt[7] & 0x80) // PTS present?
939 pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29;
940 pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22;
941 pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14;
942 pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7;
943 pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1;
947 RESULT r = m_tstools.fixupPTS(off, pts);
949 eWarning("fixup PTS while trickmode playback failed.\n");
952 int sec = pts / 90000;
953 int frm = pts % 90000;
961 // eDebug("original, fixed pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
964 pts *= m_timebase_change;
976 // eDebug("new pts (after timebase change): %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
984 pkt[9] |= (pts >> 29) & 0xE;
985 pkt[10] |= (pts >> 22) & 0xFF;
986 pkt[11] |= (pts >> 14) & 0xFE;
987 pkt[12] |= (pts >> 7) & 0xFF;
988 pkt[13] |= (pts << 1) & 0xFE;
996 if (!m_iframe_search)
999 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
1001 // eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
1003 unsigned char *d = data;
1004 while ((d + 3 < data + len) && (d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
1006 int offset = d - data;
1007 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
1008 unsigned char *ts = data + ts_offset;
1009 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
1011 if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid)) /* picture start */
1013 int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
1016 // eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
1018 if (m_iframe_state == 1)
1020 /* we are allowing data, and stop allowing data on the next frame.
1021 we now found a frame. so stop here. */
1022 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
1023 current_span_remaining = 0;
1025 unsigned char *fts = ts + 188;
1026 while (fts < (data + len))
1029 fts[2] |= 0xff; /* drop packet */
1033 return len; // ts_offset + 188; /* deliver this packet, but not more. */
1036 if (picture_type != 1) /* we are only interested in I frames */
1039 unsigned char *fts = data;
1043 fts[2] |= 0xff; /* drop packet */
1050 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
1052 /* verify that this is actually a PES header, not just some ES data */
1053 if (ts[1] & 0x40) /* PUSI set */
1055 int payload_start = 4;
1056 if (ts[3] & 0x20) /* adaptation field present */
1057 payload_start += ts[4] + 1; /* skip AF */
1058 if (payload_start == (offset%188)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */
1062 eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]);
1070 d += 4; /* ignore */
1073 if (m_iframe_state == 1)
1076 return 0; /* we need find an iframe first */
1082 DEFINE_REF(eDVBChannel);
1084 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1086 m_frontend = frontend;
1090 m_skipmode_n = m_skipmode_m = m_skipmode_frames = 0;
1093 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1096 eDVBChannel::~eDVBChannel()
1099 m_mgr->removeChannel(this);
1104 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1106 int state, ourstate = 0;
1108 /* if we are already in shutdown, don't change state. */
1109 if (m_state == state_release)
1112 if (fe->getState(state))
1115 if (state == iDVBFrontend::stateLock)
1117 eDebug("OURSTATE: ok");
1118 ourstate = state_ok;
1119 } else if (state == iDVBFrontend::stateTuning)
1121 eDebug("OURSTATE: tuning");
1122 ourstate = state_tuning;
1123 } else if (state == iDVBFrontend::stateLostLock)
1125 /* on managed channels, we try to retune in order to re-acquire lock. */
1126 if (m_current_frontend_parameters)
1128 eDebug("OURSTATE: lost lock, trying to retune");
1129 ourstate = state_tuning;
1130 m_frontend->get().tune(*m_current_frontend_parameters);
1132 /* on unmanaged channels, we don't do this. the client will do this. */
1134 eDebug("OURSTATE: lost lock, unavailable now.");
1135 ourstate = state_unavailable;
1137 } else if (state == iDVBFrontend::stateFailed)
1139 eDebug("OURSTATE: failed");
1140 ourstate = state_failed;
1142 eFatal("state unknown");
1144 if (ourstate != m_state)
1147 m_stateChanged(this);
1151 void eDVBChannel::pvrEvent(int event)
1155 case eFilePushThread::evtEOF:
1156 eDebug("eDVBChannel: End of file!");
1157 m_event(this, evtEOF);
1159 case eFilePushThread::evtUser: /* start */
1161 m_event(this, evtSOF);
1166 void eDVBChannel::cueSheetEvent(int event)
1168 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1173 case eCueSheet::evtSeek:
1175 flushPVR(m_cue->m_decoding_demux);
1177 case eCueSheet::evtSkipmode:
1180 m_cue->m_lock.WrLock();
1181 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1182 m_cue->m_lock.Unlock();
1183 eRdLocker l(m_cue->m_lock);
1184 if (m_cue->m_skipmode_ratio)
1186 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1187 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1188 /* i agree that this might look a bit like black magic. */
1189 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1190 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1191 m_skipmode_frames = m_cue->m_skipmode_ratio / 90000;
1192 m_skipmode_frames_remainder = 0;
1194 if (m_cue->m_skipmode_ratio < 0)
1195 m_skipmode_m -= m_skipmode_n;
1197 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1199 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1201 eWarning("something is wrong with this calculation");
1202 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1206 eDebug("skipmode ratio is 0, normal play");
1207 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1210 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1211 if (m_cue->m_skipmode_ratio != 0)
1212 m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1214 m_pvr_thread->setTimebaseChange(0); /* normal playback */
1215 eDebug("flush pvr");
1216 flushPVR(m_cue->m_decoding_demux);
1220 case eCueSheet::evtSpanChanged:
1222 m_source_span.clear();
1223 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1225 off_t offset_in, offset_out;
1226 pts_t pts_in = i->first, pts_out = i->second;
1227 if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
1229 eDebug("span translation failed.\n");
1232 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
1233 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1240 /* align toward zero */
1241 static inline long long align(long long x, int align)
1256 /* align toward zero */
1257 static inline long long align_with_len(long long x, int align, size_t &len)
1273 /* remember, this gets called from another thread. */
1274 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
1276 const int blocksize = 188;
1277 unsigned int max = align(10*1024*1024, blocksize);
1278 current_offset = align(current_offset, blocksize);
1282 eDebug("no cue sheet. forcing normal play");
1283 start = current_offset;
1288 m_cue->m_lock.RdLock();
1289 if (!m_cue->m_decoding_demux)
1291 start = current_offset;
1293 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
1294 m_cue->m_lock.Unlock();
1300 eDebug("skipmode %d:%d (x%d)", m_skipmode_m, m_skipmode_n, m_skipmode_frames);
1301 max = align(m_skipmode_n, blocksize);
1304 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1306 int frame_skip_success = 0;
1310 int frames_to_skip = m_skipmode_frames + m_skipmode_frames_remainder;
1311 eDebug("we are at %llx, and we try to skip %d+%d frames from here", current_offset, m_skipmode_frames, m_skipmode_frames_remainder);
1313 off_t iframe_start = current_offset;
1314 int frames_skipped = frames_to_skip;
1315 if (!m_tstools.findNextPicture(iframe_start, iframe_len, frames_skipped))
1317 m_skipmode_frames_remainder = frames_to_skip - frames_skipped;
1318 eDebug("successfully skipped %d (out of %d, rem now %d) frames.", frames_skipped, frames_to_skip, m_skipmode_frames_remainder);
1319 current_offset = align_with_len(iframe_start, blocksize, iframe_len);
1320 max = align(iframe_len + 187, blocksize);
1321 frame_skip_success = 1;
1324 m_skipmode_frames_remainder = 0;
1325 eDebug("frame skipping failed, reverting to byte-skipping");
1329 if (!frame_skip_success)
1331 current_offset += align(m_skipmode_m, blocksize);
1335 eDebug("we are at %llx, and we try to find the iframe here:", current_offset);
1337 off_t iframe_start = current_offset;
1339 int direction = (m_skipmode_m < 0) ? -1 : +1;
1340 if (m_tstools.findFrame(iframe_start, iframe_len, direction))
1344 current_offset = align_with_len(iframe_start, blocksize, iframe_len);
1345 max = align(iframe_len, blocksize);
1350 while (!m_cue->m_seek_requests.empty())
1352 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1353 m_cue->m_lock.Unlock();
1354 m_cue->m_lock.WrLock();
1355 m_cue->m_seek_requests.pop_front();
1356 m_cue->m_lock.Unlock();
1357 m_cue->m_lock.RdLock();
1358 int relative = seek.first;
1359 pts_t pts = seek.second;
1364 if (!m_cue->m_decoder)
1366 eDebug("no decoder - can't seek relative");
1369 if (m_cue->m_decoder->getPTS(0, now))
1371 eDebug("decoder getPTS failed, can't seek relative");
1374 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1376 eDebug("seekTo: getCurrentPosition failed!");
1379 } else if (pts < 0) /* seek relative to end */
1382 if (!getLength(len))
1384 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1388 eWarning("getLength failed - can't seek relative to end!");
1393 if (relative == 1) /* pts relative */
1404 if (relative == 2) /* AP relative */
1406 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1408 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1410 pts = now - 90000; /* approx. 1s */
1411 eDebug("AP relative seeking failed!");
1415 eDebug("next ap is %llx\n", pts);
1420 if (m_tstools.getOffset(offset, pts, -1))
1422 eDebug("get offset for pts=%lld failed!", pts);
1427 /* try to align to iframe */
1428 int direction = pts < 0 ? -1 : 1;
1429 m_tstools.findFrame(offset, iframe_len, direction);
1431 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
1432 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1435 m_cue->m_lock.Unlock();
1437 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1439 long long aligned_start = align(i->first, blocksize);
1440 long long aligned_end = align(i->second, blocksize);
1442 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1444 start = current_offset;
1445 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1446 if ((aligned_end - current_offset) > max)
1449 size = aligned_end - current_offset;
1450 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1453 if (current_offset < aligned_start)
1455 /* ok, our current offset is in an 'out' zone. */
1456 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1458 /* in normal playback, just start at the next zone. */
1461 /* size is not 64bit! */
1462 if ((i->second - i->first) > max)
1465 size = aligned_end - aligned_start;
1468 if (m_skipmode_m < 0)
1470 eDebug("reached SOF");
1473 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1477 /* when skipping reverse, however, choose the zone before. */
1479 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1482 aligned_start = align(i->first, blocksize);
1483 aligned_end = align(i->second, blocksize);
1485 if ((aligned_end - aligned_start) > max)
1488 len = aligned_end - aligned_start;
1490 start = aligned_end - len;
1491 eDebug("skipping to %llx, %d", start, len);
1494 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1499 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1501 eDebug("reached SOF");
1503 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1506 if (m_source_span.empty())
1508 start = current_offset;
1510 eDebug("NO CUESHEET. (%08llx, %d)", start, size);
1513 start = current_offset;
1519 void eDVBChannel::AddUse()
1521 if (++m_use_count > 1 && m_state == state_last_instance)
1524 m_stateChanged(this);
1528 void eDVBChannel::ReleaseUse()
1532 m_state = state_release;
1533 m_stateChanged(this);
1535 else if (m_use_count == 1)
1537 m_state = state_last_instance;
1538 m_stateChanged(this);
1542 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1545 m_mgr->removeChannel(this);
1552 eDebug("no frontend to tune!");
1556 m_channel_id = channelid;
1557 m_mgr->addChannel(channelid, this);
1558 m_state = state_tuning;
1559 /* if tuning fails, shutdown the channel immediately. */
1561 res = m_frontend->get().tune(*feparm);
1562 m_current_frontend_parameters = feparm;
1566 m_state = state_release;
1567 m_stateChanged(this);
1574 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1576 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1580 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1582 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1586 RESULT eDVBChannel::getState(int &state)
1592 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1597 void eDVBChannel::SDTready(int result)
1599 ePyObject args = PyTuple_New(2), ret;
1603 for (std::vector<ServiceDescriptionSection*>::const_iterator i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
1606 PyTuple_SET_ITEM(args, 0, PyInt_FromLong((*i)->getTransportStreamId()));
1607 PyTuple_SET_ITEM(args, 1, PyInt_FromLong((*i)->getOriginalNetworkId()));
1613 PyTuple_SET_ITEM(args, 0, Py_None);
1614 PyTuple_SET_ITEM(args, 1, Py_None);
1618 ret = PyObject_CallObject(m_tsid_onid_callback, args);
1622 Py_DECREF(m_tsid_onid_callback);
1623 m_tsid_onid_callback = ePyObject();
1624 m_tsid_onid_demux = 0;
1628 RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
1630 if (PyCallable_Check(callback))
1632 if (!getDemux(m_tsid_onid_demux, 0))
1634 m_SDT = new eTable<ServiceDescriptionSection>;
1635 CONNECT(m_SDT->tableReady, eDVBChannel::SDTready);
1636 if (m_SDT->start(m_tsid_onid_demux, eDVBSDTSpec()))
1638 m_tsid_onid_demux = 0;
1643 Py_INCREF(callback);
1644 m_tsid_onid_callback = callback;
1652 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1654 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1660 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1665 /* don't hold a reference to the decoding demux, we don't need it. */
1667 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1668 the refcount is lost. thus, decoding demuxes are never allocated.
1670 this poses a big problem for PiP. */
1671 if (cap & capDecode)
1676 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1681 frontend = &m_frontend->get();
1687 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1689 param = m_current_frontend_parameters;
1693 RESULT eDVBChannel::playFile(const char *file)
1695 ASSERT(!m_frontend);
1698 m_pvr_thread->stop();
1699 delete m_pvr_thread;
1703 m_tstools.openFile(file);
1705 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1706 THEN DO A REAL FIX HERE! */
1708 /* (this codepath needs to be improved anyway.) */
1709 #if HAVE_DVB_API_VERSION < 3
1710 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1712 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1714 if (m_pvr_fd_dst < 0)
1716 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1720 m_pvr_thread = new eDVBChannelFilePush();
1721 m_pvr_thread->enablePVRCommit(1);
1722 m_pvr_thread->setStreamMode(1);
1723 m_pvr_thread->setScatterGather(this);
1725 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1727 delete m_pvr_thread;
1729 eDebug("can't open PVR file %s (%m)", file);
1732 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1735 m_stateChanged(this);
1740 void eDVBChannel::stopFile()
1744 m_pvr_thread->stop();
1745 ::close(m_pvr_fd_dst);
1746 delete m_pvr_thread;
1751 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1753 m_conn_cueSheetEvent = 0;
1756 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1759 RESULT eDVBChannel::getLength(pts_t &len)
1761 return m_tstools.calcLen(len);
1764 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1766 if (!decoding_demux)
1773 if (mode == 0) /* demux */
1775 r = decoding_demux->getSTC(now, 0);
1778 eDebug("demux getSTC failed");
1782 now = pos; /* fixup supplied */
1784 off_t off = 0; /* TODO: fixme */
1785 r = m_tstools.fixupPTS(off, now);
1788 eDebug("fixup PTS failed");
1797 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1799 /* when seeking, we have to ensure that all buffers are flushed.
1800 there are basically 3 buffers:
1801 a.) the filepush's internal buffer
1802 b.) the PVR buffer (before demux)
1803 c.) the ratebuffer (after demux)
1805 it's important to clear them in the correct order, otherwise
1806 the ratebuffer (for example) would immediately refill from
1807 the not-yet-flushed PVR buffer.
1810 m_pvr_thread->pause();
1811 /* flush internal filepush buffer */
1812 m_pvr_thread->flush();
1813 /* HACK: flush PVR buffer */
1814 ::ioctl(m_pvr_fd_dst, 0);
1816 /* flush ratebuffers (video, audio) */
1818 decoding_demux->flush();
1820 /* demux will also flush all decoder.. */
1821 /* resume will re-query the SG */
1822 m_pvr_thread->resume();
1825 DEFINE_REF(eCueSheet);
1827 eCueSheet::eCueSheet()
1829 m_skipmode_ratio = 0;
1832 void eCueSheet::seekTo(int relative, const pts_t &pts)
1835 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1840 void eCueSheet::clear()
1847 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1849 ASSERT(begin < end);
1851 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1855 void eCueSheet::commitSpans()
1857 m_event(evtSpanChanged);
1860 void eCueSheet::setSkipmode(const pts_t &ratio)
1863 m_skipmode_ratio = ratio;
1865 m_event(evtSkipmode);
1868 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1870 m_decoding_demux = demux;
1871 m_decoder = decoder;
1874 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1876 connection = new eConnection(this, m_event.connect(event));