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>
13 #include <sys/ioctl.h>
15 DEFINE_REF(eDVBRegisteredFrontend);
16 DEFINE_REF(eDVBRegisteredDemux);
18 DEFINE_REF(eDVBAllocatedFrontend);
20 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
25 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
30 DEFINE_REF(eDVBAllocatedDemux);
32 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
37 eDVBAllocatedDemux::~eDVBAllocatedDemux()
42 DEFINE_REF(eDVBResourceManager);
44 eDVBResourceManager *eDVBResourceManager::instance;
46 RESULT eDVBResourceManager::getInstance(ePtr<eDVBResourceManager> &ptr)
56 ePtr<eDVBResourceManager> NewResourceManagerPtr(void)
58 ePtr<eDVBResourceManager> ptr;
59 eDVBResourceManager::getInstance(ptr);
63 eDVBResourceManager::eDVBResourceManager()
64 :m_releaseCachedChannelTimer(eTimer::create(eApp))
68 m_sec = new eDVBSatelliteEquipmentControl(m_frontend, m_simulate_frontend);
73 /* search available adapters... */
78 while (eDVBAdapterLinux::exist(num_adapter))
80 addAdapter(new eDVBAdapterLinux(num_adapter));
84 eDebug("found %d adapter, %d frontends(%d sim) and %d demux",
85 m_adapter.size(), m_frontend.size(), m_simulate_frontend.size(), m_demux.size());
87 eDVBCAService::registerChannelCallback(this);
89 CONNECT(m_releaseCachedChannelTimer->timeout, eDVBResourceManager::releaseCachedChannel);
92 void eDVBResourceManager::feStateChanged()
95 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
97 mask |= ( 1 << i->m_frontend->getSlotID() );
98 /* emit */ frontendUseMaskChanged(mask);
101 DEFINE_REF(eDVBAdapterLinux);
102 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
107 eDebug("scanning for frontends..");
112 #if HAVE_DVB_API_VERSION < 3
113 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
115 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
117 if (stat(filename, &s))
119 ePtr<eDVBFrontend> fe;
123 fe = new eDVBFrontend(m_nr, num_fe, ok);
125 m_frontend.push_back(fe);
129 fe = new eDVBFrontend(m_nr, num_fe, ok, true);
131 m_simulate_frontend.push_back(fe);
142 #if HAVE_DVB_API_VERSION < 3
143 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
145 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
147 if (stat(filename, &s))
149 ePtr<eDVBDemux> demux;
151 demux = new eDVBDemux(m_nr, num_demux);
152 m_demux.push_back(demux);
158 int eDVBAdapterLinux::getNumDemux()
160 return m_demux.size();
163 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
165 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
166 while (nr && (i != m_demux.end()))
172 if (i != m_demux.end())
180 int eDVBAdapterLinux::getNumFrontends()
182 return m_frontend.size();
185 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr, bool simulate)
187 eSmartPtrList<eDVBFrontend>::iterator i(simulate ? m_simulate_frontend.begin() : m_frontend.begin());
188 while (nr && (i != m_frontend.end()))
194 if (i != m_frontend.end())
202 int eDVBAdapterLinux::exist(int nr)
206 #if HAVE_DVB_API_VERSION < 3
207 sprintf(filename, "/dev/dvb/card%d", nr);
209 sprintf(filename, "/dev/dvb/adapter%d", nr);
211 if (!stat(filename, &s))
216 eDVBResourceManager::~eDVBResourceManager()
218 if (instance == this)
222 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
224 int num_fe = adapter->getNumFrontends();
225 int num_demux = adapter->getNumDemux();
227 m_adapter.push_back(adapter);
230 for (i=0; i<num_demux; ++i)
232 ePtr<eDVBDemux> demux;
233 if (!adapter->getDemux(demux, i))
234 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
237 ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
238 for (i=0; i<num_fe; ++i)
240 ePtr<eDVBFrontend> frontend;
241 if (!adapter->getFrontend(frontend, i))
244 frontend->getFrontendType(frontendType);
245 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
246 CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
247 m_frontend.push_back(new_fe);
248 frontend->setSEC(m_sec);
249 // we must link all dvb-t frontends ( for active antenna voltage )
250 if (frontendType == iDVBFrontend::feTerrestrial)
252 if (prev_dvbt_frontend)
254 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe);
255 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend));
257 prev_dvbt_frontend = new_fe;
262 prev_dvbt_frontend = 0;
263 for (i=0; i<num_fe; ++i)
265 ePtr<eDVBFrontend> frontend;
266 if (!adapter->getFrontend(frontend, i, true))
269 frontend->getFrontendType(frontendType);
270 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
271 // CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
272 m_simulate_frontend.push_back(new_fe);
273 frontend->setSEC(m_sec);
274 // we must link all dvb-t frontends ( for active antenna voltage )
275 if (frontendType == iDVBFrontend::feTerrestrial)
277 if (prev_dvbt_frontend)
279 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (long)new_fe);
280 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (long)&(*prev_dvbt_frontend));
282 prev_dvbt_frontend = new_fe;
289 PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
291 if (!PyList_Check(list))
293 PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
296 if ((unsigned int)PyList_Size(list) != m_frontend.size())
299 sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist",
300 m_frontend.size(), PyList_Size(list));
301 PyErr_SetString(PyExc_StandardError, blasel);
305 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
307 ePyObject obj = PyList_GET_ITEM(list, pos++);
308 if (!i->m_frontend->setSlotInfo(obj))
312 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_simulate_frontend.begin()); i != m_simulate_frontend.end(); ++i)
314 ePyObject obj = PyList_GET_ITEM(list, pos++);
315 if (!i->m_frontend->setSlotInfo(obj))
321 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm, bool simulate)
323 eSmartPtrList<eDVBRegisteredFrontend> &frontends = simulate ? m_simulate_frontend : m_frontend;
324 ePtr<eDVBRegisteredFrontend> best;
328 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(frontends.begin()); i != frontends.end(); ++i)
330 int c = i->m_frontend->isCompatibleWith(feparm);
332 if (c) /* if we have at least one frontend which is compatible with the source, flag this. */
337 // eDebug("Slot %d, score %d", i->m_frontend->getSlotID(), c);
345 // eDebug("Slot %d, score %d... but BUSY!!!!!!!!!!!", i->m_frontend->getSlotID(), c);
350 fe = new eDVBAllocatedFrontend(best);
357 return errAllSourcesBusy;
359 return errNoSourceFound;
362 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index)
364 int err = errNoSourceFound;
365 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
366 if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index)
368 // check if another slot linked to this is in use
370 i->m_frontend->getData(eDVBFrontend::SATPOS_DEPENDS_PTR, tmp);
373 eDVBRegisteredFrontend *satpos_depends_to_fe = (eDVBRegisteredFrontend *)tmp;
374 if (satpos_depends_to_fe->m_inuse)
376 eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!");
377 err = errAllSourcesBusy;
378 goto alloc_fe_by_id_not_possible;
381 else // check linked tuners
383 i->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, tmp);
386 eDVBRegisteredFrontend *next = (eDVBRegisteredFrontend *) tmp;
389 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
390 err = errAllSourcesBusy;
391 goto alloc_fe_by_id_not_possible;
393 next->m_frontend->getData(eDVBFrontend::LINKED_NEXT_PTR, tmp);
395 i->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp);
398 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *) tmp;
401 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
402 err = errAllSourcesBusy;
403 goto alloc_fe_by_id_not_possible;
405 prev->m_frontend->getData(eDVBFrontend::LINKED_PREV_PTR, tmp);
408 fe = new eDVBAllocatedFrontend(i);
411 alloc_fe_by_id_not_possible:
416 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
418 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
419 never use the first one unless we need a decoding demux. */
421 eDebug("allocate demux");
422 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
426 if (i == m_demux.end())
429 ePtr<eDVBRegisteredDemux> unused;
431 if (m_demux.size() < 5)
433 /* FIXME: hardware demux policy */
434 if (!(cap & iDVBChannel::capDecode))
436 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
443 for (; i != m_demux.end(); ++i, ++n)
445 int is_decode = n < 2;
447 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
449 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
451 if ((cap & iDVBChannel::capDecode) && !is_decode)
458 else // we asume dm8000
460 for (; i != m_demux.end(); ++i, ++n)
469 else if (i->m_adapter == fe->m_adapter &&
470 i->m_demux->getSource() == fe->m_frontend->getDVBID())
472 demux = new eDVBAllocatedDemux(i);
476 else if (n == 4) // always use demux4 for PVR (demux 4 can not descramble...)
479 demux = new eDVBAllocatedDemux(i);
489 demux = new eDVBAllocatedDemux(unused);
491 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
493 demux->get().setSourcePVR(0);
497 eDebug("demux not found");
501 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
507 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
516 #define eDebugNoSimulate(x...) \
523 // eDebugNoNewLine("SIMULATE:"); \
528 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel, bool simulate)
530 /* first, check if a channel is already existing. */
531 std::list<active_channel> &active_channels = simulate ? m_active_simulate_channels : m_active_channels;
533 if (!simulate && m_cached_channel)
535 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
536 if(channelid==cache_chan->getChannelID())
538 eDebug("use cached_channel");
539 channel = m_cached_channel;
542 m_cached_channel_state_changed_conn.disconnect();
544 m_releaseCachedChannelTimer->stop();
547 eDebugNoSimulate("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
548 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end(); ++i)
550 eDebugNoSimulate("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
551 if (i->m_channel_id == channelid)
553 eDebugNoSimulate("found shared channel..");
554 channel = i->m_channel;
559 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
563 eDebugNoSimulate("no channel list set!");
564 return errNoChannelList;
567 ePtr<iDVBFrontendParameters> feparm;
568 if (m_list->getChannelFrontendData(channelid, feparm))
570 eDebugNoSimulate("channel not found!");
571 return errChannelNotInList;
574 /* allocate a frontend. */
576 ePtr<eDVBAllocatedFrontend> fe;
578 int err = allocateFrontend(fe, feparm, simulate);
583 ePtr<eDVBChannel> ch = new eDVBChannel(this, fe);
585 res = ch->setChannel(channelid, feparm);
589 return errChidNotFound;
596 m_cached_channel = channel = ch;
597 m_cached_channel_state_changed_conn =
598 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
604 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
607 chan->getState(state);
610 case iDVBChannel::state_release:
611 case iDVBChannel::state_ok:
613 eDebug("stop release channel timer");
614 m_releaseCachedChannelTimer->stop();
617 case iDVBChannel::state_last_instance:
619 eDebug("start release channel timer");
620 m_releaseCachedChannelTimer->start(3000, true);
623 default: // ignore all other events
628 void eDVBResourceManager::releaseCachedChannel()
630 eDebug("release cached channel (timer timeout)");
634 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
636 ePtr<eDVBAllocatedFrontend> fe;
638 if (m_cached_channel)
640 m_cached_channel_state_changed_conn.disconnect();
642 m_releaseCachedChannelTimer->stop();
645 int err = allocateFrontendByIndex(fe, slot_index);
649 channel = new eDVBChannel(this, fe);
654 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
656 ePtr<eDVBAllocatedDemux> demux;
658 if (m_cached_channel && m_releaseCachedChannelTimer->isActive())
660 m_cached_channel_state_changed_conn.disconnect();
662 m_releaseCachedChannelTimer->stop();
665 channel = new eDVBChannel(this, 0);
669 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
671 ePtr<iDVBFrontend> fe;
672 if (!ch->getFrontend(fe))
674 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
675 if (frontend->is_simulate())
676 m_active_simulate_channels.push_back(active_channel(chid, ch));
679 m_active_channels.push_back(active_channel(chid, ch));
680 /* emit */ m_channelAdded(ch);
686 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
688 ePtr<iDVBFrontend> fe;
689 if (!ch->getFrontend(fe))
691 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
692 std::list<active_channel> &active_channels = frontend->is_simulate() ? m_active_simulate_channels : m_active_channels;
694 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end();)
696 if (i->m_channel == ch)
698 i = active_channels.erase(i);
710 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
712 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
716 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
718 ePtr<eDVBRegisteredFrontend> best;
721 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
724 int c = i->m_frontend->isCompatibleWith(feparm);
731 int tuner_type_channel_default(ePtr<iDVBChannelList> &channellist, const eDVBChannelID &chid)
735 ePtr<iDVBFrontendParameters> feparm;
736 if (!channellist->getChannelFrontendData(chid, feparm))
739 if (!feparm->getSystem(system))
743 case iDVBFrontend::feSatellite:
745 case iDVBFrontend::feCable:
747 case iDVBFrontend::feTerrestrial:
758 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
761 if (m_cached_channel)
763 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
764 if(channelid==cache_chan->getChannelID())
765 return tuner_type_channel_default(m_list, channelid);
768 /* first, check if a channel is already existing. */
769 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
770 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
772 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
773 if (i->m_channel_id == channelid)
775 // eDebug("found shared channel..");
776 return tuner_type_channel_default(m_list, channelid);
780 int *decremented_cached_channel_fe_usecount=NULL,
781 *decremented_fe_usecount=NULL;
783 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
785 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
786 if (i->m_channel_id == ignore)
788 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
789 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
790 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
791 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
792 // or 2 when the cached channel is not equal to the compared channel
793 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
795 ePtr<iDVBFrontend> fe;
796 if (!i->m_channel->getFrontend(fe))
798 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
800 if ( &(*fe) == &(*ii->m_frontend) )
803 decremented_fe_usecount = &ii->m_inuse;
804 if (channel == &(*m_cached_channel))
805 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
815 if (!decremented_cached_channel_fe_usecount)
817 if (m_cached_channel)
819 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
820 if (channel->getUseCount() == 1)
822 ePtr<iDVBFrontend> fe;
823 if (!channel->getFrontend(fe))
825 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
827 if ( &(*fe) == &(*ii->m_frontend) )
830 decremented_cached_channel_fe_usecount = &ii->m_inuse;
839 decremented_cached_channel_fe_usecount=NULL;
841 ePtr<iDVBFrontendParameters> feparm;
845 eDebug("no channel list set!");
849 if (m_list->getChannelFrontendData(channelid, feparm))
851 eDebug("channel not found!");
855 ret = canAllocateFrontend(feparm);
858 if (decremented_fe_usecount)
859 ++(*decremented_fe_usecount);
860 if (decremented_cached_channel_fe_usecount)
861 ++(*decremented_cached_channel_fe_usecount);
866 bool eDVBResourceManager::canMeasureFrontendInputPower()
868 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
870 return i->m_frontend->readInputpower() >= 0;
875 class eDVBChannelFilePush: public eFilePushThread
878 eDVBChannelFilePush() { setIFrameSearch(0); setTimebaseChange(0); }
879 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
881 /* "timebase change" is for doing trickmode playback at an exact speed, even when pictures are skipped. */
882 /* you need to set it to 1/16 if you want 16x playback, for example. you need video master sync. */
883 void setTimebaseChange(int ratio) { m_timebase_change = ratio; } /* 16bit fixpoint, 0 for disable */
885 int m_iframe_search, m_iframe_state, m_pid;
886 int m_timebase_change;
887 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
890 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
893 if (m_timebase_change)
895 eDebug("timebase change: %d", m_timebase_change);
897 for (offset = 0; offset < len; offset += 188)
899 unsigned char *pkt = (unsigned char*)_data + offset;
900 if (pkt[1] & 0x40) /* pusi */
902 if (pkt[3] & 0x20) // adaption field present?
903 pkt += pkt[4] + 4 + 1; /* skip adaption field and header */
905 pkt += 4; /* skip header */
906 if (pkt[0] || pkt[1] || (pkt[2] != 1))
908 eWarning("broken startcode");
914 if (pkt[7] & 0x80) // PTS present?
916 pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29;
917 pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22;
918 pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14;
919 pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7;
920 pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1;
924 RESULT r = m_tstools.fixupPTS(off, pts);
926 eWarning("fixup PTS while trickmode playback failed.\n");
929 int sec = pts / 90000;
930 int frm = pts % 90000;
938 // eDebug("original, fixed pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
941 pts *= m_timebase_change;
953 // eDebug("new pts (after timebase change): %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
961 pkt[9] |= (pts >> 29) & 0xE;
962 pkt[10] |= (pts >> 22) & 0xFF;
963 pkt[11] |= (pts >> 14) & 0xFE;
964 pkt[12] |= (pts >> 7) & 0xFF;
965 pkt[13] |= (pts << 1) & 0xFE;
973 if (!m_iframe_search)
976 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
978 // eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
980 unsigned char *d = data;
981 while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
983 int offset = d - data;
984 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
985 unsigned char *ts = data + ts_offset;
986 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
988 if ((d[3] == 0 || d[3] == 0x09 && d[-1] == 0 && (ts[1] & 0x40)) && (m_pid == pid)) /* picture start */
990 int picture_type = (d[3]==0 ? (d[5] >> 3) & 7 : (d[4] >> 5) + 1);
993 // eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
995 if (m_iframe_state == 1)
997 /* we are allowing data, and stop allowing data on the next frame.
998 we now found a frame. so stop here. */
999 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
1000 current_span_remaining = 0;
1002 unsigned char *fts = ts + 188;
1003 while (fts < (data + len))
1006 fts[2] |= 0xff; /* drop packet */
1010 return len; // ts_offset + 188; /* deliver this packet, but not more. */
1013 if (picture_type != 1) /* we are only interested in I frames */
1016 unsigned char *fts = data;
1020 fts[2] |= 0xff; /* drop packet */
1024 /* force payload only */
1028 // memset(ts + 4, 0xFF, (offset % 188) - 4);
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%184)) /* 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 */
1056 if (m_iframe_state == 1)
1059 return 0; /* we need find an iframe first */
1065 DEFINE_REF(eDVBChannel);
1067 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1069 m_frontend = frontend;
1073 m_skipmode_n = m_skipmode_m = 0;
1076 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1079 eDVBChannel::~eDVBChannel()
1082 m_mgr->removeChannel(this);
1087 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1089 int state, ourstate = 0;
1091 /* if we are already in shutdown, don't change state. */
1092 if (m_state == state_release)
1095 if (fe->getState(state))
1098 if (state == iDVBFrontend::stateLock)
1100 eDebug("OURSTATE: ok");
1101 ourstate = state_ok;
1102 } else if (state == iDVBFrontend::stateTuning)
1104 eDebug("OURSTATE: tuning");
1105 ourstate = state_tuning;
1106 } else if (state == iDVBFrontend::stateLostLock)
1108 /* on managed channels, we try to retune in order to re-acquire lock. */
1109 if (m_current_frontend_parameters)
1111 eDebug("OURSTATE: lost lock, trying to retune");
1112 ourstate = state_tuning;
1113 m_frontend->get().tune(*m_current_frontend_parameters);
1115 /* on unmanaged channels, we don't do this. the client will do this. */
1117 eDebug("OURSTATE: lost lock, unavailable now.");
1118 ourstate = state_unavailable;
1120 } else if (state == iDVBFrontend::stateFailed)
1122 eDebug("OURSTATE: failed");
1123 ourstate = state_failed;
1125 eFatal("state unknown");
1127 if (ourstate != m_state)
1130 m_stateChanged(this);
1134 void eDVBChannel::pvrEvent(int event)
1138 case eFilePushThread::evtEOF:
1139 eDebug("eDVBChannel: End of file!");
1140 m_event(this, evtEOF);
1142 case eFilePushThread::evtUser: /* start */
1144 m_event(this, evtSOF);
1149 void eDVBChannel::cueSheetEvent(int event)
1151 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1156 case eCueSheet::evtSeek:
1158 flushPVR(m_cue->m_decoding_demux);
1160 case eCueSheet::evtSkipmode:
1163 m_cue->m_lock.WrLock();
1164 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1165 m_cue->m_lock.Unlock();
1166 eRdLocker l(m_cue->m_lock);
1167 if (m_cue->m_skipmode_ratio)
1169 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1170 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1171 /* i agree that this might look a bit like black magic. */
1172 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1173 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1175 if (m_cue->m_skipmode_ratio < 0)
1176 m_skipmode_m -= m_skipmode_n;
1178 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1180 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1182 eWarning("something is wrong with this calculation");
1183 m_skipmode_n = m_skipmode_m = 0;
1187 eDebug("skipmode ratio is 0, normal play");
1188 m_skipmode_n = m_skipmode_m = 0;
1191 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1192 if (m_cue->m_skipmode_ratio != 0)
1193 m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1195 m_pvr_thread->setTimebaseChange(0); /* normal playback */
1196 eDebug("flush pvr");
1197 flushPVR(m_cue->m_decoding_demux);
1201 case eCueSheet::evtSpanChanged:
1203 m_source_span.clear();
1204 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1206 off_t offset_in, offset_out;
1207 pts_t pts_in = i->first, pts_out = i->second;
1208 if (m_tstools.getOffset(offset_in, pts_in, -1) || m_tstools.getOffset(offset_out, pts_out, 1))
1210 eDebug("span translation failed.\n");
1213 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
1214 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1221 /* align toward zero */
1222 static inline long long align(long long x, int align)
1237 /* remember, this gets called from another thread. */
1238 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
1240 const int blocksize = 188;
1241 unsigned int max = align(10*1024*1024, blocksize);
1242 current_offset = align(current_offset, blocksize);
1246 eDebug("no cue sheet. forcing normal play");
1247 start = current_offset;
1252 m_cue->m_lock.RdLock();
1253 if (!m_cue->m_decoding_demux)
1255 start = current_offset;
1257 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
1258 m_cue->m_lock.Unlock();
1264 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
1265 max = align(m_skipmode_n, blocksize);
1268 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1270 current_offset += align(m_skipmode_m, blocksize);
1272 while (!m_cue->m_seek_requests.empty())
1274 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1275 m_cue->m_lock.Unlock();
1276 m_cue->m_lock.WrLock();
1277 m_cue->m_seek_requests.pop_front();
1278 m_cue->m_lock.Unlock();
1279 m_cue->m_lock.RdLock();
1280 int relative = seek.first;
1281 pts_t pts = seek.second;
1286 if (!m_cue->m_decoder)
1288 eDebug("no decoder - can't seek relative");
1291 if (m_cue->m_decoder->getPTS(0, now))
1293 eDebug("decoder getPTS failed, can't seek relative");
1296 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1298 eDebug("seekTo: getCurrentPosition failed!");
1301 } else if (pts < 0) /* seek relative to end */
1304 if (!getLength(len))
1306 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1310 eWarning("getLength failed - can't seek relative to end!");
1315 if (relative == 1) /* pts relative */
1326 if (relative == 2) /* AP relative */
1328 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1330 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1332 pts = now - 90000; /* approx. 1s */
1333 eDebug("AP relative seeking failed!");
1337 eDebug("next ap is %llx\n", pts);
1342 if (m_tstools.getOffset(offset, pts, -1))
1344 eDebug("get offset for pts=%lld failed!", pts);
1348 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1349 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1352 m_cue->m_lock.Unlock();
1354 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1356 long long aligned_start = align(i->first, blocksize);
1357 long long aligned_end = align(i->second, blocksize);
1359 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1361 start = current_offset;
1362 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1363 if ((aligned_end - current_offset) > max)
1366 size = aligned_end - current_offset;
1367 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1370 if (current_offset < aligned_start)
1372 /* ok, our current offset is in an 'out' zone. */
1373 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1375 /* in normal playback, just start at the next zone. */
1378 /* size is not 64bit! */
1379 if ((i->second - i->first) > max)
1382 size = aligned_end - aligned_start;
1385 if (m_skipmode_m < 0)
1387 eDebug("reached SOF");
1390 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1394 /* when skipping reverse, however, choose the zone before. */
1396 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1399 aligned_start = align(i->first, blocksize);
1400 aligned_end = align(i->second, blocksize);
1402 if ((aligned_end - aligned_start) > max)
1405 len = aligned_end - aligned_start;
1407 start = aligned_end - len;
1408 eDebug("skipping to %llx, %d", start, len);
1411 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1416 if (m_source_span.empty()) {
1417 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1419 eDebug("reached SOF");
1421 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1423 start = current_offset;
1426 off_t tmp2, tmp = align(m_source_span.rbegin()->second, blocksize);
1429 m_tstools.getOffset(tmp2, len, 1);
1430 if (current_offset == tmp || current_offset == tmp2) {
1434 start = tmp - align(512*1024, blocksize);
1435 size = align(512*1024, blocksize);
1439 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
1443 void eDVBChannel::AddUse()
1445 if (++m_use_count > 1 && m_state == state_last_instance)
1448 m_stateChanged(this);
1452 void eDVBChannel::ReleaseUse()
1456 m_state = state_release;
1457 m_stateChanged(this);
1459 else if (m_use_count == 1)
1461 m_state = state_last_instance;
1462 m_stateChanged(this);
1466 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1469 m_mgr->removeChannel(this);
1476 eDebug("no frontend to tune!");
1480 m_channel_id = channelid;
1481 m_mgr->addChannel(channelid, this);
1482 m_state = state_tuning;
1483 /* if tuning fails, shutdown the channel immediately. */
1485 res = m_frontend->get().tune(*feparm);
1486 m_current_frontend_parameters = feparm;
1490 m_state = state_release;
1491 m_stateChanged(this);
1498 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1500 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1504 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1506 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1510 RESULT eDVBChannel::getState(int &state)
1516 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1521 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1523 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1529 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1534 /* don't hold a reference to the decoding demux, we don't need it. */
1536 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1537 the refcount is lost. thus, decoding demuxes are never allocated.
1539 this poses a big problem for PiP. */
1540 if (cap & capDecode)
1545 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1550 frontend = &m_frontend->get();
1556 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1558 param = m_current_frontend_parameters;
1562 RESULT eDVBChannel::playFile(const char *file)
1564 ASSERT(!m_frontend);
1567 m_pvr_thread->stop();
1568 delete m_pvr_thread;
1572 m_tstools.openFile(file);
1574 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1575 THEN DO A REAL FIX HERE! */
1577 /* (this codepath needs to be improved anyway.) */
1578 #if HAVE_DVB_API_VERSION < 3
1579 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1581 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1583 if (m_pvr_fd_dst < 0)
1585 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1589 m_pvr_thread = new eDVBChannelFilePush();
1590 m_pvr_thread->enablePVRCommit(1);
1591 m_pvr_thread->setStreamMode(1);
1592 m_pvr_thread->setScatterGather(this);
1594 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1596 delete m_pvr_thread;
1598 eDebug("can't open PVR file %s (%m)", file);
1601 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1604 m_stateChanged(this);
1609 void eDVBChannel::stopFile()
1613 m_pvr_thread->stop();
1614 ::close(m_pvr_fd_dst);
1615 delete m_pvr_thread;
1620 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1622 m_conn_cueSheetEvent = 0;
1625 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1628 RESULT eDVBChannel::getLength(pts_t &len)
1630 return m_tstools.calcLen(len);
1633 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1635 if (!decoding_demux)
1642 if (mode == 0) /* demux */
1644 r = decoding_demux->getSTC(now, 0);
1647 eDebug("demux getSTC failed");
1651 now = pos; /* fixup supplied */
1653 off_t off = 0; /* TODO: fixme */
1654 r = m_tstools.fixupPTS(off, now);
1657 eDebug("fixup PTS failed");
1666 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1668 /* when seeking, we have to ensure that all buffers are flushed.
1669 there are basically 3 buffers:
1670 a.) the filepush's internal buffer
1671 b.) the PVR buffer (before demux)
1672 c.) the ratebuffer (after demux)
1674 it's important to clear them in the correct order, otherwise
1675 the ratebuffer (for example) would immediately refill from
1676 the not-yet-flushed PVR buffer.
1679 m_pvr_thread->pause();
1680 /* flush internal filepush buffer */
1681 m_pvr_thread->flush();
1682 /* HACK: flush PVR buffer */
1683 ::ioctl(m_pvr_fd_dst, 0);
1685 /* flush ratebuffers (video, audio) */
1687 decoding_demux->flush();
1689 /* demux will also flush all decoder.. */
1690 /* resume will re-query the SG */
1691 m_pvr_thread->resume();
1694 DEFINE_REF(eCueSheet);
1696 eCueSheet::eCueSheet()
1698 m_skipmode_ratio = 0;
1701 void eCueSheet::seekTo(int relative, const pts_t &pts)
1704 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1709 void eCueSheet::clear()
1716 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1718 assert(begin < end);
1720 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1724 void eCueSheet::commitSpans()
1726 m_event(evtSpanChanged);
1729 void eCueSheet::setSkipmode(const pts_t &ratio)
1732 m_skipmode_ratio = ratio;
1734 m_event(evtSkipmode);
1737 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1739 m_decoding_demux = demux;
1740 m_decoder = decoder;
1743 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1745 connection = new eConnection(this, m_event.connect(event));