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/sec.h>
12 #include <sys/ioctl.h>
14 DEFINE_REF(eDVBRegisteredFrontend);
15 DEFINE_REF(eDVBRegisteredDemux);
17 DEFINE_REF(eDVBAllocatedFrontend);
19 eDVBAllocatedFrontend::eDVBAllocatedFrontend(eDVBRegisteredFrontend *fe): m_fe(fe)
24 eDVBAllocatedFrontend::~eDVBAllocatedFrontend()
29 DEFINE_REF(eDVBAllocatedDemux);
31 eDVBAllocatedDemux::eDVBAllocatedDemux(eDVBRegisteredDemux *demux): m_demux(demux)
36 eDVBAllocatedDemux::~eDVBAllocatedDemux()
41 DEFINE_REF(eDVBResourceManager);
43 eDVBResourceManager *eDVBResourceManager::instance;
45 RESULT eDVBResourceManager::getInstance(ePtr<eDVBResourceManager> &ptr)
55 ePtr<eDVBResourceManager> NewResourceManagerPtr(void)
57 ePtr<eDVBResourceManager> ptr;
58 eDVBResourceManager::getInstance(ptr);
62 eDVBResourceManager::eDVBResourceManager()
63 :m_releaseCachedChannelTimer(eApp)
67 m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
71 /* search available adapters... */
76 while (eDVBAdapterLinux::exist(num_adapter))
78 addAdapter(new eDVBAdapterLinux(num_adapter));
82 eDebug("found %d adapter, %d frontends and %d demux",
83 m_adapter.size(), m_frontend.size(), m_demux.size());
85 CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel);
88 void eDVBResourceManager::feStateChanged()
91 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
93 mask |= ( 1 << i->m_frontend->getSlotID() );
94 /* emit */ frontendUseMaskChanged(mask);
97 DEFINE_REF(eDVBAdapterLinux);
98 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
103 eDebug("scanning for frontends..");
108 #if HAVE_DVB_API_VERSION < 3
109 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
111 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
113 if (stat(filename, &s))
115 ePtr<eDVBFrontend> fe;
118 fe = new eDVBFrontend(m_nr, num_fe, ok);
120 m_frontend.push_back(fe);
130 #if HAVE_DVB_API_VERSION < 3
131 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
133 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
135 if (stat(filename, &s))
137 ePtr<eDVBDemux> demux;
139 demux = new eDVBDemux(m_nr, num_demux);
140 m_demux.push_back(demux);
146 int eDVBAdapterLinux::getNumDemux()
148 return m_demux.size();
151 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
153 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
154 while (nr && (i != m_demux.end()))
160 if (i != m_demux.end())
168 int eDVBAdapterLinux::getNumFrontends()
170 return m_frontend.size();
173 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
175 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
176 while (nr && (i != m_frontend.end()))
182 if (i != m_frontend.end())
190 int eDVBAdapterLinux::exist(int nr)
194 #if HAVE_DVB_API_VERSION < 3
195 sprintf(filename, "/dev/dvb/card%d", nr);
197 sprintf(filename, "/dev/dvb/adapter%d", nr);
199 if (!stat(filename, &s))
204 eDVBResourceManager::~eDVBResourceManager()
206 if (instance == this)
210 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
212 int num_fe = adapter->getNumFrontends();
213 int num_demux = adapter->getNumDemux();
215 m_adapter.push_back(adapter);
218 for (i=0; i<num_demux; ++i)
220 ePtr<eDVBDemux> demux;
221 if (!adapter->getDemux(demux, i))
222 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
225 ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
226 for (i=0; i<num_fe; ++i)
228 ePtr<eDVBFrontend> frontend;
229 if (!adapter->getFrontend(frontend, i))
232 frontend->getFrontendType(frontendType);
233 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
234 CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
235 m_frontend.push_back(new_fe);
236 frontend->setSEC(m_sec);
237 // we must link all dvb-t frontends ( for active antenna voltage )
238 if (frontendType == iDVBFrontend::feTerrestrial)
240 if (prev_dvbt_frontend)
242 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (int)new_fe);
243 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (int)&(*prev_dvbt_frontend));
245 prev_dvbt_frontend = new_fe;
251 void eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
253 if (!PyList_Check(list))
255 PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
258 if (PyList_Size(list) != m_frontend.size())
261 sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist",
262 m_frontend.size(), PyList_Size(list));
263 PyErr_SetString(PyExc_StandardError, blasel);
267 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
269 ePyObject obj = PyList_GET_ITEM(list, pos++);
270 i->m_frontend->setSlotInfo(obj);
274 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
276 ePtr<eDVBRegisteredFrontend> best;
279 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
282 int c = i->m_frontend->isCompatibleWith(feparm);
292 fe = new eDVBAllocatedFrontend(best);
301 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index)
303 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
304 if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index)
306 fe = new eDVBAllocatedFrontend(i);
314 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
316 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
317 never use the first one unless we need a decoding demux. */
319 eDebug("allocate demux");
320 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
322 if (i == m_demux.end())
326 /* FIXME: hardware demux policy */
327 if (!(cap & iDVBChannel::capDecode))
329 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
336 for (; i != m_demux.end(); ++i, ++n)
338 int is_decode = n < 2;
340 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
342 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
344 if ((cap & iDVBChannel::capDecode) && !is_decode)
347 demux = new eDVBAllocatedDemux(i);
349 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
351 demux->get().setSourcePVR(0);
355 eDebug("demux not found");
359 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
365 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
374 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
376 /* first, check if a channel is already existing. */
378 if (m_cached_channel)
380 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
381 if(channelid==cache_chan->getChannelID())
383 eDebug("use cached_channel");
384 channel = m_cached_channel;
387 m_cached_channel_state_changed_conn.disconnect();
389 m_releaseCachedChannelTimer.stop();
392 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
393 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
395 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
396 if (i->m_channel_id == channelid)
398 // eDebug("found shared channel..");
399 channel = i->m_channel;
404 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
408 eDebug("no channel list set!");
412 ePtr<iDVBFrontendParameters> feparm;
413 if (m_list->getChannelFrontendData(channelid, feparm))
415 eDebug("channel not found!");
419 /* allocate a frontend. */
421 ePtr<eDVBAllocatedFrontend> fe;
423 if (allocateFrontend(fe, feparm))
424 return errNoFrontend;
427 ePtr<eDVBChannel> ch;
428 ch = new eDVBChannel(this, fe);
430 res = ch->setChannel(channelid, feparm);
434 return errChidNotFound;
436 m_cached_channel = channel = ch;
437 m_cached_channel_state_changed_conn =
438 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
443 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
446 chan->getState(state);
449 case iDVBChannel::state_release:
450 case iDVBChannel::state_ok:
452 eDebug("stop release channel timer");
453 m_releaseCachedChannelTimer.stop();
456 case iDVBChannel::state_last_instance:
458 eDebug("start release channel timer");
459 m_releaseCachedChannelTimer.start(3000, true);
462 default: // ignore all other events
467 void eDVBResourceManager::releaseCachedChannel()
469 eDebug("release cached channel (timer timeout)");
473 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
475 ePtr<eDVBAllocatedFrontend> fe;
477 if (m_cached_channel)
479 m_cached_channel_state_changed_conn.disconnect();
481 m_releaseCachedChannelTimer.stop();
484 if (allocateFrontendByIndex(fe, slot_index))
485 return errNoFrontend;
488 ch = new eDVBChannel(this, fe);
495 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
497 ePtr<eDVBAllocatedDemux> demux;
499 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
501 m_cached_channel_state_changed_conn.disconnect();
503 m_releaseCachedChannelTimer.stop();
507 ch = new eDVBChannel(this, 0);
513 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
515 m_active_channels.push_back(active_channel(chid, ch));
516 /* emit */ m_channelAdded(ch);
520 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
523 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
525 if (i->m_channel == ch)
527 i = m_active_channels.erase(i);
538 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
540 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
544 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
546 ePtr<eDVBRegisteredFrontend> best;
549 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
552 int c = i->m_frontend->isCompatibleWith(feparm);
560 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
563 if (m_cached_channel)
565 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
566 if(channelid==cache_chan->getChannelID())
570 /* first, check if a channel is already existing. */
571 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
572 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
574 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
575 if (i->m_channel_id == channelid)
577 // eDebug("found shared channel..");
582 int *decremented_cached_channel_fe_usecount=NULL,
583 *decremented_fe_usecount=NULL;
585 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
587 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
588 if (i->m_channel_id == ignore)
590 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
591 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
592 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
593 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
594 // or 2 when the cached channel is not equal to the compared channel
595 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
597 ePtr<iDVBFrontend> fe;
598 if (!i->m_channel->getFrontend(fe))
600 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
602 if ( &(*fe) == &(*ii->m_frontend) )
605 decremented_fe_usecount = &ii->m_inuse;
606 if (channel == &(*m_cached_channel))
607 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
617 if (!decremented_cached_channel_fe_usecount)
619 if (m_cached_channel)
621 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
622 if (channel->getUseCount() == 1)
624 ePtr<iDVBFrontend> fe;
625 if (!channel->getFrontend(fe))
627 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
629 if ( &(*fe) == &(*ii->m_frontend) )
632 decremented_cached_channel_fe_usecount = &ii->m_inuse;
641 decremented_cached_channel_fe_usecount=NULL;
643 ePtr<iDVBFrontendParameters> feparm;
647 eDebug("no channel list set!");
652 if (m_list->getChannelFrontendData(channelid, feparm))
654 eDebug("channel not found!");
659 ret = canAllocateFrontend(feparm);
662 if (decremented_fe_usecount)
663 ++(*decremented_fe_usecount);
664 if (decremented_cached_channel_fe_usecount)
665 ++(*decremented_cached_channel_fe_usecount);
670 class eDVBChannelFilePush: public eFilePushThread
673 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
675 int m_iframe_search, m_iframe_state, m_pid;
676 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
679 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
682 if (!m_iframe_search)
685 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
687 eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
689 unsigned char *d = data;
690 while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
692 int offset = d - data;
693 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
694 unsigned char *ts = data + ts_offset;
695 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
697 if ((d[3] == 0) && (m_pid == pid)) /* picture start */
699 int picture_type = (d[5] >> 3) & 7;
702 eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
704 if (m_iframe_state == 1)
706 /* we are allowing data, and stop allowing data on the next frame.
707 we now found a frame. so stop here. */
708 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
709 current_span_remaining = 0;
711 unsigned char *fts = ts + 188;
712 while (fts < (data + len))
715 fts[2] |= 0xff; /* drop packet */
719 return len; // ts_offset + 188; /* deliver this packet, but not more. */
722 if (picture_type != 1) /* we are only interested in I frames */
725 unsigned char *fts = data;
729 fts[2] |= 0xff; /* drop packet */
733 /* force payload only */
737 // memset(ts + 4, 0xFF, (offset % 188) - 4);
741 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
745 eDebug("now locked to pid %04x", pid);
755 if (m_iframe_state == 1)
758 return 0; /* we need find an iframe first */
764 DEFINE_REF(eDVBChannel);
766 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
768 m_frontend = frontend;
772 m_skipmode_n = m_skipmode_m = 0;
775 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
778 eDVBChannel::~eDVBChannel()
781 m_mgr->removeChannel(this);
786 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
788 int state, ourstate = 0;
790 /* if we are already in shutdown, don't change state. */
791 if (m_state == state_release)
794 if (fe->getState(state))
797 if (state == iDVBFrontend::stateLock)
799 eDebug("OURSTATE: ok");
801 } else if (state == iDVBFrontend::stateTuning)
803 eDebug("OURSTATE: tuning");
804 ourstate = state_tuning;
805 } else if (state == iDVBFrontend::stateLostLock)
807 /* on managed channels, we try to retune in order to re-acquire lock. */
808 if (m_current_frontend_parameters)
810 eDebug("OURSTATE: lost lock, trying to retune");
811 ourstate = state_tuning;
812 m_frontend->get().tune(*m_current_frontend_parameters);
814 /* on unmanaged channels, we don't do this. the client will do this. */
816 eDebug("OURSTATE: lost lock, unavailable now.");
817 ourstate = state_unavailable;
819 } else if (state == iDVBFrontend::stateFailed)
821 eDebug("OURSTATE: failed");
822 ourstate = state_failed;
824 eFatal("state unknown");
826 if (ourstate != m_state)
829 m_stateChanged(this);
833 void eDVBChannel::pvrEvent(int event)
837 case eFilePushThread::evtEOF:
838 eDebug("eDVBChannel: End of file!");
839 m_event(this, evtEOF);
841 case eFilePushThread::evtUser: /* start */
843 m_event(this, evtSOF);
848 void eDVBChannel::cueSheetEvent(int event)
852 case eCueSheet::evtSeek:
854 flushPVR(m_cue->m_decoding_demux);
856 case eCueSheet::evtSkipmode:
859 eSingleLocker l(m_cue->m_lock);
860 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
861 if (m_cue->m_skipmode_ratio)
863 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
864 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
865 /* i agree that this might look a bit like black magic. */
866 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
867 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
869 if (m_cue->m_skipmode_ratio < 0)
870 m_skipmode_m -= m_skipmode_n;
872 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
874 if (abs(m_skipmode_m) < abs(m_skipmode_n))
876 eWarning("something is wrong with this calculation");
877 m_skipmode_n = m_skipmode_m = 0;
882 eDebug("skipmode ratio is 0, normal play");
883 m_skipmode_n = m_skipmode_m = 0;
886 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
888 flushPVR(m_cue->m_decoding_demux);
892 case eCueSheet::evtSpanChanged:
894 m_source_span.clear();
895 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
897 off_t offset_in, offset_out;
898 pts_t pts_in = i->first, pts_out = i->second;
899 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
901 eDebug("span translation failed.\n");
904 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
905 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
912 /* align toward zero */
913 static inline long long align(long long x, int align)
928 /* remember, this gets called from another thread. */
929 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
931 const int blocksize = 188;
932 unsigned int max = align(10*1024*1024, blocksize);
933 current_offset = align(current_offset, blocksize);
937 eDebug("no cue sheet. forcing normal play");
938 start = current_offset;
943 eSingleLocker l(m_cue->m_lock);
945 if (!m_cue->m_decoding_demux)
947 start = current_offset;
949 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
955 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
956 max = align(m_skipmode_n, blocksize);
959 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
961 current_offset += align(m_skipmode_m, blocksize);
963 while (!m_cue->m_seek_requests.empty())
965 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
966 m_cue->m_seek_requests.pop_front();
967 int relative = seek.first;
968 pts_t pts = seek.second;
973 if (!m_cue->m_decoder)
975 eDebug("no decoder - can't seek relative");
978 if (m_cue->m_decoder->getPTS(0, now))
980 eDebug("decoder getPTS failed, can't seek relative");
983 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
985 eDebug("seekTo: getCurrentPosition failed!");
988 } else if (pts < 0) /* seek relative to end */
993 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
997 eWarning("getLength failed - can't seek relative to end!");
1002 if (relative == 1) /* pts relative */
1013 if (relative == 2) /* AP relative */
1015 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1017 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1020 eDebug("AP relative seeking failed!");
1023 eDebug("next ap is %llx\n", pts);
1029 if (m_tstools.getOffset(offset, pts))
1031 eDebug("get offset for pts=%lld failed!", pts);
1035 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1036 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1039 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1041 long long aligned_start = align(i->first, blocksize);
1042 long long aligned_end = align(i->second, blocksize);
1044 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1046 start = current_offset;
1047 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1048 if ((aligned_end - current_offset) > max)
1051 size = aligned_end - current_offset;
1052 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1055 if (current_offset < aligned_start)
1057 /* ok, our current offset is in an 'out' zone. */
1058 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1060 /* in normal playback, just start at the next zone. */
1063 /* size is not 64bit! */
1064 if ((i->second - i->first) > max)
1067 size = aligned_end - aligned_start;
1070 if (m_skipmode_m < 0)
1072 eDebug("reached SOF");
1075 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1079 /* when skipping reverse, however, choose the zone before. */
1081 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1084 if ((i->second - i->first) > max)
1087 len = aligned_end - aligned_start;
1089 start = aligned_end - len;
1090 eDebug("skipping to %llx, %d", start, len);
1093 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1098 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1100 eDebug("reached SOF");
1102 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1105 start = current_offset;
1108 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
1112 void eDVBChannel::AddUse()
1114 if (++m_use_count > 1 && m_state == state_last_instance)
1117 m_stateChanged(this);
1121 void eDVBChannel::ReleaseUse()
1125 m_state = state_release;
1126 m_stateChanged(this);
1128 else if (m_use_count == 1)
1130 m_state = state_last_instance;
1131 m_stateChanged(this);
1135 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1138 m_mgr->removeChannel(this);
1145 eDebug("no frontend to tune!");
1149 m_channel_id = channelid;
1150 m_mgr->addChannel(channelid, this);
1151 m_state = state_tuning;
1152 /* if tuning fails, shutdown the channel immediately. */
1154 res = m_frontend->get().tune(*feparm);
1155 m_current_frontend_parameters = feparm;
1159 m_state = state_release;
1160 m_stateChanged(this);
1167 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1169 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1173 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1175 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1179 RESULT eDVBChannel::getState(int &state)
1185 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1190 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1192 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1198 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1203 /* don't hold a reference to the decoding demux, we don't need it. */
1205 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1206 the refcount is lost. thus, decoding demuxes are never allocated.
1208 this poses a big problem for PiP. */
1209 if (cap & capDecode)
1214 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1219 frontend = &m_frontend->get();
1225 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1227 param = m_current_frontend_parameters;
1231 RESULT eDVBChannel::playFile(const char *file)
1233 ASSERT(!m_frontend);
1236 m_pvr_thread->stop();
1237 delete m_pvr_thread;
1241 m_tstools.openFile(file);
1243 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1244 THEN DO A REAL FIX HERE! */
1246 /* (this codepath needs to be improved anyway.) */
1247 #if HAVE_DVB_API_VERSION < 3
1248 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1250 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1252 if (m_pvr_fd_dst < 0)
1254 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1258 m_pvr_thread = new eDVBChannelFilePush();
1259 m_pvr_thread->enablePVRCommit(1);
1260 m_pvr_thread->setStreamMode(1);
1261 m_pvr_thread->setScatterGather(this);
1263 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1265 delete m_pvr_thread;
1267 eDebug("can't open PVR file %s (%m)", file);
1270 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1273 m_stateChanged(this);
1278 void eDVBChannel::stopFile()
1282 m_pvr_thread->stop();
1283 ::close(m_pvr_fd_dst);
1284 delete m_pvr_thread;
1289 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1291 m_conn_cueSheetEvent = 0;
1294 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1297 RESULT eDVBChannel::getLength(pts_t &len)
1299 return m_tstools.calcLen(len);
1302 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1304 if (!decoding_demux)
1311 if (mode == 0) /* demux */
1313 r = decoding_demux->getSTC(now, 0);
1316 eDebug("demux getSTC failed");
1320 now = pos; /* fixup supplied */
1322 off_t off = 0; /* TODO: fixme */
1323 r = m_tstools.fixupPTS(off, now);
1326 eDebug("fixup PTS failed");
1335 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1337 /* when seeking, we have to ensure that all buffers are flushed.
1338 there are basically 3 buffers:
1339 a.) the filepush's internal buffer
1340 b.) the PVR buffer (before demux)
1341 c.) the ratebuffer (after demux)
1343 it's important to clear them in the correct order, otherwise
1344 the ratebuffer (for example) would immediately refill from
1345 the not-yet-flushed PVR buffer.
1348 m_pvr_thread->pause();
1349 /* flush internal filepush buffer */
1350 m_pvr_thread->flush();
1351 /* HACK: flush PVR buffer */
1352 ::ioctl(m_pvr_fd_dst, 0);
1354 /* flush ratebuffers (video, audio) */
1356 decoding_demux->flush();
1358 /* demux will also flush all decoder.. */
1359 /* resume will re-query the SG */
1360 m_pvr_thread->resume();
1363 DEFINE_REF(eCueSheet);
1365 eCueSheet::eCueSheet()
1367 m_skipmode_ratio = 0;
1370 void eCueSheet::seekTo(int relative, const pts_t &pts)
1373 eSingleLocker l(m_lock);
1374 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1379 void eCueSheet::clear()
1381 eSingleLocker l(m_lock);
1385 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1388 eSingleLocker l(m_lock);
1389 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1393 void eCueSheet::commitSpans()
1395 m_event(evtSpanChanged);
1398 void eCueSheet::setSkipmode(const pts_t &ratio)
1401 eSingleLocker l(m_lock);
1402 m_skipmode_ratio = ratio;
1404 m_event(evtSkipmode);
1407 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1409 m_decoding_demux = demux;
1410 m_decoder = decoder;
1413 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1415 connection = new eConnection(this, m_event.connect(event));