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 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid)) /* picture start */
995 int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
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 */
1034 /* verify that this is actually a PES header, not just some ES data */
1035 if (ts[1] & 0x40) /* PUSI set */
1037 int payload_start = 4;
1038 if (ts[3] & 0x20) /* adaptation field present */
1039 payload_start += ts[4] + 1; /* skip AF */
1040 if (payload_start == (offset%188)) /* the 00 00 01 should be directly at the payload start, otherwise it's not a PES header */
1044 eDebug("now locked to pid %04x (%02x %02x %02x %02x)", pid, ts[0], ts[1], ts[2], ts[3]);
1052 d += 4; /* ignore */
1055 if (m_iframe_state == 1)
1058 return 0; /* we need find an iframe first */
1064 DEFINE_REF(eDVBChannel);
1066 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1068 m_frontend = frontend;
1072 m_skipmode_n = m_skipmode_m = m_skipmode_frames = 0;
1075 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1078 eDVBChannel::~eDVBChannel()
1081 m_mgr->removeChannel(this);
1086 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1088 int state, ourstate = 0;
1090 /* if we are already in shutdown, don't change state. */
1091 if (m_state == state_release)
1094 if (fe->getState(state))
1097 if (state == iDVBFrontend::stateLock)
1099 eDebug("OURSTATE: ok");
1100 ourstate = state_ok;
1101 } else if (state == iDVBFrontend::stateTuning)
1103 eDebug("OURSTATE: tuning");
1104 ourstate = state_tuning;
1105 } else if (state == iDVBFrontend::stateLostLock)
1107 /* on managed channels, we try to retune in order to re-acquire lock. */
1108 if (m_current_frontend_parameters)
1110 eDebug("OURSTATE: lost lock, trying to retune");
1111 ourstate = state_tuning;
1112 m_frontend->get().tune(*m_current_frontend_parameters);
1114 /* on unmanaged channels, we don't do this. the client will do this. */
1116 eDebug("OURSTATE: lost lock, unavailable now.");
1117 ourstate = state_unavailable;
1119 } else if (state == iDVBFrontend::stateFailed)
1121 eDebug("OURSTATE: failed");
1122 ourstate = state_failed;
1124 eFatal("state unknown");
1126 if (ourstate != m_state)
1129 m_stateChanged(this);
1133 void eDVBChannel::pvrEvent(int event)
1137 case eFilePushThread::evtEOF:
1138 eDebug("eDVBChannel: End of file!");
1139 m_event(this, evtEOF);
1141 case eFilePushThread::evtUser: /* start */
1143 m_event(this, evtSOF);
1148 void eDVBChannel::cueSheetEvent(int event)
1150 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1155 case eCueSheet::evtSeek:
1157 flushPVR(m_cue->m_decoding_demux);
1159 case eCueSheet::evtSkipmode:
1162 m_cue->m_lock.WrLock();
1163 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1164 m_cue->m_lock.Unlock();
1165 eRdLocker l(m_cue->m_lock);
1166 if (m_cue->m_skipmode_ratio)
1168 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1169 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1170 /* i agree that this might look a bit like black magic. */
1171 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1172 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1173 m_skipmode_frames = m_cue->m_skipmode_ratio / 90000;
1174 m_skipmode_frames_remainder = 0;
1176 if (m_cue->m_skipmode_ratio < 0)
1177 m_skipmode_m -= m_skipmode_n;
1179 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1181 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1183 eWarning("something is wrong with this calculation");
1184 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1188 eDebug("skipmode ratio is 0, normal play");
1189 m_skipmode_frames = m_skipmode_n = m_skipmode_m = 0;
1192 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1193 if (m_cue->m_skipmode_ratio != 0)
1194 m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1196 m_pvr_thread->setTimebaseChange(0); /* normal playback */
1197 eDebug("flush pvr");
1198 flushPVR(m_cue->m_decoding_demux);
1202 case eCueSheet::evtSpanChanged:
1204 m_source_span.clear();
1205 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1207 off_t offset_in, offset_out;
1208 pts_t pts_in = i->first, pts_out = i->second;
1209 if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
1211 eDebug("span translation failed.\n");
1214 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
1215 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1222 /* align toward zero */
1223 static inline long long align(long long x, int align)
1238 /* align toward zero */
1239 static inline long long align_with_len(long long x, int align, size_t &len)
1255 /* remember, this gets called from another thread. */
1256 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
1258 const int blocksize = 188;
1259 unsigned int max = align(10*1024*1024, blocksize);
1260 current_offset = align(current_offset, blocksize);
1264 eDebug("no cue sheet. forcing normal play");
1265 start = current_offset;
1270 m_cue->m_lock.RdLock();
1271 if (!m_cue->m_decoding_demux)
1273 start = current_offset;
1275 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
1276 m_cue->m_lock.Unlock();
1282 eDebug("skipmode %d:%d (x%d)", m_skipmode_m, m_skipmode_n, m_skipmode_frames);
1283 max = align(m_skipmode_n, blocksize);
1286 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1288 int frame_skip_success = 0;
1292 int frames_to_skip = m_skipmode_frames + m_skipmode_frames_remainder;
1293 eDebug("we are at %llx, and we try to skip %d+%d frames from here", current_offset, m_skipmode_frames, m_skipmode_frames_remainder);
1295 off_t iframe_start = current_offset;
1296 int frames_skipped = frames_to_skip;
1297 if (!m_tstools.findNextPicture(iframe_start, iframe_len, frames_skipped))
1299 m_skipmode_frames_remainder = frames_to_skip - frames_skipped;
1300 eDebug("successfully skipped %d (out of %d, rem now %d) frames.", frames_skipped, frames_to_skip, m_skipmode_frames_remainder);
1301 current_offset = align_with_len(iframe_start, blocksize, iframe_len);
1302 max = align(iframe_len + 187, blocksize);
1303 frame_skip_success = 1;
1306 m_skipmode_frames_remainder = 0;
1307 eDebug("frame skipping failed, reverting to byte-skipping");
1311 if (!frame_skip_success)
1313 current_offset += align(m_skipmode_m, blocksize);
1317 eDebug("we are at %llx, and we try to find the iframe here:", current_offset);
1319 off_t iframe_start = current_offset;
1321 int direction = (m_skipmode_m < 0) ? -1 : +1;
1322 if (m_tstools.findFrame(iframe_start, iframe_len, direction))
1326 current_offset = align_with_len(iframe_start, blocksize, iframe_len);
1327 max = align(iframe_len, blocksize);
1332 while (!m_cue->m_seek_requests.empty())
1334 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1335 m_cue->m_lock.Unlock();
1336 m_cue->m_lock.WrLock();
1337 m_cue->m_seek_requests.pop_front();
1338 m_cue->m_lock.Unlock();
1339 m_cue->m_lock.RdLock();
1340 int relative = seek.first;
1341 pts_t pts = seek.second;
1346 if (!m_cue->m_decoder)
1348 eDebug("no decoder - can't seek relative");
1351 if (m_cue->m_decoder->getPTS(0, now))
1353 eDebug("decoder getPTS failed, can't seek relative");
1356 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1358 eDebug("seekTo: getCurrentPosition failed!");
1361 } else if (pts < 0) /* seek relative to end */
1364 if (!getLength(len))
1366 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1370 eWarning("getLength failed - can't seek relative to end!");
1375 if (relative == 1) /* pts relative */
1386 if (relative == 2) /* AP relative */
1388 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1390 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1392 pts = now - 90000; /* approx. 1s */
1393 eDebug("AP relative seeking failed!");
1397 eDebug("next ap is %llx\n", pts);
1402 if (m_tstools.getOffset(offset, pts, -1))
1404 eDebug("get offset for pts=%lld failed!", pts);
1409 /* try to align to iframe */
1410 int direction = pts < 0 ? -1 : 1;
1411 m_tstools.findFrame(offset, iframe_len, direction);
1413 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx (skipped additional %d frames due to iframe re-align)", relative, pts, offset, direction);
1414 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1417 m_cue->m_lock.Unlock();
1419 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1421 long long aligned_start = align(i->first, blocksize);
1422 long long aligned_end = align(i->second, blocksize);
1424 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1426 start = current_offset;
1427 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1428 if ((aligned_end - current_offset) > max)
1431 size = aligned_end - current_offset;
1432 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1435 if (current_offset < aligned_start)
1437 /* ok, our current offset is in an 'out' zone. */
1438 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1440 /* in normal playback, just start at the next zone. */
1443 /* size is not 64bit! */
1444 if ((i->second - i->first) > max)
1447 size = aligned_end - aligned_start;
1450 if (m_skipmode_m < 0)
1452 eDebug("reached SOF");
1455 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1459 /* when skipping reverse, however, choose the zone before. */
1461 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1464 aligned_start = align(i->first, blocksize);
1465 aligned_end = align(i->second, blocksize);
1467 if ((aligned_end - aligned_start) > max)
1470 len = aligned_end - aligned_start;
1472 start = aligned_end - len;
1473 eDebug("skipping to %llx, %d", start, len);
1476 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1481 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1483 eDebug("reached SOF");
1485 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1488 if (m_source_span.empty())
1490 start = current_offset;
1492 eDebug("NO CUESHEET. (%08llx, %d)", start, size);
1495 start = current_offset;
1501 void eDVBChannel::AddUse()
1503 if (++m_use_count > 1 && m_state == state_last_instance)
1506 m_stateChanged(this);
1510 void eDVBChannel::ReleaseUse()
1514 m_state = state_release;
1515 m_stateChanged(this);
1517 else if (m_use_count == 1)
1519 m_state = state_last_instance;
1520 m_stateChanged(this);
1524 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1527 m_mgr->removeChannel(this);
1534 eDebug("no frontend to tune!");
1538 m_channel_id = channelid;
1539 m_mgr->addChannel(channelid, this);
1540 m_state = state_tuning;
1541 /* if tuning fails, shutdown the channel immediately. */
1543 res = m_frontend->get().tune(*feparm);
1544 m_current_frontend_parameters = feparm;
1548 m_state = state_release;
1549 m_stateChanged(this);
1556 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1558 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1562 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1564 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1568 RESULT eDVBChannel::getState(int &state)
1574 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1579 void eDVBChannel::SDTready(int result)
1581 ePyObject args = PyTuple_New(2), ret;
1585 for (std::vector<ServiceDescriptionSection*>::const_iterator i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
1588 PyTuple_SET_ITEM(args, 0, PyInt_FromLong((*i)->getTransportStreamId()));
1589 PyTuple_SET_ITEM(args, 1, PyInt_FromLong((*i)->getOriginalNetworkId()));
1595 PyTuple_SET_ITEM(args, 0, Py_None);
1596 PyTuple_SET_ITEM(args, 1, Py_None);
1600 ret = PyObject_CallObject(m_tsid_onid_callback, args);
1604 Py_DECREF(m_tsid_onid_callback);
1605 m_tsid_onid_callback = ePyObject();
1606 m_tsid_onid_demux = 0;
1610 RESULT eDVBChannel::requestTsidOnid(ePyObject callback)
1612 if (PyCallable_Check(callback))
1614 if (!getDemux(m_tsid_onid_demux, 0))
1616 m_SDT = new eTable<ServiceDescriptionSection>;
1617 CONNECT(m_SDT->tableReady, eDVBChannel::SDTready);
1618 if (m_SDT->start(m_tsid_onid_demux, eDVBSDTSpec()))
1620 m_tsid_onid_demux = 0;
1625 Py_INCREF(callback);
1626 m_tsid_onid_callback = callback;
1634 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1636 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1642 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1647 /* don't hold a reference to the decoding demux, we don't need it. */
1649 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1650 the refcount is lost. thus, decoding demuxes are never allocated.
1652 this poses a big problem for PiP. */
1653 if (cap & capDecode)
1658 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1663 frontend = &m_frontend->get();
1669 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1671 param = m_current_frontend_parameters;
1675 RESULT eDVBChannel::playFile(const char *file)
1677 ASSERT(!m_frontend);
1680 m_pvr_thread->stop();
1681 delete m_pvr_thread;
1685 m_tstools.openFile(file);
1687 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1688 THEN DO A REAL FIX HERE! */
1690 /* (this codepath needs to be improved anyway.) */
1691 #if HAVE_DVB_API_VERSION < 3
1692 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1694 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1696 if (m_pvr_fd_dst < 0)
1698 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1702 m_pvr_thread = new eDVBChannelFilePush();
1703 m_pvr_thread->enablePVRCommit(1);
1704 m_pvr_thread->setStreamMode(1);
1705 m_pvr_thread->setScatterGather(this);
1707 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1709 delete m_pvr_thread;
1711 eDebug("can't open PVR file %s (%m)", file);
1714 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1717 m_stateChanged(this);
1722 void eDVBChannel::stopFile()
1726 m_pvr_thread->stop();
1727 ::close(m_pvr_fd_dst);
1728 delete m_pvr_thread;
1733 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1735 m_conn_cueSheetEvent = 0;
1738 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1741 RESULT eDVBChannel::getLength(pts_t &len)
1743 return m_tstools.calcLen(len);
1746 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1748 if (!decoding_demux)
1755 if (mode == 0) /* demux */
1757 r = decoding_demux->getSTC(now, 0);
1760 eDebug("demux getSTC failed");
1764 now = pos; /* fixup supplied */
1766 off_t off = 0; /* TODO: fixme */
1767 r = m_tstools.fixupPTS(off, now);
1770 eDebug("fixup PTS failed");
1779 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1781 /* when seeking, we have to ensure that all buffers are flushed.
1782 there are basically 3 buffers:
1783 a.) the filepush's internal buffer
1784 b.) the PVR buffer (before demux)
1785 c.) the ratebuffer (after demux)
1787 it's important to clear them in the correct order, otherwise
1788 the ratebuffer (for example) would immediately refill from
1789 the not-yet-flushed PVR buffer.
1792 m_pvr_thread->pause();
1793 /* flush internal filepush buffer */
1794 m_pvr_thread->flush();
1795 /* HACK: flush PVR buffer */
1796 ::ioctl(m_pvr_fd_dst, 0);
1798 /* flush ratebuffers (video, audio) */
1800 decoding_demux->flush();
1802 /* demux will also flush all decoder.. */
1803 /* resume will re-query the SG */
1804 m_pvr_thread->resume();
1807 DEFINE_REF(eCueSheet);
1809 eCueSheet::eCueSheet()
1811 m_skipmode_ratio = 0;
1814 void eCueSheet::seekTo(int relative, const pts_t &pts)
1817 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1822 void eCueSheet::clear()
1829 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1831 assert(begin < end);
1833 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1837 void eCueSheet::commitSpans()
1839 m_event(evtSpanChanged);
1842 void eCueSheet::setSkipmode(const pts_t &ratio)
1845 m_skipmode_ratio = ratio;
1847 m_event(evtSkipmode);
1850 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1852 m_decoding_demux = demux;
1853 m_decoder = decoder;
1856 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1858 connection = new eConnection(this, m_event.connect(event));