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);
72 /* search available adapters... */
77 while (eDVBAdapterLinux::exist(num_adapter))
79 addAdapter(new eDVBAdapterLinux(num_adapter));
83 eDebug("found %d adapter, %d frontends and %d demux",
84 m_adapter.size(), m_frontend.size(), m_demux.size());
86 eDVBCAService::registerChannelCallback(this);
88 CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel);
91 void eDVBResourceManager::feStateChanged()
94 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
96 mask |= ( 1 << i->m_frontend->getSlotID() );
97 /* emit */ frontendUseMaskChanged(mask);
100 DEFINE_REF(eDVBAdapterLinux);
101 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
106 eDebug("scanning for frontends..");
111 #if HAVE_DVB_API_VERSION < 3
112 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
114 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
116 if (stat(filename, &s))
118 ePtr<eDVBFrontend> fe;
121 fe = new eDVBFrontend(m_nr, num_fe, ok);
123 m_frontend.push_back(fe);
133 #if HAVE_DVB_API_VERSION < 3
134 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
136 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
138 if (stat(filename, &s))
140 ePtr<eDVBDemux> demux;
142 demux = new eDVBDemux(m_nr, num_demux);
143 m_demux.push_back(demux);
149 int eDVBAdapterLinux::getNumDemux()
151 return m_demux.size();
154 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
156 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
157 while (nr && (i != m_demux.end()))
163 if (i != m_demux.end())
171 int eDVBAdapterLinux::getNumFrontends()
173 return m_frontend.size();
176 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
178 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
179 while (nr && (i != m_frontend.end()))
185 if (i != m_frontend.end())
193 int eDVBAdapterLinux::exist(int nr)
197 #if HAVE_DVB_API_VERSION < 3
198 sprintf(filename, "/dev/dvb/card%d", nr);
200 sprintf(filename, "/dev/dvb/adapter%d", nr);
202 if (!stat(filename, &s))
207 eDVBResourceManager::~eDVBResourceManager()
209 if (instance == this)
213 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
215 int num_fe = adapter->getNumFrontends();
216 int num_demux = adapter->getNumDemux();
218 m_adapter.push_back(adapter);
221 for (i=0; i<num_demux; ++i)
223 ePtr<eDVBDemux> demux;
224 if (!adapter->getDemux(demux, i))
225 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
228 ePtr<eDVBRegisteredFrontend> prev_dvbt_frontend;
229 for (i=0; i<num_fe; ++i)
231 ePtr<eDVBFrontend> frontend;
232 if (!adapter->getFrontend(frontend, i))
235 frontend->getFrontendType(frontendType);
236 eDVBRegisteredFrontend *new_fe = new eDVBRegisteredFrontend(frontend, adapter);
237 CONNECT(new_fe->stateChanged, eDVBResourceManager::feStateChanged);
238 m_frontend.push_back(new_fe);
239 frontend->setSEC(m_sec);
240 // we must link all dvb-t frontends ( for active antenna voltage )
241 if (frontendType == iDVBFrontend::feTerrestrial)
243 if (prev_dvbt_frontend)
245 prev_dvbt_frontend->m_frontend->setData(eDVBFrontend::LINKED_NEXT_PTR, (int)new_fe);
246 frontend->setData(eDVBFrontend::LINKED_PREV_PTR, (int)&(*prev_dvbt_frontend));
248 prev_dvbt_frontend = new_fe;
254 PyObject *eDVBResourceManager::setFrontendSlotInformations(ePyObject list)
256 if (!PyList_Check(list))
258 PyErr_SetString(PyExc_StandardError, "eDVBResourceManager::setFrontendSlotInformations argument should be a python list");
261 if ((unsigned int)PyList_Size(list) != m_frontend.size())
264 sprintf(blasel, "eDVBResourceManager::setFrontendSlotInformations list size incorrect %d frontends avail, but %d entries in slotlist",
265 m_frontend.size(), PyList_Size(list));
266 PyErr_SetString(PyExc_StandardError, blasel);
270 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
272 ePyObject obj = PyList_GET_ITEM(list, pos++);
273 if (!i->m_frontend->setSlotInfo(obj))
279 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
281 ePtr<eDVBRegisteredFrontend> best;
284 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
287 int c = i->m_frontend->isCompatibleWith(feparm);
297 fe = new eDVBAllocatedFrontend(best);
306 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int slot_index)
308 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
309 if (!i->m_inuse && i->m_frontend->getSlotID() == slot_index)
311 // check if another slot linked to this is in use
312 eDVBRegisteredFrontend *satpos_depends_to_fe =
313 (eDVBRegisteredFrontend*) i->m_frontend->m_data[eDVBFrontend::SATPOS_DEPENDS_PTR];
314 if ( (int)satpos_depends_to_fe != -1 )
316 if (satpos_depends_to_fe->m_inuse)
318 eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!");
319 goto alloc_fe_by_id_not_possible;
322 else // check linked tuners
324 eDVBRegisteredFrontend *next =
325 (eDVBRegisteredFrontend *) i->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR];
326 while ( (int)next != -1 )
330 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
331 goto alloc_fe_by_id_not_possible;
333 next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR];
335 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)
336 i->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR];
337 while ( (int)prev != -1 )
341 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
342 goto alloc_fe_by_id_not_possible;
344 prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR];
347 fe = new eDVBAllocatedFrontend(i);
350 alloc_fe_by_id_not_possible:
355 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
357 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
358 never use the first one unless we need a decoding demux. */
360 eDebug("allocate demux");
361 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
363 if (i == m_demux.end())
367 /* FIXME: hardware demux policy */
368 if (!(cap & iDVBChannel::capDecode))
370 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
377 for (; i != m_demux.end(); ++i, ++n)
379 int is_decode = n < 2;
381 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
383 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
385 if ((cap & iDVBChannel::capDecode) && !is_decode)
388 demux = new eDVBAllocatedDemux(i);
390 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
392 demux->get().setSourcePVR(0);
396 eDebug("demux not found");
400 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
406 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
415 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
417 /* first, check if a channel is already existing. */
419 if (m_cached_channel)
421 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
422 if(channelid==cache_chan->getChannelID())
424 eDebug("use cached_channel");
425 channel = m_cached_channel;
428 m_cached_channel_state_changed_conn.disconnect();
430 m_releaseCachedChannelTimer.stop();
433 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
434 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
436 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
437 if (i->m_channel_id == channelid)
439 // eDebug("found shared channel..");
440 channel = i->m_channel;
445 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
449 eDebug("no channel list set!");
453 ePtr<iDVBFrontendParameters> feparm;
454 if (m_list->getChannelFrontendData(channelid, feparm))
456 eDebug("channel not found!");
460 /* allocate a frontend. */
462 ePtr<eDVBAllocatedFrontend> fe;
464 if (allocateFrontend(fe, feparm))
465 return errNoFrontend;
468 ePtr<eDVBChannel> ch;
469 ch = new eDVBChannel(this, fe);
471 res = ch->setChannel(channelid, feparm);
475 return errChidNotFound;
477 m_cached_channel = channel = ch;
478 m_cached_channel_state_changed_conn =
479 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
484 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
487 chan->getState(state);
490 case iDVBChannel::state_release:
491 case iDVBChannel::state_ok:
493 eDebug("stop release channel timer");
494 m_releaseCachedChannelTimer.stop();
497 case iDVBChannel::state_last_instance:
499 eDebug("start release channel timer");
500 m_releaseCachedChannelTimer.start(3000, true);
503 default: // ignore all other events
508 void eDVBResourceManager::releaseCachedChannel()
510 eDebug("release cached channel (timer timeout)");
514 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
516 ePtr<eDVBAllocatedFrontend> fe;
518 if (m_cached_channel)
520 m_cached_channel_state_changed_conn.disconnect();
522 m_releaseCachedChannelTimer.stop();
525 if (allocateFrontendByIndex(fe, slot_index))
526 return errNoFrontend;
529 ch = new eDVBChannel(this, fe);
536 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
538 ePtr<eDVBAllocatedDemux> demux;
540 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
542 m_cached_channel_state_changed_conn.disconnect();
544 m_releaseCachedChannelTimer.stop();
548 ch = new eDVBChannel(this, 0);
554 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
556 m_active_channels.push_back(active_channel(chid, ch));
557 /* emit */ m_channelAdded(ch);
561 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
564 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
566 if (i->m_channel == ch)
568 i = m_active_channels.erase(i);
579 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
581 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
585 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
587 ePtr<eDVBRegisteredFrontend> best;
590 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
593 int c = i->m_frontend->isCompatibleWith(feparm);
600 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
603 if (m_cached_channel)
605 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
606 if(channelid==cache_chan->getChannelID())
610 /* first, check if a channel is already existing. */
611 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
612 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
614 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
615 if (i->m_channel_id == channelid)
617 // eDebug("found shared channel..");
622 int *decremented_cached_channel_fe_usecount=NULL,
623 *decremented_fe_usecount=NULL;
625 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
627 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
628 if (i->m_channel_id == ignore)
630 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
631 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
632 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
633 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
634 // or 2 when the cached channel is not equal to the compared channel
635 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
637 ePtr<iDVBFrontend> fe;
638 if (!i->m_channel->getFrontend(fe))
640 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
642 if ( &(*fe) == &(*ii->m_frontend) )
645 decremented_fe_usecount = &ii->m_inuse;
646 if (channel == &(*m_cached_channel))
647 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
657 if (!decremented_cached_channel_fe_usecount)
659 if (m_cached_channel)
661 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
662 if (channel->getUseCount() == 1)
664 ePtr<iDVBFrontend> fe;
665 if (!channel->getFrontend(fe))
667 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
669 if ( &(*fe) == &(*ii->m_frontend) )
672 decremented_cached_channel_fe_usecount = &ii->m_inuse;
681 decremented_cached_channel_fe_usecount=NULL;
683 ePtr<iDVBFrontendParameters> feparm;
687 eDebug("no channel list set!");
692 if (m_list->getChannelFrontendData(channelid, feparm))
694 eDebug("channel not found!");
699 ret = canAllocateFrontend(feparm);
702 if (decremented_fe_usecount)
703 ++(*decremented_fe_usecount);
704 if (decremented_cached_channel_fe_usecount)
705 ++(*decremented_cached_channel_fe_usecount);
710 class eDVBChannelFilePush: public eFilePushThread
713 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
715 int m_iframe_search, m_iframe_state, m_pid;
716 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
719 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
722 if (!m_iframe_search)
725 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
727 eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
729 unsigned char *d = data;
730 while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
732 int offset = d - data;
733 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
734 unsigned char *ts = data + ts_offset;
735 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
737 if ((d[3] == 0) && (m_pid == pid)) /* picture start */
739 int picture_type = (d[5] >> 3) & 7;
742 eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
744 if (m_iframe_state == 1)
746 /* we are allowing data, and stop allowing data on the next frame.
747 we now found a frame. so stop here. */
748 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
749 current_span_remaining = 0;
751 unsigned char *fts = ts + 188;
752 while (fts < (data + len))
755 fts[2] |= 0xff; /* drop packet */
759 return len; // ts_offset + 188; /* deliver this packet, but not more. */
762 if (picture_type != 1) /* we are only interested in I frames */
765 unsigned char *fts = data;
769 fts[2] |= 0xff; /* drop packet */
773 /* force payload only */
777 // memset(ts + 4, 0xFF, (offset % 188) - 4);
781 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
785 eDebug("now locked to pid %04x", pid);
795 if (m_iframe_state == 1)
798 return 0; /* we need find an iframe first */
804 DEFINE_REF(eDVBChannel);
806 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
808 m_frontend = frontend;
812 m_skipmode_n = m_skipmode_m = 0;
815 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
818 eDVBChannel::~eDVBChannel()
821 m_mgr->removeChannel(this);
826 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
828 int state, ourstate = 0;
830 /* if we are already in shutdown, don't change state. */
831 if (m_state == state_release)
834 if (fe->getState(state))
837 if (state == iDVBFrontend::stateLock)
839 eDebug("OURSTATE: ok");
841 } else if (state == iDVBFrontend::stateTuning)
843 eDebug("OURSTATE: tuning");
844 ourstate = state_tuning;
845 } else if (state == iDVBFrontend::stateLostLock)
847 /* on managed channels, we try to retune in order to re-acquire lock. */
848 if (m_current_frontend_parameters)
850 eDebug("OURSTATE: lost lock, trying to retune");
851 ourstate = state_tuning;
852 m_frontend->get().tune(*m_current_frontend_parameters);
854 /* on unmanaged channels, we don't do this. the client will do this. */
856 eDebug("OURSTATE: lost lock, unavailable now.");
857 ourstate = state_unavailable;
859 } else if (state == iDVBFrontend::stateFailed)
861 eDebug("OURSTATE: failed");
862 ourstate = state_failed;
864 eFatal("state unknown");
866 if (ourstate != m_state)
869 m_stateChanged(this);
873 void eDVBChannel::pvrEvent(int event)
877 case eFilePushThread::evtEOF:
878 eDebug("eDVBChannel: End of file!");
879 m_event(this, evtEOF);
881 case eFilePushThread::evtUser: /* start */
883 m_event(this, evtSOF);
888 void eDVBChannel::cueSheetEvent(int event)
892 case eCueSheet::evtSeek:
894 flushPVR(m_cue->m_decoding_demux);
896 case eCueSheet::evtSkipmode:
899 m_cue->m_lock.WrLock();
900 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
901 m_cue->m_lock.Unlock();
902 eRdLocker l(m_cue->m_lock);
903 if (m_cue->m_skipmode_ratio)
905 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
906 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
907 /* i agree that this might look a bit like black magic. */
908 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
909 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
911 if (m_cue->m_skipmode_ratio < 0)
912 m_skipmode_m -= m_skipmode_n;
914 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
916 if (abs(m_skipmode_m) < abs(m_skipmode_n))
918 eWarning("something is wrong with this calculation");
919 m_skipmode_n = m_skipmode_m = 0;
924 eDebug("skipmode ratio is 0, normal play");
925 m_skipmode_n = m_skipmode_m = 0;
928 ASSERT(m_pvr_thread);
929 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
931 flushPVR(m_cue->m_decoding_demux);
935 case eCueSheet::evtSpanChanged:
937 m_source_span.clear();
938 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
940 off_t offset_in, offset_out;
941 pts_t pts_in = i->first, pts_out = i->second;
942 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
944 eDebug("span translation failed.\n");
947 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
948 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
955 /* align toward zero */
956 static inline long long align(long long x, int align)
971 /* remember, this gets called from another thread. */
972 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
974 const int blocksize = 188;
975 unsigned int max = align(10*1024*1024, blocksize);
976 current_offset = align(current_offset, blocksize);
980 eDebug("no cue sheet. forcing normal play");
981 start = current_offset;
986 m_cue->m_lock.RdLock();
987 if (!m_cue->m_decoding_demux)
989 start = current_offset;
991 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
992 m_cue->m_lock.Unlock();
998 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
999 max = align(m_skipmode_n, blocksize);
1002 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
1004 current_offset += align(m_skipmode_m, blocksize);
1006 while (!m_cue->m_seek_requests.empty())
1008 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1009 m_cue->m_lock.Unlock();
1010 m_cue->m_lock.WrLock();
1011 m_cue->m_seek_requests.pop_front();
1012 m_cue->m_lock.Unlock();
1013 m_cue->m_lock.RdLock();
1014 int relative = seek.first;
1015 pts_t pts = seek.second;
1020 if (!m_cue->m_decoder)
1022 eDebug("no decoder - can't seek relative");
1025 if (m_cue->m_decoder->getPTS(0, now))
1027 eDebug("decoder getPTS failed, can't seek relative");
1030 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1032 eDebug("seekTo: getCurrentPosition failed!");
1035 } else if (pts < 0) /* seek relative to end */
1038 if (!getLength(len))
1040 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1044 eWarning("getLength failed - can't seek relative to end!");
1049 if (relative == 1) /* pts relative */
1060 if (relative == 2) /* AP relative */
1062 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1064 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1066 pts = now - 90000; /* approx. 1s */
1067 eDebug("AP relative seeking failed!");
1070 eDebug("next ap is %llx\n", pts);
1076 if (m_tstools.getOffset(offset, pts))
1078 eDebug("get offset for pts=%lld failed!", pts);
1082 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1083 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1086 m_cue->m_lock.Unlock();
1088 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1090 long long aligned_start = align(i->first, blocksize);
1091 long long aligned_end = align(i->second, blocksize);
1093 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1095 start = current_offset;
1096 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1097 if ((aligned_end - current_offset) > max)
1100 size = aligned_end - current_offset;
1101 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1104 if (current_offset < aligned_start)
1106 /* ok, our current offset is in an 'out' zone. */
1107 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1109 /* in normal playback, just start at the next zone. */
1112 /* size is not 64bit! */
1113 if ((i->second - i->first) > max)
1116 size = aligned_end - aligned_start;
1119 if (m_skipmode_m < 0)
1121 eDebug("reached SOF");
1124 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1128 /* when skipping reverse, however, choose the zone before. */
1130 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1133 aligned_start = align(i->first, blocksize);
1134 aligned_end = align(i->second, blocksize);
1136 if ((aligned_end - aligned_start) > max)
1139 len = aligned_end - aligned_start;
1141 start = aligned_end - len;
1142 eDebug("skipping to %llx, %d", start, len);
1145 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1150 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1152 eDebug("reached SOF");
1154 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1157 start = current_offset;
1160 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
1164 void eDVBChannel::AddUse()
1166 if (++m_use_count > 1 && m_state == state_last_instance)
1169 m_stateChanged(this);
1173 void eDVBChannel::ReleaseUse()
1177 m_state = state_release;
1178 m_stateChanged(this);
1180 else if (m_use_count == 1)
1182 m_state = state_last_instance;
1183 m_stateChanged(this);
1187 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1190 m_mgr->removeChannel(this);
1197 eDebug("no frontend to tune!");
1201 m_channel_id = channelid;
1202 m_mgr->addChannel(channelid, this);
1203 m_state = state_tuning;
1204 /* if tuning fails, shutdown the channel immediately. */
1206 res = m_frontend->get().tune(*feparm);
1207 m_current_frontend_parameters = feparm;
1211 m_state = state_release;
1212 m_stateChanged(this);
1219 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1221 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1225 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1227 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1231 RESULT eDVBChannel::getState(int &state)
1237 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1242 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1244 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1250 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1255 /* don't hold a reference to the decoding demux, we don't need it. */
1257 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1258 the refcount is lost. thus, decoding demuxes are never allocated.
1260 this poses a big problem for PiP. */
1261 if (cap & capDecode)
1266 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1271 frontend = &m_frontend->get();
1277 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1279 param = m_current_frontend_parameters;
1283 RESULT eDVBChannel::playFile(const char *file)
1285 ASSERT(!m_frontend);
1288 m_pvr_thread->stop();
1289 delete m_pvr_thread;
1293 m_tstools.openFile(file);
1295 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1296 THEN DO A REAL FIX HERE! */
1298 /* (this codepath needs to be improved anyway.) */
1299 #if HAVE_DVB_API_VERSION < 3
1300 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1302 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1304 if (m_pvr_fd_dst < 0)
1306 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1310 m_pvr_thread = new eDVBChannelFilePush();
1311 m_pvr_thread->enablePVRCommit(1);
1312 m_pvr_thread->setStreamMode(1);
1313 m_pvr_thread->setScatterGather(this);
1315 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1317 delete m_pvr_thread;
1319 eDebug("can't open PVR file %s (%m)", file);
1322 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1325 m_stateChanged(this);
1330 void eDVBChannel::stopFile()
1334 m_pvr_thread->stop();
1335 ::close(m_pvr_fd_dst);
1336 delete m_pvr_thread;
1341 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1343 m_conn_cueSheetEvent = 0;
1346 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1349 RESULT eDVBChannel::getLength(pts_t &len)
1351 return m_tstools.calcLen(len);
1354 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1356 if (!decoding_demux)
1363 if (mode == 0) /* demux */
1365 r = decoding_demux->getSTC(now, 0);
1368 eDebug("demux getSTC failed");
1372 now = pos; /* fixup supplied */
1374 off_t off = 0; /* TODO: fixme */
1375 r = m_tstools.fixupPTS(off, now);
1378 eDebug("fixup PTS failed");
1387 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1389 /* when seeking, we have to ensure that all buffers are flushed.
1390 there are basically 3 buffers:
1391 a.) the filepush's internal buffer
1392 b.) the PVR buffer (before demux)
1393 c.) the ratebuffer (after demux)
1395 it's important to clear them in the correct order, otherwise
1396 the ratebuffer (for example) would immediately refill from
1397 the not-yet-flushed PVR buffer.
1400 m_pvr_thread->pause();
1401 /* flush internal filepush buffer */
1402 m_pvr_thread->flush();
1403 /* HACK: flush PVR buffer */
1404 ::ioctl(m_pvr_fd_dst, 0);
1406 /* flush ratebuffers (video, audio) */
1408 decoding_demux->flush();
1410 /* demux will also flush all decoder.. */
1411 /* resume will re-query the SG */
1412 m_pvr_thread->resume();
1415 DEFINE_REF(eCueSheet);
1417 eCueSheet::eCueSheet()
1419 m_skipmode_ratio = 0;
1422 void eCueSheet::seekTo(int relative, const pts_t &pts)
1425 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1430 void eCueSheet::clear()
1437 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1440 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1444 void eCueSheet::commitSpans()
1446 m_event(evtSpanChanged);
1449 void eCueSheet::setSkipmode(const pts_t &ratio)
1452 m_skipmode_ratio = ratio;
1454 m_event(evtSkipmode);
1457 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1459 m_decoding_demux = demux;
1460 m_decoder = decoder;
1463 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1465 connection = new eConnection(this, m_event.connect(event));