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(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;
584 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);
651 ch = new eDVBChannel(this, fe);
658 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
660 ePtr<eDVBAllocatedDemux> demux;
662 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
664 m_cached_channel_state_changed_conn.disconnect();
666 m_releaseCachedChannelTimer.stop();
670 ch = new eDVBChannel(this, 0);
676 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
678 ePtr<iDVBFrontend> fe;
679 if (!ch->getFrontend(fe))
681 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
682 if (frontend->is_simulate())
683 m_active_simulate_channels.push_back(active_channel(chid, ch));
686 m_active_channels.push_back(active_channel(chid, ch));
687 /* emit */ m_channelAdded(ch);
693 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
695 ePtr<iDVBFrontend> fe;
696 if (!ch->getFrontend(fe))
698 eDVBFrontend *frontend = (eDVBFrontend*)&(*fe);
699 std::list<active_channel> &active_channels = frontend->is_simulate() ? m_active_simulate_channels : m_active_channels;
701 for (std::list<active_channel>::iterator i(active_channels.begin()); i != active_channels.end();)
703 if (i->m_channel == ch)
705 i = active_channels.erase(i);
717 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
719 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
723 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
725 ePtr<eDVBRegisteredFrontend> best;
728 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
731 int c = i->m_frontend->isCompatibleWith(feparm);
738 int tuner_type_channel_default(ePtr<iDVBChannelList> &channellist, const eDVBChannelID &chid)
742 ePtr<iDVBFrontendParameters> feparm;
743 if (!channellist->getChannelFrontendData(chid, feparm))
746 if (!feparm->getSystem(system))
750 case iDVBFrontend::feSatellite:
752 case iDVBFrontend::feCable:
754 case iDVBFrontend::feTerrestrial:
765 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
768 if (m_cached_channel)
770 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
771 if(channelid==cache_chan->getChannelID())
772 return tuner_type_channel_default(m_list, channelid);
775 /* first, check if a channel is already existing. */
776 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
777 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
779 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
780 if (i->m_channel_id == channelid)
782 // eDebug("found shared channel..");
783 return tuner_type_channel_default(m_list, channelid);
787 int *decremented_cached_channel_fe_usecount=NULL,
788 *decremented_fe_usecount=NULL;
790 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
792 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
793 if (i->m_channel_id == ignore)
795 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
796 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
797 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
798 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
799 // or 2 when the cached channel is not equal to the compared channel
800 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
802 ePtr<iDVBFrontend> fe;
803 if (!i->m_channel->getFrontend(fe))
805 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
807 if ( &(*fe) == &(*ii->m_frontend) )
810 decremented_fe_usecount = &ii->m_inuse;
811 if (channel == &(*m_cached_channel))
812 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
822 if (!decremented_cached_channel_fe_usecount)
824 if (m_cached_channel)
826 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
827 if (channel->getUseCount() == 1)
829 ePtr<iDVBFrontend> fe;
830 if (!channel->getFrontend(fe))
832 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
834 if ( &(*fe) == &(*ii->m_frontend) )
837 decremented_cached_channel_fe_usecount = &ii->m_inuse;
846 decremented_cached_channel_fe_usecount=NULL;
848 ePtr<iDVBFrontendParameters> feparm;
852 eDebug("no channel list set!");
856 if (m_list->getChannelFrontendData(channelid, feparm))
858 eDebug("channel not found!");
862 ret = canAllocateFrontend(feparm);
865 if (decremented_fe_usecount)
866 ++(*decremented_fe_usecount);
867 if (decremented_cached_channel_fe_usecount)
868 ++(*decremented_cached_channel_fe_usecount);
873 bool eDVBResourceManager::canMeasureFrontendInputPower()
875 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
877 return i->m_frontend->readInputpower() >= 0;
882 class eDVBChannelFilePush: public eFilePushThread
885 eDVBChannelFilePush() { setIFrameSearch(0); setTimebaseChange(0); }
886 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
888 /* "timebase change" is for doing trickmode playback at an exact speed, even when pictures are skipped. */
889 /* you need to set it to 1/16 if you want 16x playback, for example. you need video master sync. */
890 void setTimebaseChange(int ratio) { m_timebase_change = ratio; } /* 16bit fixpoint, 0 for disable */
892 int m_iframe_search, m_iframe_state, m_pid;
893 int m_timebase_change;
894 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
897 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
900 if (m_timebase_change)
902 eDebug("timebase change: %d", m_timebase_change);
904 for (offset = 0; offset < len; offset += 188)
906 unsigned char *pkt = (unsigned char*)_data + offset;
907 if (pkt[1] & 0x40) /* pusi */
909 if (pkt[3] & 0x20) // adaption field present?
910 pkt += pkt[4] + 4 + 1; /* skip adaption field and header */
912 pkt += 4; /* skip header */
913 if (pkt[0] || pkt[1] || (pkt[2] != 1))
915 eWarning("broken startcode");
921 if (pkt[7] & 0x80) // PTS present?
923 pts = ((unsigned long long)(pkt[ 9]&0xE)) << 29;
924 pts |= ((unsigned long long)(pkt[10]&0xFF)) << 22;
925 pts |= ((unsigned long long)(pkt[11]&0xFE)) << 14;
926 pts |= ((unsigned long long)(pkt[12]&0xFF)) << 7;
927 pts |= ((unsigned long long)(pkt[13]&0xFE)) >> 1;
931 RESULT r = m_tstools.fixupPTS(off, pts);
933 eWarning("fixup PTS while trickmode playback failed.\n");
936 int sec = pts / 90000;
937 int frm = pts % 90000;
945 // eDebug("original, fixed pts: %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
948 pts *= m_timebase_change;
960 // eDebug("new pts (after timebase change): %016llx %d:%02d:%02d:%02d:%05d", pts, d, hr, min, sec, frm);
968 pkt[9] |= (pts >> 29) & 0xE;
969 pkt[10] |= (pts >> 22) & 0xFF;
970 pkt[11] |= (pts >> 14) & 0xFE;
971 pkt[12] |= (pts >> 7) & 0xFF;
972 pkt[13] |= (pts << 1) & 0xFE;
980 if (!m_iframe_search)
983 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
985 // eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
987 unsigned char *d = data;
988 while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
990 int offset = d - data;
991 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
992 unsigned char *ts = data + ts_offset;
993 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
995 if ((d[3] == 0) && (m_pid == pid)) /* picture start */
997 int picture_type = (d[5] >> 3) & 7;
1000 // eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
1002 if (m_iframe_state == 1)
1004 /* we are allowing data, and stop allowing data on the next frame.
1005 we now found a frame. so stop here. */
1006 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
1007 current_span_remaining = 0;
1009 unsigned char *fts = ts + 188;
1010 while (fts < (data + len))
1013 fts[2] |= 0xff; /* drop packet */
1017 return len; // ts_offset + 188; /* deliver this packet, but not more. */
1020 if (picture_type != 1) /* we are only interested in I frames */
1023 unsigned char *fts = data;
1027 fts[2] |= 0xff; /* drop packet */
1031 /* force payload only */
1035 // memset(ts + 4, 0xFF, (offset % 188) - 4);
1039 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
1043 eDebug("now locked to pid %04x", pid);
1049 d += 4; /* ignore */
1053 if (m_iframe_state == 1)
1056 return 0; /* we need find an iframe first */
1062 DEFINE_REF(eDVBChannel);
1064 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
1066 m_frontend = frontend;
1070 m_skipmode_n = m_skipmode_m = 0;
1073 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
1076 eDVBChannel::~eDVBChannel()
1079 m_mgr->removeChannel(this);
1084 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
1086 int state, ourstate = 0;
1088 /* if we are already in shutdown, don't change state. */
1089 if (m_state == state_release)
1092 if (fe->getState(state))
1095 if (state == iDVBFrontend::stateLock)
1097 eDebug("OURSTATE: ok");
1098 ourstate = state_ok;
1099 } else if (state == iDVBFrontend::stateTuning)
1101 eDebug("OURSTATE: tuning");
1102 ourstate = state_tuning;
1103 } else if (state == iDVBFrontend::stateLostLock)
1105 /* on managed channels, we try to retune in order to re-acquire lock. */
1106 if (m_current_frontend_parameters)
1108 eDebug("OURSTATE: lost lock, trying to retune");
1109 ourstate = state_tuning;
1110 m_frontend->get().tune(*m_current_frontend_parameters);
1112 /* on unmanaged channels, we don't do this. the client will do this. */
1114 eDebug("OURSTATE: lost lock, unavailable now.");
1115 ourstate = state_unavailable;
1117 } else if (state == iDVBFrontend::stateFailed)
1119 eDebug("OURSTATE: failed");
1120 ourstate = state_failed;
1122 eFatal("state unknown");
1124 if (ourstate != m_state)
1127 m_stateChanged(this);
1131 void eDVBChannel::pvrEvent(int event)
1135 case eFilePushThread::evtEOF:
1136 eDebug("eDVBChannel: End of file!");
1137 m_event(this, evtEOF);
1139 case eFilePushThread::evtUser: /* start */
1141 m_event(this, evtSOF);
1146 void eDVBChannel::cueSheetEvent(int event)
1148 /* we might end up here if playing failed or stopped, but the client hasn't (yet) noted. */
1153 case eCueSheet::evtSeek:
1155 flushPVR(m_cue->m_decoding_demux);
1157 case eCueSheet::evtSkipmode:
1160 m_cue->m_lock.WrLock();
1161 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
1162 m_cue->m_lock.Unlock();
1163 eRdLocker l(m_cue->m_lock);
1164 if (m_cue->m_skipmode_ratio)
1166 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
1167 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
1168 /* i agree that this might look a bit like black magic. */
1169 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
1170 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
1172 if (m_cue->m_skipmode_ratio < 0)
1173 m_skipmode_m -= m_skipmode_n;
1175 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
1177 if (abs(m_skipmode_m) < abs(m_skipmode_n))
1179 eWarning("something is wrong with this calculation");
1180 m_skipmode_n = m_skipmode_m = 0;
1184 eDebug("skipmode ratio is 0, normal play");
1185 m_skipmode_n = m_skipmode_m = 0;
1188 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
1189 if (m_cue->m_skipmode_ratio != 0)
1190 m_pvr_thread->setTimebaseChange(0x10000 * 9000 / (m_cue->m_skipmode_ratio / 10)); /* negative values are also ok */
1192 m_pvr_thread->setTimebaseChange(0); /* normal playback */
1193 eDebug("flush pvr");
1194 flushPVR(m_cue->m_decoding_demux);
1198 case eCueSheet::evtSpanChanged:
1200 m_source_span.clear();
1201 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
1203 off_t offset_in, offset_out;
1204 pts_t pts_in = i->first, pts_out = i->second;
1205 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
1207 eDebug("span translation failed.\n");
1210 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
1211 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
1218 /* align toward zero */
1219 static inline long long align(long long x, int align)
1234 /* remember, this gets called from another thread. */
1235 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
1237 const int blocksize = 188;
1238 unsigned int max = align(10*1024*1024, blocksize);
1239 current_offset = align(current_offset, blocksize);
1243 eDebug("no cue sheet. forcing normal play");
1244 start = current_offset;
1249 m_cue->m_lock.RdLock();
1250 if (!m_cue->m_decoding_demux)
1252 start = current_offset;
1254 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
1255 m_cue->m_lock.Unlock();
1261 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
1262 max = align(m_skipmode_n, blocksize);
1265 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1267 current_offset += align(m_skipmode_m, blocksize);
1269 while (!m_cue->m_seek_requests.empty())
1271 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1272 m_cue->m_lock.Unlock();
1273 m_cue->m_lock.WrLock();
1274 m_cue->m_seek_requests.pop_front();
1275 m_cue->m_lock.Unlock();
1276 m_cue->m_lock.RdLock();
1277 int relative = seek.first;
1278 pts_t pts = seek.second;
1283 if (!m_cue->m_decoder)
1285 eDebug("no decoder - can't seek relative");
1288 if (m_cue->m_decoder->getPTS(0, now))
1290 eDebug("decoder getPTS failed, can't seek relative");
1293 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1295 eDebug("seekTo: getCurrentPosition failed!");
1298 } else if (pts < 0) /* seek relative to end */
1301 if (!getLength(len))
1303 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1307 eWarning("getLength failed - can't seek relative to end!");
1312 if (relative == 1) /* pts relative */
1323 if (relative == 2) /* AP relative */
1325 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1327 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1329 pts = now - 90000; /* approx. 1s */
1330 eDebug("AP relative seeking failed!");
1333 eDebug("next ap is %llx\n", pts);
1339 if (m_tstools.getOffset(offset, pts))
1341 eDebug("get offset for pts=%lld failed!", pts);
1345 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1346 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1349 m_cue->m_lock.Unlock();
1351 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1353 long long aligned_start = align(i->first, blocksize);
1354 long long aligned_end = align(i->second, blocksize);
1356 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1358 start = current_offset;
1359 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1360 if ((aligned_end - current_offset) > max)
1363 size = aligned_end - current_offset;
1364 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1367 if (current_offset < aligned_start)
1369 /* ok, our current offset is in an 'out' zone. */
1370 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1372 /* in normal playback, just start at the next zone. */
1375 /* size is not 64bit! */
1376 if ((i->second - i->first) > max)
1379 size = aligned_end - aligned_start;
1382 if (m_skipmode_m < 0)
1384 eDebug("reached SOF");
1387 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1391 /* when skipping reverse, however, choose the zone before. */
1393 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1396 aligned_start = align(i->first, blocksize);
1397 aligned_end = align(i->second, blocksize);
1399 if ((aligned_end - aligned_start) > max)
1402 len = aligned_end - aligned_start;
1404 start = aligned_end - len;
1405 eDebug("skipping to %llx, %d", start, len);
1408 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1413 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1415 eDebug("reached SOF");
1417 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1420 start = current_offset;
1423 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
1427 void eDVBChannel::AddUse()
1429 if (++m_use_count > 1 && m_state == state_last_instance)
1432 m_stateChanged(this);
1436 void eDVBChannel::ReleaseUse()
1440 m_state = state_release;
1441 m_stateChanged(this);
1443 else if (m_use_count == 1)
1445 m_state = state_last_instance;
1446 m_stateChanged(this);
1450 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1453 m_mgr->removeChannel(this);
1460 eDebug("no frontend to tune!");
1464 m_channel_id = channelid;
1465 m_mgr->addChannel(channelid, this);
1466 m_state = state_tuning;
1467 /* if tuning fails, shutdown the channel immediately. */
1469 res = m_frontend->get().tune(*feparm);
1470 m_current_frontend_parameters = feparm;
1474 m_state = state_release;
1475 m_stateChanged(this);
1482 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1484 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1488 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1490 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1494 RESULT eDVBChannel::getState(int &state)
1500 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1505 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1507 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1513 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1518 /* don't hold a reference to the decoding demux, we don't need it. */
1520 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1521 the refcount is lost. thus, decoding demuxes are never allocated.
1523 this poses a big problem for PiP. */
1524 if (cap & capDecode)
1529 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1534 frontend = &m_frontend->get();
1540 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1542 param = m_current_frontend_parameters;
1546 RESULT eDVBChannel::playFile(const char *file)
1548 ASSERT(!m_frontend);
1551 m_pvr_thread->stop();
1552 delete m_pvr_thread;
1556 m_tstools.openFile(file);
1558 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1559 THEN DO A REAL FIX HERE! */
1561 /* (this codepath needs to be improved anyway.) */
1562 #if HAVE_DVB_API_VERSION < 3
1563 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1565 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1567 if (m_pvr_fd_dst < 0)
1569 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1573 m_pvr_thread = new eDVBChannelFilePush();
1574 m_pvr_thread->enablePVRCommit(1);
1575 m_pvr_thread->setStreamMode(1);
1576 m_pvr_thread->setScatterGather(this);
1578 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1580 delete m_pvr_thread;
1582 eDebug("can't open PVR file %s (%m)", file);
1585 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1588 m_stateChanged(this);
1593 void eDVBChannel::stopFile()
1597 m_pvr_thread->stop();
1598 ::close(m_pvr_fd_dst);
1599 delete m_pvr_thread;
1604 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1606 m_conn_cueSheetEvent = 0;
1609 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1612 RESULT eDVBChannel::getLength(pts_t &len)
1614 return m_tstools.calcLen(len);
1617 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1619 if (!decoding_demux)
1626 if (mode == 0) /* demux */
1628 r = decoding_demux->getSTC(now, 0);
1631 eDebug("demux getSTC failed");
1635 now = pos; /* fixup supplied */
1637 off_t off = 0; /* TODO: fixme */
1638 r = m_tstools.fixupPTS(off, now);
1641 eDebug("fixup PTS failed");
1650 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1652 /* when seeking, we have to ensure that all buffers are flushed.
1653 there are basically 3 buffers:
1654 a.) the filepush's internal buffer
1655 b.) the PVR buffer (before demux)
1656 c.) the ratebuffer (after demux)
1658 it's important to clear them in the correct order, otherwise
1659 the ratebuffer (for example) would immediately refill from
1660 the not-yet-flushed PVR buffer.
1663 m_pvr_thread->pause();
1664 /* flush internal filepush buffer */
1665 m_pvr_thread->flush();
1666 /* HACK: flush PVR buffer */
1667 ::ioctl(m_pvr_fd_dst, 0);
1669 /* flush ratebuffers (video, audio) */
1671 decoding_demux->flush();
1673 /* demux will also flush all decoder.. */
1674 /* resume will re-query the SG */
1675 m_pvr_thread->resume();
1678 DEFINE_REF(eCueSheet);
1680 eCueSheet::eCueSheet()
1682 m_skipmode_ratio = 0;
1685 void eCueSheet::seekTo(int relative, const pts_t &pts)
1688 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1693 void eCueSheet::clear()
1700 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1702 assert(begin < end);
1704 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1708 void eCueSheet::commitSpans()
1710 m_event(evtSpanChanged);
1713 void eCueSheet::setSkipmode(const pts_t &ratio)
1716 m_skipmode_ratio = ratio;
1718 m_event(evtSkipmode);
1721 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1723 m_decoding_demux = demux;
1724 m_decoder = decoder;
1727 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1729 connection = new eConnection(this, m_event.connect(event));