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 ((unsigned int)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 // check if another slot linked to this is in use
307 eDVBRegisteredFrontend *satpos_depends_to_fe =
308 (eDVBRegisteredFrontend*) i->m_frontend->m_data[eDVBFrontend::SATPOS_DEPENDS_PTR];
309 if ( (int)satpos_depends_to_fe != -1 )
311 if (satpos_depends_to_fe->m_inuse)
313 eDebug("another satpos depending frontend is in use.. so allocateFrontendByIndex not possible!");
314 goto alloc_fe_by_id_not_possible;
317 else // check linked tuners
319 eDVBRegisteredFrontend *next =
320 (eDVBRegisteredFrontend *) i->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR];
321 while ( (int)next != -1 )
325 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
326 goto alloc_fe_by_id_not_possible;
328 next = (eDVBRegisteredFrontend *)next->m_frontend->m_data[eDVBFrontend::LINKED_NEXT_PTR];
330 eDVBRegisteredFrontend *prev = (eDVBRegisteredFrontend *)
331 i->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR];
332 while ( (int)prev != -1 )
336 eDebug("another linked frontend is in use.. so allocateFrontendByIndex not possible!");
337 goto alloc_fe_by_id_not_possible;
339 prev = (eDVBRegisteredFrontend *)prev->m_frontend->m_data[eDVBFrontend::LINKED_PREV_PTR];
342 fe = new eDVBAllocatedFrontend(i);
345 alloc_fe_by_id_not_possible:
350 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
352 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
353 never use the first one unless we need a decoding demux. */
355 eDebug("allocate demux");
356 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
358 if (i == m_demux.end())
362 /* FIXME: hardware demux policy */
363 if (!(cap & iDVBChannel::capDecode))
365 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
372 for (; i != m_demux.end(); ++i, ++n)
374 int is_decode = n < 2;
376 int in_use = is_decode ? (i->m_demux->getRefCount() != 2) : i->m_inuse;
378 if ((!in_use) && ((!fe) || (i->m_adapter == fe->m_adapter)))
380 if ((cap & iDVBChannel::capDecode) && !is_decode)
383 demux = new eDVBAllocatedDemux(i);
385 demux->get().setSourceFrontend(fe->m_frontend->getDVBID());
387 demux->get().setSourcePVR(0);
391 eDebug("demux not found");
395 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
401 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
410 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
412 /* first, check if a channel is already existing. */
414 if (m_cached_channel)
416 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
417 if(channelid==cache_chan->getChannelID())
419 eDebug("use cached_channel");
420 channel = m_cached_channel;
423 m_cached_channel_state_changed_conn.disconnect();
425 m_releaseCachedChannelTimer.stop();
428 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
429 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
431 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
432 if (i->m_channel_id == channelid)
434 // eDebug("found shared channel..");
435 channel = i->m_channel;
440 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
444 eDebug("no channel list set!");
448 ePtr<iDVBFrontendParameters> feparm;
449 if (m_list->getChannelFrontendData(channelid, feparm))
451 eDebug("channel not found!");
455 /* allocate a frontend. */
457 ePtr<eDVBAllocatedFrontend> fe;
459 if (allocateFrontend(fe, feparm))
460 return errNoFrontend;
463 ePtr<eDVBChannel> ch;
464 ch = new eDVBChannel(this, fe);
466 res = ch->setChannel(channelid, feparm);
470 return errChidNotFound;
472 m_cached_channel = channel = ch;
473 m_cached_channel_state_changed_conn =
474 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
479 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
482 chan->getState(state);
485 case iDVBChannel::state_release:
486 case iDVBChannel::state_ok:
488 eDebug("stop release channel timer");
489 m_releaseCachedChannelTimer.stop();
492 case iDVBChannel::state_last_instance:
494 eDebug("start release channel timer");
495 m_releaseCachedChannelTimer.start(3000, true);
498 default: // ignore all other events
503 void eDVBResourceManager::releaseCachedChannel()
505 eDebug("release cached channel (timer timeout)");
509 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int slot_index)
511 ePtr<eDVBAllocatedFrontend> fe;
513 if (m_cached_channel)
515 m_cached_channel_state_changed_conn.disconnect();
517 m_releaseCachedChannelTimer.stop();
520 if (allocateFrontendByIndex(fe, slot_index))
521 return errNoFrontend;
524 ch = new eDVBChannel(this, fe);
531 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
533 ePtr<eDVBAllocatedDemux> demux;
535 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
537 m_cached_channel_state_changed_conn.disconnect();
539 m_releaseCachedChannelTimer.stop();
543 ch = new eDVBChannel(this, 0);
549 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
551 m_active_channels.push_back(active_channel(chid, ch));
552 /* emit */ m_channelAdded(ch);
556 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
559 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
561 if (i->m_channel == ch)
563 i = m_active_channels.erase(i);
574 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
576 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
580 int eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
582 ePtr<eDVBRegisteredFrontend> best;
585 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
588 int c = i->m_frontend->isCompatibleWith(feparm);
595 int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
598 if (m_cached_channel)
600 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
601 if(channelid==cache_chan->getChannelID())
605 /* first, check if a channel is already existing. */
606 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
607 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
609 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
610 if (i->m_channel_id == channelid)
612 // eDebug("found shared channel..");
617 int *decremented_cached_channel_fe_usecount=NULL,
618 *decremented_fe_usecount=NULL;
620 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
622 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
623 if (i->m_channel_id == ignore)
625 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
626 // one eUsePtr<iDVBChannel> is used in eDVBServicePMTHandler
627 // another on eUsePtr<iDVBChannel> is used in the eDVBScan instance used in eDVBServicePMTHandler (for SDT scan)
628 // so we must check here if usecount is 3 (when the channel is equal to the cached channel)
629 // or 2 when the cached channel is not equal to the compared channel
630 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 3 : channel->getUseCount() == 2) // channel only used once..
632 ePtr<iDVBFrontend> fe;
633 if (!i->m_channel->getFrontend(fe))
635 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
637 if ( &(*fe) == &(*ii->m_frontend) )
640 decremented_fe_usecount = &ii->m_inuse;
641 if (channel == &(*m_cached_channel))
642 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
652 if (!decremented_cached_channel_fe_usecount)
654 if (m_cached_channel)
656 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
657 if (channel->getUseCount() == 1)
659 ePtr<iDVBFrontend> fe;
660 if (!channel->getFrontend(fe))
662 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
664 if ( &(*fe) == &(*ii->m_frontend) )
667 decremented_cached_channel_fe_usecount = &ii->m_inuse;
676 decremented_cached_channel_fe_usecount=NULL;
678 ePtr<iDVBFrontendParameters> feparm;
682 eDebug("no channel list set!");
687 if (m_list->getChannelFrontendData(channelid, feparm))
689 eDebug("channel not found!");
694 ret = canAllocateFrontend(feparm);
697 if (decremented_fe_usecount)
698 ++(*decremented_fe_usecount);
699 if (decremented_cached_channel_fe_usecount)
700 ++(*decremented_cached_channel_fe_usecount);
705 class eDVBChannelFilePush: public eFilePushThread
708 void setIFrameSearch(int enabled) { m_iframe_search = enabled; m_iframe_state = 0; }
710 int m_iframe_search, m_iframe_state, m_pid;
711 int filterRecordData(const unsigned char *data, int len, size_t ¤t_span_remaining);
714 int eDVBChannelFilePush::filterRecordData(const unsigned char *_data, int len, size_t ¤t_span_remaining)
717 if (!m_iframe_search)
720 unsigned char *data = (unsigned char*)_data; /* remove that const. we know what we are doing. */
722 eDebug("filterRecordData, size=%d (mod 188=%d), first byte is %02x", len, len %188, data[0]);
724 unsigned char *d = data;
725 while ((d = (unsigned char*)memmem(d, data + len - d, "\x00\x00\x01", 3)))
727 int offset = d - data;
728 int ts_offset = offset - offset % 188; /* offset to the start of TS packet */
729 unsigned char *ts = data + ts_offset;
730 int pid = ((ts[1] << 8) | ts[2]) & 0x1FFF;
732 if ((d[3] == 0) && (m_pid == pid)) /* picture start */
734 int picture_type = (d[5] >> 3) & 7;
737 eDebug("%d-frame at %d, offset in TS packet: %d, pid=%04x", picture_type, offset, offset % 188, pid);
739 if (m_iframe_state == 1)
741 /* we are allowing data, and stop allowing data on the next frame.
742 we now found a frame. so stop here. */
743 memset(data + offset, 0, 188 - (offset%188)); /* zero out rest of TS packet */
744 current_span_remaining = 0;
746 unsigned char *fts = ts + 188;
747 while (fts < (data + len))
750 fts[2] |= 0xff; /* drop packet */
754 return len; // ts_offset + 188; /* deliver this packet, but not more. */
757 if (picture_type != 1) /* we are only interested in I frames */
760 unsigned char *fts = data;
764 fts[2] |= 0xff; /* drop packet */
768 /* force payload only */
772 // memset(ts + 4, 0xFF, (offset % 188) - 4);
776 } else if ((d[3] & 0xF0) == 0xE0) /* video stream */
780 eDebug("now locked to pid %04x", pid);
790 if (m_iframe_state == 1)
793 return 0; /* we need find an iframe first */
799 DEFINE_REF(eDVBChannel);
801 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
803 m_frontend = frontend;
807 m_skipmode_n = m_skipmode_m = 0;
810 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
813 eDVBChannel::~eDVBChannel()
816 m_mgr->removeChannel(this);
821 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
823 int state, ourstate = 0;
825 /* if we are already in shutdown, don't change state. */
826 if (m_state == state_release)
829 if (fe->getState(state))
832 if (state == iDVBFrontend::stateLock)
834 eDebug("OURSTATE: ok");
836 } else if (state == iDVBFrontend::stateTuning)
838 eDebug("OURSTATE: tuning");
839 ourstate = state_tuning;
840 } else if (state == iDVBFrontend::stateLostLock)
842 /* on managed channels, we try to retune in order to re-acquire lock. */
843 if (m_current_frontend_parameters)
845 eDebug("OURSTATE: lost lock, trying to retune");
846 ourstate = state_tuning;
847 m_frontend->get().tune(*m_current_frontend_parameters);
849 /* on unmanaged channels, we don't do this. the client will do this. */
851 eDebug("OURSTATE: lost lock, unavailable now.");
852 ourstate = state_unavailable;
854 } else if (state == iDVBFrontend::stateFailed)
856 eDebug("OURSTATE: failed");
857 ourstate = state_failed;
859 eFatal("state unknown");
861 if (ourstate != m_state)
864 m_stateChanged(this);
868 void eDVBChannel::pvrEvent(int event)
872 case eFilePushThread::evtEOF:
873 eDebug("eDVBChannel: End of file!");
874 m_event(this, evtEOF);
876 case eFilePushThread::evtUser: /* start */
878 m_event(this, evtSOF);
883 void eDVBChannel::cueSheetEvent(int event)
887 case eCueSheet::evtSeek:
889 flushPVR(m_cue->m_decoding_demux);
891 case eCueSheet::evtSkipmode:
894 m_cue->m_lock.WrLock();
895 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
896 m_cue->m_lock.Unlock();
897 eRdLocker l(m_cue->m_lock);
898 if (m_cue->m_skipmode_ratio)
900 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
901 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
902 /* i agree that this might look a bit like black magic. */
903 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
904 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
906 if (m_cue->m_skipmode_ratio < 0)
907 m_skipmode_m -= m_skipmode_n;
909 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
911 if (abs(m_skipmode_m) < abs(m_skipmode_n))
913 eWarning("something is wrong with this calculation");
914 m_skipmode_n = m_skipmode_m = 0;
919 eDebug("skipmode ratio is 0, normal play");
920 m_skipmode_n = m_skipmode_m = 0;
923 m_pvr_thread->setIFrameSearch(m_skipmode_n != 0);
925 flushPVR(m_cue->m_decoding_demux);
929 case eCueSheet::evtSpanChanged:
931 m_source_span.clear();
932 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
934 off_t offset_in, offset_out;
935 pts_t pts_in = i->first, pts_out = i->second;
936 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
938 eDebug("span translation failed.\n");
941 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
942 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
949 /* align toward zero */
950 static inline long long align(long long x, int align)
965 /* remember, this gets called from another thread. */
966 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
968 const int blocksize = 188;
969 unsigned int max = align(10*1024*1024, blocksize);
970 current_offset = align(current_offset, blocksize);
974 eDebug("no cue sheet. forcing normal play");
975 start = current_offset;
980 m_cue->m_lock.RdLock();
981 if (!m_cue->m_decoding_demux)
983 start = current_offset;
985 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
986 m_cue->m_lock.Unlock();
992 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
993 max = align(m_skipmode_n, blocksize);
996 eDebug("getNextSourceSpan, current offset is %08llx, m_skipmode_m = %d!", current_offset, m_skipmode_m);
998 current_offset += align(m_skipmode_m, blocksize);
1000 while (!m_cue->m_seek_requests.empty())
1002 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
1003 m_cue->m_lock.Unlock();
1004 m_cue->m_lock.WrLock();
1005 m_cue->m_seek_requests.pop_front();
1006 m_cue->m_lock.Unlock();
1007 m_cue->m_lock.RdLock();
1008 int relative = seek.first;
1009 pts_t pts = seek.second;
1014 if (!m_cue->m_decoder)
1016 eDebug("no decoder - can't seek relative");
1019 if (m_cue->m_decoder->getPTS(0, now))
1021 eDebug("decoder getPTS failed, can't seek relative");
1024 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
1026 eDebug("seekTo: getCurrentPosition failed!");
1029 } else if (pts < 0) /* seek relative to end */
1032 if (!getLength(len))
1034 eDebug("seeking relative to end. len=%lld, seek = %lld", len, pts);
1038 eWarning("getLength failed - can't seek relative to end!");
1043 if (relative == 1) /* pts relative */
1054 if (relative == 2) /* AP relative */
1056 eDebug("AP relative seeking: %lld, at %lld", pts, now);
1058 if (m_tstools.getNextAccessPoint(nextap, now, pts))
1061 eDebug("AP relative seeking failed!");
1064 eDebug("next ap is %llx\n", pts);
1070 if (m_tstools.getOffset(offset, pts))
1072 eDebug("get offset for pts=%lld failed!", pts);
1076 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
1077 current_offset = align(offset, blocksize); /* in case tstools return non-aligned offset */
1080 m_cue->m_lock.Unlock();
1082 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
1084 long long aligned_start = align(i->first, blocksize);
1085 long long aligned_end = align(i->second, blocksize);
1087 if ((current_offset >= aligned_start) && (current_offset < aligned_end))
1089 start = current_offset;
1090 /* max can not exceed max(size_t). aligned_end - current_offset, however, can. */
1091 if ((aligned_end - current_offset) > max)
1094 size = aligned_end - current_offset;
1095 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
1098 if (current_offset < aligned_start)
1100 /* ok, our current offset is in an 'out' zone. */
1101 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
1103 /* in normal playback, just start at the next zone. */
1106 /* size is not 64bit! */
1107 if ((i->second - i->first) > max)
1110 size = aligned_end - aligned_start;
1113 if (m_skipmode_m < 0)
1115 eDebug("reached SOF");
1118 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1122 /* when skipping reverse, however, choose the zone before. */
1124 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
1127 if ((i->second - i->first) > max)
1130 len = aligned_end - aligned_start;
1132 start = aligned_end - len;
1133 eDebug("skipping to %llx, %d", start, len);
1136 eDebug("result: %llx, %x (%llx %llx)", start, size, aligned_start, aligned_end);
1141 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
1143 eDebug("reached SOF");
1145 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
1148 start = current_offset;
1151 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
1155 void eDVBChannel::AddUse()
1157 if (++m_use_count > 1 && m_state == state_last_instance)
1160 m_stateChanged(this);
1164 void eDVBChannel::ReleaseUse()
1168 m_state = state_release;
1169 m_stateChanged(this);
1171 else if (m_use_count == 1)
1173 m_state = state_last_instance;
1174 m_stateChanged(this);
1178 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
1181 m_mgr->removeChannel(this);
1188 eDebug("no frontend to tune!");
1192 m_channel_id = channelid;
1193 m_mgr->addChannel(channelid, this);
1194 m_state = state_tuning;
1195 /* if tuning fails, shutdown the channel immediately. */
1197 res = m_frontend->get().tune(*feparm);
1198 m_current_frontend_parameters = feparm;
1202 m_state = state_release;
1203 m_stateChanged(this);
1210 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
1212 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
1216 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
1218 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
1222 RESULT eDVBChannel::getState(int &state)
1228 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
1233 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
1235 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1241 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1246 /* don't hold a reference to the decoding demux, we don't need it. */
1248 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1249 the refcount is lost. thus, decoding demuxes are never allocated.
1251 this poses a big problem for PiP. */
1252 if (cap & capDecode)
1257 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1262 frontend = &m_frontend->get();
1268 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1270 param = m_current_frontend_parameters;
1274 RESULT eDVBChannel::playFile(const char *file)
1276 ASSERT(!m_frontend);
1279 m_pvr_thread->stop();
1280 delete m_pvr_thread;
1284 m_tstools.openFile(file);
1286 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1287 THEN DO A REAL FIX HERE! */
1289 /* (this codepath needs to be improved anyway.) */
1290 #if HAVE_DVB_API_VERSION < 3
1291 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1293 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1295 if (m_pvr_fd_dst < 0)
1297 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1301 m_pvr_thread = new eDVBChannelFilePush();
1302 m_pvr_thread->enablePVRCommit(1);
1303 m_pvr_thread->setStreamMode(1);
1304 m_pvr_thread->setScatterGather(this);
1306 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1308 delete m_pvr_thread;
1310 eDebug("can't open PVR file %s (%m)", file);
1313 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1316 m_stateChanged(this);
1321 void eDVBChannel::stopFile()
1325 m_pvr_thread->stop();
1326 ::close(m_pvr_fd_dst);
1327 delete m_pvr_thread;
1332 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1334 m_conn_cueSheetEvent = 0;
1337 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1340 RESULT eDVBChannel::getLength(pts_t &len)
1342 return m_tstools.calcLen(len);
1345 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1347 if (!decoding_demux)
1354 if (mode == 0) /* demux */
1356 r = decoding_demux->getSTC(now, 0);
1359 eDebug("demux getSTC failed");
1363 now = pos; /* fixup supplied */
1365 off_t off = 0; /* TODO: fixme */
1366 r = m_tstools.fixupPTS(off, now);
1369 eDebug("fixup PTS failed");
1378 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1380 /* when seeking, we have to ensure that all buffers are flushed.
1381 there are basically 3 buffers:
1382 a.) the filepush's internal buffer
1383 b.) the PVR buffer (before demux)
1384 c.) the ratebuffer (after demux)
1386 it's important to clear them in the correct order, otherwise
1387 the ratebuffer (for example) would immediately refill from
1388 the not-yet-flushed PVR buffer.
1391 m_pvr_thread->pause();
1392 /* flush internal filepush buffer */
1393 m_pvr_thread->flush();
1394 /* HACK: flush PVR buffer */
1395 ::ioctl(m_pvr_fd_dst, 0);
1397 /* flush ratebuffers (video, audio) */
1399 decoding_demux->flush();
1401 /* demux will also flush all decoder.. */
1402 /* resume will re-query the SG */
1403 m_pvr_thread->resume();
1406 DEFINE_REF(eCueSheet);
1408 eCueSheet::eCueSheet()
1410 m_skipmode_ratio = 0;
1413 void eCueSheet::seekTo(int relative, const pts_t &pts)
1416 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1421 void eCueSheet::clear()
1428 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1431 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1435 void eCueSheet::commitSpans()
1437 m_event(evtSpanChanged);
1440 void eCueSheet::setSkipmode(const pts_t &ratio)
1443 m_skipmode_ratio = ratio;
1445 m_event(evtSkipmode);
1448 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1450 m_decoding_demux = demux;
1451 m_decoder = decoder;
1454 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1456 connection = new eConnection(this, m_event.connect(event));