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)
445 if (i->m_adapter == fe->m_adapter &&
446 i->m_demux->getSource() == fe->m_frontend->getDVBID())
448 demux = new eDVBAllocatedDemux(i);
452 else if (i->m_demux->getSource() == -1) // PVR
454 demux = new eDVBAllocatedDemux(i);
460 else if (m_demux.size() < 5) // ATI
462 /* FIXME: hardware demux policy */
463 if (!(cap & iDVBChannel::capDecode))
465 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
472 for (; i != m_demux.end(); ++i, ++n)
474 int is_decode = n < 2;
476 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
478 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
480 if ((cap & iDVBChannel::capDecode) && !is_decode)
487 else // we asume dm8000
489 for (; i != m_demux.end(); ++i, ++n)
498 else if (i->m_adapter == fe->m_adapter &&
499 i->m_demux->getSource() == fe->m_frontend->getDVBID())
501 demux = new eDVBAllocatedDemux(i);
505 else if (n == 4) // always use demux4 for PVR (demux 4 can not descramble...)
508 demux = new eDVBAllocatedDemux(i);
518 demux = new eDVBAllocatedDemux(unused);
520 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
522 demux->get().setSourcePVR(0);
526 eDebug("demux not found");
530 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
536 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
545 #define eDebugNoSimulate(x...) \
552 // eDebugNoNewLine("SIMULATE:"); \
557 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate)
559 /* first, check if a channel is already existing. */
560 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
562 if (!simulate && m_cached_channel)
564 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
565 if(channelid==cache_chan->getChannelID())
567 eDebug("use cached_channel");
568 channel = m_cached_channel;
571 m_cached_channel_state_changed_conn.disconnect();
573 m_releaseCachedChannelTimer->stop();
576 eDebugNoSimulate("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
577 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
579 eDebugNoSimulate("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
580 if (i->m_channel_id == channelid)
582 eDebugNoSimulate("found shared channel..");
583 channel = i->m_channel;
588 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
592 eDebugNoSimulate("no channel list set!");
593 return errNoChannelList;
596 ePtr<iDVBFrontendParameters> feparm;
597 if (m_list->getChannelFrontendData(channelid, feparm))
599 eDebugNoSimulate("channel not found!");
600 return errChannelNotInList;
603 /* allocate a frontend. */
605 ePtr<eDVBAllocatedFrontend> fe;
607 int err = allocateFrontend(fe, feparm, simulate);
612 ePtr<eDVBChannel> ch = new eDVBChannel(this, fe);
614 res = ch->setChannel(channelid, feparm);
618 return errChidNotFound;
625 m_cached_channel = channel = ch;
626 m_cached_channel_state_changed_conn =
627 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
633 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
636 chan->getState(state);
639 case iDVBChannel::state_release:
640 case iDVBChannel::state_ok:
642 eDebug("stop release channel timer");
643 m_releaseCachedChannelTimer->stop();
646 case iDVBChannel::state_last_instance:
648 eDebug("start release channel timer");
649 m_releaseCachedChannelTimer->start(3000, true);
652 default: // ignore all other events
657 void eDVBResourceManager::releaseCachedChannel()
659 eDebug("release cached channel (timer timeout)");
663 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
665 ePtr<eDVBAllocatedFrontend> fe;
667 if (m_cached_channel)
669 m_cached_channel_state_changed_conn.disconnect();
671 m_releaseCachedChannelTimer->stop();
674 int err = allocateFrontendByIndex(fe, slot_index);
678 channel = new eDVBChannel(this, fe);
683 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
685 ePtr<eDVBAllocatedDemux> demux;
687 if (m_cached_channel && m_releaseCachedChannelTimer->isActive())
689 m_cached_channel_state_changed_conn.disconnect();
691 m_releaseCachedChannelTimer->stop();
694 channel = new eDVBChannel(this, 0);
698 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
700 ePtr<iDVBFrontend> fe;
701 if (!ch->getFrontend(fe))
703 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
704 if (frontend->is_simulate())
705 m_active_simulate_channels.push_back(active_channel(chid, ch));
708 m_active_channels.push_back(active_channel(chid, ch));
709 /* emit */ m_channelAdded(ch);
715 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
717 ePtr<iDVBFrontend> fe;
718 if (!ch->getFrontend(fe))
720 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
721 std::list<active_channel> &active_channels = frontend->is_simulate() ? m_active_simulate_channels : m_active_channels;
723 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end();)
725 if (i->m_channel == ch)
727 i = active_channels.erase(i);
739 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
741 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
745 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm, bool simulate)
747 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
748 ePtr<eDVBRegisteredFrontend> best;
751 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
754 int c = i->m_frontend->isCompatibleWith(feparm);
761 int tuner_type_channel_default(ePtr<iDVBChannelList> &channellist, const eDVBChannelID &chid)
765 ePtr<iDVBFrontendParameters> feparm;
766 if (!channellist->getChannelFrontendData(chid, feparm))
769 if (!feparm->getSystem(system))
773 case iDVBFrontend::feSatellite:
775 case iDVBFrontend::feCable:
777 case iDVBFrontend::feTerrestrial:
788 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, bool simulate)
790 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
792 if (!simulate && m_cached_channel)
794 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
795 if(channelid==cache_chan->getChannelID())
796 return tuner_type_channel_default(m_list, channelid);
799 /* first, check if a channel is already existing. */
800 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
801 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
803 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
804 if (i->m_channel_id == channelid)
806 // eDebug("found shared channel..");
807 return tuner_type_channel_default(m_list, channelid);
811 int *decremented_cached_channel_fe_usecount=NULL,
812 *decremented_fe_usecount=NULL;
814 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
816 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
817 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
818 if (i->m_channel_id == ignore)
820 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
821 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
822 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
823 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
824 // or 2 when the cached channel is not equal to the compared channel
825 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
827 ePtr<iDVBFrontend> fe;
828 if (!i->m_channel->getFrontend(fe))
830 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
832 if ( &(*fe) == &(*ii->m_frontend) )
835 decremented_fe_usecount = &ii->m_inuse;
836 if (channel == &(*m_cached_channel))
837 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
847 if (!decremented_cached_channel_fe_usecount)
849 if (m_cached_channel)
851 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
852 if (channel->getUseCount() == 1)
854 ePtr<iDVBFrontend> fe;
855 if (!channel->getFrontend(fe))
857 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
858 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(frontends.begin()); ii != frontends.end(); ++ii)
860 if ( &(*fe) == &(*ii->m_frontend) )
863 decremented_cached_channel_fe_usecount = &ii->m_inuse;
872 decremented_cached_channel_fe_usecount=NULL;
874 ePtr<iDVBFrontendParameters> feparm;
878 eDebug("no channel list set!");
882 if (m_list->getChannelFrontendData(channelid, feparm))
884 eDebug("channel not found!");
888 ret = canAllocateFrontend(feparm, simulate);
891 if (decremented_fe_usecount)
892 ++(*decremented_fe_usecount);
893 if (decremented_cached_channel_fe_usecount)
894 ++(*decremented_cached_channel_fe_usecount);
899 bool eDVBResourceManager::canMeasureFrontendInputPower()
901 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
903 return i->m_frontend->readInputpower() >= 0;
908 class eDVBChannelFilePush: public eFilePushThread
911 eDVBChannelFilePush() { setIFrameSearch(0); setTimebaseChange(0); }
912 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
914 /* "timebase change" is for doing trickmode playback at an exact speed, even when pictures are skipped. */
915 /* you need to set it to 1/16 if you want 16x playback, for example. you need video master sync. */
916 void setTimebaseChange(int ratio) { m_timebase_change = ratio; } /* 16bit fixpoint, 0 for disable */
918 int m_iframe_search, m_iframe_state, m_pid;
919 int m_timebase_change;
920 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
923 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
926 if (m_timebase_change)
928 eDebug("timebase change: %d", m_timebase_change);
930 for (offset = 0; offset < len; offset += 188)
932 unsigned char *pkt = (unsigned char*)_data + offset;
933 if (pkt[1] & 0x40) /* pusi */
935 if (pkt[3] & 0x20) // adaption field present?
936 pkt += pkt[4] + 4 + 1; /* skip adaption field and header */
938 pkt += 4; /* skip header */
939 if (pkt[0] || pkt[1] || (pkt[2] != 1))
941 eWarning("broken startcode");
947 if (pkt[7] & 0x80) // PTS present?
949 pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29;
950 pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22;
951 pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14;
952 pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7;
953 pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1;
957 RESULT r = m_tstools.fixupPTS(off, pts);
959 eWarning("fixup PTS while trickmode playback failed.\n");
962 int sec = pts / 90000;
963 int frm = pts % 90000;
971 // eDebug("original, fixed pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
974 pts *= m_timebase_change;
986 // eDebug("new pts (after timebase change): %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
994 pkt[9] |= (pts >> 29) & 0xE;
995 pkt[10] |= (pts >> 22) & 0xFF;
996 pkt[11] |= (pts >> 14) & 0xFE;
997 pkt[12] |= (pts >> 7) & 0xFF;
998 pkt[13] |= (pts << 1) & 0xFE;
1006 if (!m_iframe_search)
1009 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
1011 // eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
1013 unsigned char *d = data;
1014 while ((d + 3 < data + len) && (d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
1016 int offset = d - data;
1017 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
1018 unsigned char *ts = data + ts_offset;
1019 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
1021 if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid)) /* picture start */
1023 int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
1026 // eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
1028 if (m_iframe_state == 1)
1030 /* we are allowing data, and stop allowing data on the next frame.
1031 we now found a frame. so stop here. */
1032 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
1033 current_span_remaining = 0;
1035 unsigned char *fts = ts + 188;
1036 while (fts < (data + len))
1039 fts[2] |= 0xff; /* drop packet */
1043 return len; // ts_offset + 188; /* deliver this packet, but not more. */
1046 if (picture_type != 1) /* we are only interested in I frames */
1049 unsigned char *fts = data;
1053 fts[2] |= 0xff; /* drop packet */
1060 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
1062 /* verify that this is actually a PES header, not just some ES data */
1063 if (ts[1] & 0x40) /* PUSI set */
1065 int payload_start = 4;
1066 if (ts[3] & 0x20) /* adaptation field present */
1067 payload_start += ts[4] + 1; /* skip AF */
1068 if (payload_start == (offset%188)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */
1072 eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]);
1080 d += 4; /* ignore */
1083 if (m_iframe_state == 1)
1086 return 0; /* we need find an iframe first */
1092 DEFINE_REF(eDVBChannel);
1094 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1096 m_frontend = frontend;
1100 m_skipmode_n = m_skipmode_m = m_skipmode_frames = 0;
1103 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1106 eDVBChannel::~eDVBChannel()
1109 m_mgr->removeChannel(this);
1114 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1116 int state, ourstate = 0;
1118 /* if we are already in shutdown, don't change state. */
1119 if (m_state == state_release)
1122 if (fe->getState(state))
1125 if (state == iDVBFrontend::stateLock)
1127 eDebug("OURSTATE: ok");
1128 ourstate = state_ok;
1129 } else if (state == iDVBFrontend::stateTuning)
1131 eDebug("OURSTATE: tuning");
1132 ourstate = state_tuning;
1133 } else if (state == iDVBFrontend::stateLostLock)
1135 /* on managed channels, we try to retune in order to re-acquire lock. */
1136 if (m_current_frontend_parameters)
1138 eDebug("OURSTATE: lost lock, trying to retune");
1139 ourstate = state_tuning;
1140 m_frontend->get().tune(*m_current_frontend_parameters);
1142 /* on unmanaged channels, we don't do this. the client will do this. */
1144 eDebug("OURSTATE: lost lock, unavailable now.");
1145 ourstate = state_unavailable;
1147 } else if (state == iDVBFrontend::stateFailed)
1149 eDebug("OURSTATE: failed");
1150 ourstate = state_failed;
1152 eFatal("state unknown");
1154 if (ourstate != m_state)
1157 m_stateChanged(this);
1161 void eDVBChannel::pvrEvent(int event)
1165 case eFilePushThread::evtEOF:
1166 eDebug("eDVBChannel: End of file!");
1167 m_event(this, evtEOF);
1169 case eFilePushThread::evtUser: /* start */
1171 m_event(this, evtSOF);
1176 void eDVBChannel::cueSheetEvent(int event)
1178 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1183 case eCueSheet::evtSeek:
1185 flushPVR(m_cue->m_decoding_demux);
1187 case eCueSheet::evtSkipmode:
1190 m_cue->m_lock.WrLock();
1191 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1192 m_cue->m_lock.Unlock();
1193 eRdLocker l(m_cue->m_lock);
1194 if (m_cue->m_skipmode_ratio)
1196 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1197 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1198 /* i agree that this might look a bit like black magic. */
1199 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1200 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1201 m_skipmode_frames = m_cue->m_skipmode_ratio / 90000;
1202 m_skipmode_frames_remainder = 0;
1204 if (m_cue->m_skipmode_ratio < 0)
1205 m_skipmode_m -= m_skipmode_n;
1207 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1209 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1211 eWarning("something is wrong with this calculation");
1212 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1216 eDebug("skipmode ratio is 0, normal play");
1217 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1220 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1221 if (m_cue->m_skipmode_ratio != 0)
1222 m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1224 m_pvr_thread->setTimebaseChange(0); /* normal playback */
1225 eDebug("flush pvr");
1226 flushPVR(m_cue->m_decoding_demux);
1230 case eCueSheet::evtSpanChanged:
1232 m_source_span.clear();
1233 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1235 off_t offset_in, offset_out;
1236 pts_t pts_in = i->first, pts_out = i->second;
1237 if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
1239 eDebug("span translation failed.\n");
1242 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
1243 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1250 /* align toward zero */
1251 static inline long long align(long long x, int align)
1266 /* align toward zero */
1267 static inline long long align_with_len(long long x, int align, size_t &len)
1283 /* remember, this gets called from another thread. */
1284 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
1286 const int blocksize = 188;
1287 unsigned int max = align(10*1024*1024, blocksize);
1288 current_offset = align(current_offset, blocksize);
1292 eDebug("no cue sheet. forcing normal play");
1293 start = current_offset;
1298 m_cue->m_lock.RdLock();
1299 if (!m_cue->m_decoding_demux)
1301 start = current_offset;
1303 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
1304 m_cue->m_lock.Unlock();
1310 eDebug("skipmode %d:%d (x%d)", m_skipmode_m, m_skipmode_n, m_skipmode_frames);
1311 max = align(m_skipmode_n, blocksize);
1314 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1316 int frame_skip_success = 0;
1320 int frames_to_skip = m_skipmode_frames + m_skipmode_frames_remainder;
1321 eDebug("we are at %llx, and we try to skip %d+%d frames from here", current_offset, m_skipmode_frames, m_skipmode_frames_remainder);
1323 off_t iframe_start = current_offset;
1324 int frames_skipped = frames_to_skip;
1325 if (!m_tstools.findNextPicture(iframe_start, iframe_len, frames_skipped))
1327 m_skipmode_frames_remainder = frames_to_skip - frames_skipped;
1328 eDebug("successfully skipped %d (out of %d, rem now %d) frames.", frames_skipped, frames_to_skip, m_skipmode_frames_remainder);
1329 current_offset = align_with_len(iframe_start, blocksize, iframe_len);
1330 max = align(iframe_len + 187, blocksize);
1331 frame_skip_success = 1;
1334 m_skipmode_frames_remainder = 0;
1335 eDebug("frame skipping failed, reverting to byte-skipping");
1339 if (!frame_skip_success)
1341 current_offset += align(m_skipmode_m, blocksize);
1345 eDebug("we are at %llx, and we try to find the iframe here:", current_offset);
1347 off_t iframe_start = current_offset;
1349 int direction = (m_skipmode_m < 0) ? -1 : +1;
1350 if (m_tstools.findFrame(iframe_start, iframe_len, direction))
1354 current_offset = align_with_len(iframe_start, blocksize, iframe_len);
1355 max = align(iframe_len, blocksize);
1360 while (!m_cue->m_seek_requests.empty())
1362 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1363 m_cue->m_lock.Unlock();
1364 m_cue->m_lock.WrLock();
1365 m_cue->m_seek_requests.pop_front();
1366 m_cue->m_lock.Unlock();
1367 m_cue->m_lock.RdLock();
1368 int relative = seek.first;
1369 pts_t pts = seek.second;
1374 if (!m_cue->m_decoder)
1376 eDebug("no decoder - can't seek relative");
1379 if (m_cue->m_decoder->getPTS(0, now))
1381 eDebug("decoder getPTS failed, can't seek relative");
1384 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1386 eDebug("seekTo: getCurrentPosition failed!");
1389 } else if (pts < 0) /* seek relative to end */
1392 if (!getLength(len))
1394 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1398 eWarning("getLength failed - can't seek relative to end!");
1403 if (relative == 1) /* pts relative */
1414 if (relative == 2) /* AP relative */
1416 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1418 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1420 pts = now - 90000; /* approx. 1s */
1421 eDebug("AP relative seeking failed!");
1425 eDebug("next ap is %llx\n", pts);
1430 if (m_tstools.getOffset(offset, pts, -1))
1432 eDebug("get offset for pts=%lld failed!", pts);
1437 /* try to align to iframe */
1438 int direction = pts < 0 ? -1 : 1;
1439 m_tstools.findFrame(offset, iframe_len, direction);
1441 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
1442 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1445 m_cue->m_lock.Unlock();
1447 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1449 long long aligned_start = align(i->first, blocksize);
1450 long long aligned_end = align(i->second, blocksize);
1452 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1454 start = current_offset;
1455 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1456 if ((aligned_end - current_offset) > max)
1459 size = aligned_end - current_offset;
1460 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1463 if (current_offset < aligned_start)
1465 /* ok, our current offset is in an 'out' zone. */
1466 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1468 /* in normal playback, just start at the next zone. */
1471 /* size is not 64bit! */
1472 if ((i->second - i->first) > max)
1475 size = aligned_end - aligned_start;
1478 if (m_skipmode_m < 0)
1480 eDebug("reached SOF");
1483 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1487 /* when skipping reverse, however, choose the zone before. */
1489 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1492 aligned_start = align(i->first, blocksize);
1493 aligned_end = align(i->second, blocksize);
1495 if ((aligned_end - aligned_start) > max)
1498 len = aligned_end - aligned_start;
1500 start = aligned_end - len;
1501 eDebug("skipping to %llx, %d", start, len);
1504 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1509 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1511 eDebug("reached SOF");
1513 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1516 if (m_source_span.empty())
1518 start = current_offset;
1520 eDebug("NO CUESHEET. (%08llx, %d)", start, size);
1523 start = current_offset;
1529 void eDVBChannel::AddUse()
1531 if (++m_use_count > 1 && m_state == state_last_instance)
1534 m_stateChanged(this);
1538 void eDVBChannel::ReleaseUse()
1542 m_state = state_release;
1543 m_stateChanged(this);
1545 else if (m_use_count == 1)
1547 m_state = state_last_instance;
1548 m_stateChanged(this);
1552 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1555 m_mgr->removeChannel(this);
1562 eDebug("no frontend to tune!");
1566 m_channel_id = channelid;
1567 m_mgr->addChannel(channelid, this);
1568 m_state = state_tuning;
1569 /* if tuning fails, shutdown the channel immediately. */
1571 res = m_frontend->get().tune(*feparm);
1572 m_current_frontend_parameters = feparm;
1576 m_state = state_release;
1577 m_stateChanged(this);
1584 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1586 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1590 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1592 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1596 RESULT eDVBChannel::getState(int &state)
1602 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1607 void eDVBChannel::SDTready(int result)
1609 ePyObject args = PyTuple_New(2), ret;
1613 for (std::vector<ServiceDescriptionSection*>::const_iterator i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
1616 PyTuple_SET_ITEM(args, 0, PyInt_FromLong((*i)->getTransportStreamId()));
1617 PyTuple_SET_ITEM(args, 1, PyInt_FromLong((*i)->getOriginalNetworkId()));
1623 PyTuple_SET_ITEM(args, 0, Py_None);
1624 PyTuple_SET_ITEM(args, 1, Py_None);
1628 ret = PyObject_CallObject(m_tsid_onid_callback, args);
1632 Py_DECREF(m_tsid_onid_callback);
1633 m_tsid_onid_callback = ePyObject();
1634 m_tsid_onid_demux = 0;
1638 RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
1640 if (PyCallable_Check(callback))
1642 if (!getDemux(m_tsid_onid_demux, 0))
1644 m_SDT = new eTable<ServiceDescriptionSection>;
1645 CONNECT(m_SDT->tableReady, eDVBChannel::SDTready);
1646 if (m_SDT->start(m_tsid_onid_demux, eDVBSDTSpec()))
1648 m_tsid_onid_demux = 0;
1653 Py_INCREF(callback);
1654 m_tsid_onid_callback = callback;
1662 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1664 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1670 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1675 /* don't hold a reference to the decoding demux, we don't need it. */
1677 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1678 the refcount is lost. thus, decoding demuxes are never allocated.
1680 this poses a big problem for PiP. */
1681 if (cap & capDecode)
1686 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1691 frontend = &m_frontend->get();
1697 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1699 param = m_current_frontend_parameters;
1703 RESULT eDVBChannel::playFile(const char *file)
1705 ASSERT(!m_frontend);
1708 m_pvr_thread->stop();
1709 delete m_pvr_thread;
1713 m_tstools.openFile(file);
1715 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1716 THEN DO A REAL FIX HERE! */
1718 /* (this codepath needs to be improved anyway.) */
1719 #if HAVE_DVB_API_VERSION < 3
1720 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1722 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1724 if (m_pvr_fd_dst < 0)
1726 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1730 m_pvr_thread = new eDVBChannelFilePush();
1731 m_pvr_thread->enablePVRCommit(1);
1732 m_pvr_thread->setStreamMode(1);
1733 m_pvr_thread->setScatterGather(this);
1735 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1737 delete m_pvr_thread;
1739 eDebug("can't open PVR file %s (%m)", file);
1742 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1745 m_stateChanged(this);
1750 void eDVBChannel::stopFile()
1754 m_pvr_thread->stop();
1755 ::close(m_pvr_fd_dst);
1756 delete m_pvr_thread;
1761 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1763 m_conn_cueSheetEvent = 0;
1766 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1769 RESULT eDVBChannel::getLength(pts_t &len)
1771 return m_tstools.calcLen(len);
1774 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1776 if (!decoding_demux)
1783 if (mode == 0) /* demux */
1785 r = decoding_demux->getSTC(now, 0);
1788 eDebug("demux getSTC failed");
1792 now = pos; /* fixup supplied */
1794 off_t off = 0; /* TODO: fixme */
1795 r = m_tstools.fixupPTS(off, now);
1798 eDebug("fixup PTS failed");
1807 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1809 /* when seeking, we have to ensure that all buffers are flushed.
1810 there are basically 3 buffers:
1811 a.) the filepush's internal buffer
1812 b.) the PVR buffer (before demux)
1813 c.) the ratebuffer (after demux)
1815 it's important to clear them in the correct order, otherwise
1816 the ratebuffer (for example) would immediately refill from
1817 the not-yet-flushed PVR buffer.
1820 m_pvr_thread->pause();
1821 /* flush internal filepush buffer */
1822 m_pvr_thread->flush();
1823 /* HACK: flush PVR buffer */
1824 ::ioctl(m_pvr_fd_dst, 0);
1826 /* flush ratebuffers (video, audio) */
1828 decoding_demux->flush();
1830 /* demux will also flush all decoder.. */
1831 /* resume will re-query the SG */
1832 m_pvr_thread->resume();
1835 DEFINE_REF(eCueSheet);
1837 eCueSheet::eCueSheet()
1839 m_skipmode_ratio = 0;
1842 void eCueSheet::seekTo(int relative, const pts_t &pts)
1845 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1850 void eCueSheet::clear()
1857 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1859 ASSERT(begin < end);
1861 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1865 void eCueSheet::commitSpans()
1867 m_event(evtSpanChanged);
1870 void eCueSheet::setSkipmode(const pts_t &ratio)
1873 m_skipmode_ratio = ratio;
1875 m_event(evtSkipmode);
1878 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1880 m_decoding_demux = demux;
1881 m_decoder = decoder;
1884 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1886 connection = new eConnection(this, m_event.connect(event));