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 eDVBResourceManager::eDVBResourceManager()
56 :m_releaseCachedChannelTimer(eApp)
60 m_sec = new eDVBSatelliteEquipmentControl(m_frontend);
64 /* search available adapters... */
69 while (eDVBAdapterLinux::exist(num_adapter))
71 addAdapter(new eDVBAdapterLinux(num_adapter));
75 eDebug("found %d adapter, %d frontends and %d demux",
76 m_adapter.size(), m_frontend.size(), m_demux.size());
78 CONNECT(m_releaseCachedChannelTimer.timeout, eDVBResourceManager::releaseCachedChannel);
82 DEFINE_REF(eDVBAdapterLinux);
83 eDVBAdapterLinux::eDVBAdapterLinux(int nr): m_nr(nr)
88 eDebug("scanning for frontends..");
93 #if HAVE_DVB_API_VERSION < 3
94 sprintf(filename, "/dev/dvb/card%d/frontend%d", m_nr, num_fe);
96 sprintf(filename, "/dev/dvb/adapter%d/frontend%d", m_nr, num_fe);
98 if (stat(filename, &s))
100 ePtr<eDVBFrontend> fe;
103 fe = new eDVBFrontend(m_nr, num_fe, ok);
105 m_frontend.push_back(fe);
115 #if HAVE_DVB_API_VERSION < 3
116 sprintf(filename, "/dev/dvb/card%d/demux%d", m_nr, num_demux);
118 sprintf(filename, "/dev/dvb/adapter%d/demux%d", m_nr, num_demux);
120 if (stat(filename, &s))
122 ePtr<eDVBDemux> demux;
124 demux = new eDVBDemux(m_nr, num_demux);
125 m_demux.push_back(demux);
131 int eDVBAdapterLinux::getNumDemux()
133 return m_demux.size();
136 RESULT eDVBAdapterLinux::getDemux(ePtr<eDVBDemux> &demux, int nr)
138 eSmartPtrList<eDVBDemux>::iterator i(m_demux.begin());
139 while (nr && (i != m_demux.end()))
145 if (i != m_demux.end())
153 int eDVBAdapterLinux::getNumFrontends()
155 return m_frontend.size();
158 RESULT eDVBAdapterLinux::getFrontend(ePtr<eDVBFrontend> &fe, int nr)
160 eSmartPtrList<eDVBFrontend>::iterator i(m_frontend.begin());
161 while (nr && (i != m_frontend.end()))
167 if (i != m_frontend.end())
175 int eDVBAdapterLinux::exist(int nr)
179 #if HAVE_DVB_API_VERSION < 3
180 sprintf(filename, "/dev/dvb/card%d", nr);
182 sprintf(filename, "/dev/dvb/adapter%d", nr);
184 if (!stat(filename, &s))
189 eDVBResourceManager::~eDVBResourceManager()
191 if (instance == this)
195 void eDVBResourceManager::addAdapter(iDVBAdapter *adapter)
197 int num_fe = adapter->getNumFrontends();
198 int num_demux = adapter->getNumDemux();
200 m_adapter.push_back(adapter);
203 for (i=0; i<num_demux; ++i)
205 ePtr<eDVBDemux> demux;
206 if (!adapter->getDemux(demux, i))
207 m_demux.push_back(new eDVBRegisteredDemux(demux, adapter));
210 for (i=0; i<num_fe; ++i)
212 ePtr<eDVBFrontend> frontend;
214 if (!adapter->getFrontend(frontend, i))
216 frontend->setSEC(m_sec);
217 m_frontend.push_back(new eDVBRegisteredFrontend(frontend, adapter));
222 RESULT eDVBResourceManager::allocateFrontend(ePtr<eDVBAllocatedFrontend> &fe, ePtr<iDVBFrontendParameters> &feparm)
224 ePtr<eDVBRegisteredFrontend> best;
227 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
230 int c = i->m_frontend->isCompatibleWith(feparm);
240 fe = new eDVBAllocatedFrontend(best);
249 RESULT eDVBResourceManager::allocateFrontendByIndex(ePtr<eDVBAllocatedFrontend> &fe, int nr)
251 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i, --nr)
252 if ((!nr) && !i->m_inuse)
254 fe = new eDVBAllocatedFrontend(i);
262 RESULT eDVBResourceManager::allocateDemux(eDVBRegisteredFrontend *fe, ePtr<eDVBAllocatedDemux> &demux, int cap)
264 /* find first unused demux which is on same adapter as frontend (or any, if PVR)
265 never use the first one unless we need a decoding demux. */
267 eDebug("allocate demux");
268 eSmartPtrList<eDVBRegisteredDemux>::iterator i(m_demux.begin());
270 if (i == m_demux.end())
274 /* FIXME: hardware demux policy */
275 if (!(cap & iDVBChannel::capDecode))
277 if (m_demux.size() > 2) /* assumed to be true, otherwise we have lost anyway */
284 for (; i != m_demux.end(); ++i, ++n)
285 if ((!i->m_inuse) && ((!fe) || (i->m_adapter == fe->m_adapter)))
287 if ((cap & iDVBChannel::capDecode) && (n >= 2))
290 demux = new eDVBAllocatedDemux(i);
292 demux->get().setSourceFrontend(fe->m_frontend->getID());
294 demux->get().setSourcePVR(0);
297 eDebug("demux not found");
301 RESULT eDVBResourceManager::setChannelList(iDVBChannelList *list)
307 RESULT eDVBResourceManager::getChannelList(ePtr<iDVBChannelList> &list)
316 RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr<iDVBChannel> &channel)
318 /* first, check if a channel is already existing. */
320 if (m_cached_channel)
322 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
323 if(channelid==cache_chan->getChannelID())
325 eDebug("use cached_channel");
326 channel = m_cached_channel;
329 m_cached_channel_state_changed_conn.disconnect();
331 m_releaseCachedChannelTimer.stop();
334 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
335 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
337 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
338 if (i->m_channel_id == channelid)
340 // eDebug("found shared channel..");
341 channel = i->m_channel;
346 /* no currently available channel is tuned to this channelid. create a new one, if possible. */
350 eDebug("no channel list set!");
354 ePtr<iDVBFrontendParameters> feparm;
355 if (m_list->getChannelFrontendData(channelid, feparm))
357 eDebug("channel not found!");
361 /* allocate a frontend. */
363 ePtr<eDVBAllocatedFrontend> fe;
365 if (allocateFrontend(fe, feparm))
366 return errNoFrontend;
369 ePtr<eDVBChannel> ch;
370 ch = new eDVBChannel(this, fe);
372 res = ch->setChannel(channelid, feparm);
376 return errChidNotFound;
378 m_cached_channel = channel = ch;
379 m_cached_channel_state_changed_conn =
380 CONNECT(ch->m_stateChanged,eDVBResourceManager::DVBChannelStateChanged);
385 void eDVBResourceManager::DVBChannelStateChanged(iDVBChannel *chan)
388 chan->getState(state);
391 case iDVBChannel::state_release:
392 case iDVBChannel::state_ok:
394 eDebug("stop release channel timer");
395 m_releaseCachedChannelTimer.stop();
398 case iDVBChannel::state_last_instance:
400 eDebug("start release channel timer");
401 m_releaseCachedChannelTimer.start(3000, true);
404 default: // ignore all other events
409 void eDVBResourceManager::releaseCachedChannel()
411 eDebug("release cached channel (timer timeout)");
415 RESULT eDVBResourceManager::allocateRawChannel(eUsePtr<iDVBChannel> &channel, int frontend_index)
417 ePtr<eDVBAllocatedFrontend> fe;
419 if (m_cached_channel)
421 m_cached_channel_state_changed_conn.disconnect();
423 m_releaseCachedChannelTimer.stop();
426 if (allocateFrontendByIndex(fe, frontend_index))
427 return errNoFrontend;
430 ch = new eDVBChannel(this, fe);
437 RESULT eDVBResourceManager::allocatePVRChannel(eUsePtr<iDVBPVRChannel> &channel)
439 ePtr<eDVBAllocatedDemux> demux;
441 if (m_cached_channel && m_releaseCachedChannelTimer.isActive())
443 m_cached_channel_state_changed_conn.disconnect();
445 m_releaseCachedChannelTimer.stop();
449 ch = new eDVBChannel(this, 0);
455 RESULT eDVBResourceManager::addChannel(const eDVBChannelID &chid, eDVBChannel *ch)
457 m_active_channels.push_back(active_channel(chid, ch));
458 /* emit */ m_channelAdded(ch);
462 RESULT eDVBResourceManager::removeChannel(eDVBChannel *ch)
465 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end();)
467 if (i->m_channel == ch)
469 i = m_active_channels.erase(i);
480 RESULT eDVBResourceManager::connectChannelAdded(const Slot1<void,eDVBChannel*> &channelAdded, ePtr<eConnection> &connection)
482 connection = new eConnection((eDVBResourceManager*)this, m_channelAdded.connect(channelAdded));
486 bool eDVBResourceManager::canAllocateFrontend(ePtr<iDVBFrontendParameters> &feparm)
488 ePtr<eDVBRegisteredFrontend> best;
491 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
494 int c = i->m_frontend->isCompatibleWith(feparm);
502 bool eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore)
505 if (m_cached_channel)
507 eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel);
508 if(channelid==cache_chan->getChannelID())
512 /* first, check if a channel is already existing. */
513 // eDebug("allocate channel.. %04x:%04x", channelid.transport_stream_id.get(), channelid.original_network_id.get());
514 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
516 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
517 if (i->m_channel_id == channelid)
519 // eDebug("found shared channel..");
524 int *decremented_cached_channel_fe_usecount=NULL,
525 *decremented_fe_usecount=NULL;
527 for (std::list<active_channel>::iterator i(m_active_channels.begin()); i != m_active_channels.end(); ++i)
529 // eDebug("available channel.. %04x:%04x", i->m_channel_id.transport_stream_id.get(), i->m_channel_id.original_network_id.get());
530 if (i->m_channel_id == ignore)
532 eDVBChannel *channel = (eDVBChannel*) &(*i->m_channel);
533 if (channel == &(*m_cached_channel) ? channel->getUseCount() == 2 : channel->getUseCount() == 1) // channel only used once..
535 ePtr<iDVBFrontend> fe;
536 if (!i->m_channel->getFrontend(fe))
538 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
540 if ( &(*fe) == &(*ii->m_frontend) )
543 decremented_fe_usecount = &ii->m_inuse;
544 if (channel == &(*m_cached_channel))
545 decremented_cached_channel_fe_usecount = decremented_fe_usecount;
555 if (!decremented_cached_channel_fe_usecount)
557 if (m_cached_channel)
559 eDVBChannel *channel = (eDVBChannel*) &(*m_cached_channel);
560 if (channel->getUseCount() == 1)
562 ePtr<iDVBFrontend> fe;
563 if (!channel->getFrontend(fe))
565 for (eSmartPtrList<eDVBRegisteredFrontend>::iterator ii(m_frontend.begin()); ii != m_frontend.end(); ++ii)
567 if ( &(*fe) == &(*ii->m_frontend) )
570 decremented_cached_channel_fe_usecount = &ii->m_inuse;
579 decremented_cached_channel_fe_usecount=NULL;
581 ePtr<iDVBFrontendParameters> feparm;
585 eDebug("no channel list set!");
590 if (m_list->getChannelFrontendData(channelid, feparm))
592 eDebug("channel not found!");
597 ret = canAllocateFrontend(feparm);
600 if (decremented_fe_usecount)
601 ++(*decremented_fe_usecount);
602 if (decremented_cached_channel_fe_usecount)
603 ++(*decremented_cached_channel_fe_usecount);
608 DEFINE_REF(eDVBChannel);
610 eDVBChannel::eDVBChannel(eDVBResourceManager *mgr, eDVBAllocatedFrontend *frontend): m_state(state_idle), m_mgr(mgr)
612 m_frontend = frontend;
616 m_skipmode_n = m_skipmode_m = 0;
619 m_frontend->get().connectStateChange(slot(*this, &eDVBChannel::frontendStateChanged), m_conn_frontendStateChanged);
622 eDVBChannel::~eDVBChannel()
625 m_mgr->removeChannel(this);
630 void eDVBChannel::frontendStateChanged(iDVBFrontend*fe)
632 int state, ourstate = 0;
634 /* if we are already in shutdown, don't change state. */
635 if (m_state == state_release)
638 if (fe->getState(state))
641 if (state == iDVBFrontend::stateLock)
643 eDebug("OURSTATE: ok");
645 } else if (state == iDVBFrontend::stateTuning)
647 eDebug("OURSTATE: tuning");
648 ourstate = state_tuning;
649 } else if (state == iDVBFrontend::stateLostLock)
651 /* on managed channels, we try to retune in order to re-acquire lock. */
652 if (m_current_frontend_parameters)
654 eDebug("OURSTATE: lost lock, trying to retune");
655 ourstate = state_tuning;
656 m_frontend->get().tune(*m_current_frontend_parameters);
658 /* on unmanaged channels, we don't do this. the client will do this. */
660 eDebug("OURSTATE: lost lock, unavailable now.");
661 ourstate = state_unavailable;
663 } else if (state == iDVBFrontend::stateFailed)
665 eDebug("OURSTATE: failed");
666 ourstate = state_failed;
668 eFatal("state unknown");
670 if (ourstate != m_state)
673 m_stateChanged(this);
677 void eDVBChannel::pvrEvent(int event)
681 case eFilePushThread::evtEOF:
682 eDebug("eDVBChannel: End of file!");
683 m_event(this, evtEOF);
685 case eFilePushThread::evtUser: /* start */
687 m_event(this, evtSOF);
692 void eDVBChannel::cueSheetEvent(int event)
696 case eCueSheet::evtSeek:
698 flushPVR(m_cue->m_decoding_demux);
700 case eCueSheet::evtSkipmode:
703 eSingleLocker l(m_cue->m_lock);
704 m_cue->m_seek_requests.push_back(std::pair<int, pts_t>(1, 0)); /* resync */
705 if (m_cue->m_skipmode_ratio)
707 int bitrate = m_tstools.calcBitrate(); /* in bits/s */
708 eDebug("skipmode ratio is %lld:90000, bitrate is %d bit/s", m_cue->m_skipmode_ratio, bitrate);
709 /* i agree that this might look a bit like black magic. */
710 m_skipmode_n = 512*1024; /* must be 1 iframe at least. */
711 m_skipmode_m = bitrate / 8 / 90000 * m_cue->m_skipmode_ratio / 8;
713 if (m_cue->m_skipmode_ratio < 0)
714 m_skipmode_m -= m_skipmode_n;
716 eDebug("resolved to: %d %d", m_skipmode_m, m_skipmode_n);
718 if (abs(m_skipmode_m) < abs(m_skipmode_n))
720 eWarning("something is wrong with this calculation");
721 m_skipmode_n = m_skipmode_m = 0;
726 eDebug("skipmode ratio is 0, normal play");
727 m_skipmode_n = m_skipmode_m = 0;
730 flushPVR(m_cue->m_decoding_demux);
733 case eCueSheet::evtSpanChanged:
735 m_source_span.clear();
736 for (std::list<std::pair<pts_t, pts_t> >::const_iterator i(m_cue->m_spans.begin()); i != m_cue->m_spans.end(); ++i)
738 off_t offset_in, offset_out;
739 pts_t pts_in = i->first, pts_out = i->second;
740 if (m_tstools.getOffset(offset_in, pts_in) || m_tstools.getOffset(offset_out, pts_out))
742 eDebug("span translation failed.\n");
745 eDebug("source span: %llx .. %llx, translated to %llx..%llx", pts_in, pts_out, offset_in, offset_out);
746 m_source_span.push_back(std::pair<off_t, off_t>(offset_in, offset_out));
753 /* remember, this gets called from another thread. */
754 void eDVBChannel::getNextSourceSpan(off_t current_offset, size_t bytes_read, off_t &start, size_t &size)
756 unsigned int max = 10*1024*1024;
760 eDebug("no cue sheet. forcing normal play");
761 start = current_offset;
766 eSingleLocker l(m_cue->m_lock);
768 if (!m_cue->m_decoding_demux)
770 start = current_offset;
772 eDebug("getNextSourceSpan, no decoding demux. forcing normal play");
778 eDebug("skipmode %d:%d", m_skipmode_m, m_skipmode_n);
782 eDebug("getNextSourceSpan, current offset is %08llx!", current_offset);
784 current_offset += m_skipmode_m;
786 while (!m_cue->m_seek_requests.empty())
788 std::pair<int, pts_t> seek = m_cue->m_seek_requests.front();
789 m_cue->m_seek_requests.pop_front();
790 int relative = seek.first;
791 pts_t pts = seek.second;
796 if (!m_cue->m_decoder)
798 eDebug("no decoder - can't seek relative");
801 if (m_cue->m_decoder->getPTS(0, now))
803 eDebug("decoder getPTS failed, can't seek relative");
806 if (getCurrentPosition(m_cue->m_decoding_demux, now, 1))
808 eDebug("seekTo: getCurrentPosition failed!");
813 if (relative == 1) /* pts relative */
824 if (relative == 2) /* AP relative */
826 eDebug("AP relative seeking: %lld, at %lld", pts, now);
828 if (m_tstools.getNextAccessPoint(nextap, now, pts))
831 eDebug("AP relative seeking failed!");
834 eDebug("next ap is %llx\n", pts);
840 if (m_tstools.getOffset(offset, pts))
843 eDebug("ok, resolved skip (rel: %d, diff %lld), now at %08llx", relative, pts, offset);
844 current_offset = offset;
847 for (std::list<std::pair<off_t, off_t> >::const_iterator i(m_source_span.begin()); i != m_source_span.end(); ++i)
849 if ((current_offset >= i->first) && (current_offset < i->second))
851 start = current_offset;
852 /* max can not exceed max(size_t). i->second - current_offset, however, can. */
853 if ((i->second - current_offset) > max)
856 size = i->second - current_offset;
857 eDebug("HIT, %lld < %lld < %lld, size: %d", i->first, current_offset, i->second, size);
860 if (current_offset < i->first)
862 /* ok, our current offset is in an 'out' zone. */
863 if ((m_skipmode_m >= 0) || (i == m_source_span.begin()))
865 /* in normal playback, just start at the next zone. */
868 /* size is not 64bit! */
869 if ((i->second - i->first) > max)
872 size = i->second - i->first;
875 if (m_skipmode_m < 0)
877 eDebug("reached SOF");
880 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
884 /* when skipping reverse, however, choose the zone before. */
886 eDebug("skip to previous block, which is %llx..%llx", i->first, i->second);
889 if ((i->second - i->first) > max)
892 len = i->second - i->first;
894 start = i->second - len;
895 eDebug("skipping to %llx, %d", start, len);
901 if ((current_offset < -m_skipmode_m) && (m_skipmode_m < 0))
903 eDebug("reached SOF");
905 m_pvr_thread->sendEvent(eFilePushThread::evtUser);
908 start = current_offset;
910 eDebug("END OF CUESHEET. (%08llx, %d)", start, size);
914 void eDVBChannel::AddUse()
916 if (++m_use_count > 1 && m_state == state_last_instance)
919 m_stateChanged(this);
923 void eDVBChannel::ReleaseUse()
927 m_state = state_release;
928 m_stateChanged(this);
930 else if (m_use_count == 1)
932 m_state = state_last_instance;
933 m_stateChanged(this);
937 RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtr<iDVBFrontendParameters> &feparm)
940 m_mgr->removeChannel(this);
947 eDebug("no frontend to tune!");
951 m_channel_id = channelid;
952 m_mgr->addChannel(channelid, this);
953 m_state = state_tuning;
954 /* if tuning fails, shutdown the channel immediately. */
956 res = m_frontend->get().tune(*feparm);
957 m_current_frontend_parameters = feparm;
961 m_state = state_release;
962 m_stateChanged(this);
969 RESULT eDVBChannel::connectStateChange(const Slot1<void,iDVBChannel*> &stateChange, ePtr<eConnection> &connection)
971 connection = new eConnection((iDVBChannel*)this, m_stateChanged.connect(stateChange));
975 RESULT eDVBChannel::connectEvent(const Slot2<void,iDVBChannel*,int> &event, ePtr<eConnection> &connection)
977 connection = new eConnection((iDVBChannel*)this, m_event.connect(event));
981 RESULT eDVBChannel::getState(int &state)
987 RESULT eDVBChannel::setCIRouting(const eDVBCIRouting &routing)
992 RESULT eDVBChannel::getDemux(ePtr<iDVBDemux> &demux, int cap)
994 ePtr<eDVBAllocatedDemux> &our_demux = (cap & capDecode) ? m_decoder_demux : m_demux;
1000 if (m_mgr->allocateDemux(m_frontend ? (eDVBRegisteredFrontend*)*m_frontend : (eDVBRegisteredFrontend*)0, our_demux, cap))
1005 /* don't hold a reference to the decoding demux, we don't need it. */
1007 /* FIXME: by dropping the 'allocated demux' in favour of the 'iDVBDemux',
1008 the refcount is lost. thus, decoding demuxes are never allocated.
1010 this poses a big problem for PiP. */
1011 if (cap & capDecode)
1016 RESULT eDVBChannel::getFrontend(ePtr<iDVBFrontend> &frontend)
1021 frontend = &m_frontend->get();
1027 RESULT eDVBChannel::getCurrentFrontendParameters(ePtr<iDVBFrontendParameters> ¶m)
1029 param = m_current_frontend_parameters;
1033 RESULT eDVBChannel::playFile(const char *file)
1035 ASSERT(!m_frontend);
1038 m_pvr_thread->stop();
1039 delete m_pvr_thread;
1043 m_tstools.openFile(file);
1045 /* DON'T EVEN THINK ABOUT FIXING THIS. FIX THE ATI SOURCES FIRST,
1046 THEN DO A REAL FIX HERE! */
1048 /* (this codepath needs to be improved anyway.) */
1049 #if HAVE_DVB_API_VERSION < 3
1050 m_pvr_fd_dst = open("/dev/pvr", O_WRONLY);
1052 m_pvr_fd_dst = open("/dev/misc/pvr", O_WRONLY);
1054 if (m_pvr_fd_dst < 0)
1056 eDebug("can't open /dev/misc/pvr - you need to buy the new(!) $$$ box! (%m)"); // or wait for the driver to be improved.
1060 m_pvr_thread = new eFilePushThread();
1061 m_pvr_thread->enablePVRCommit(1);
1062 m_pvr_thread->setScatterGather(this);
1064 if (m_pvr_thread->start(file, m_pvr_fd_dst))
1066 delete m_pvr_thread;
1068 eDebug("can't open PVR file %s (%m)", file);
1071 CONNECT(m_pvr_thread->m_event, eDVBChannel::pvrEvent);
1074 m_stateChanged(this);
1079 void eDVBChannel::stopFile()
1083 m_pvr_thread->stop();
1084 ::close(m_pvr_fd_dst);
1085 delete m_pvr_thread;
1090 void eDVBChannel::setCueSheet(eCueSheet *cuesheet)
1092 m_conn_cueSheetEvent = 0;
1095 m_cue->connectEvent(slot(*this, &eDVBChannel::cueSheetEvent), m_conn_cueSheetEvent);
1098 RESULT eDVBChannel::getLength(pts_t &len)
1100 return m_tstools.calcLen(len);
1103 RESULT eDVBChannel::getCurrentPosition(iDVBDemux *decoding_demux, pts_t &pos, int mode)
1105 if (!decoding_demux)
1112 if (mode == 0) /* demux */
1114 r = decoding_demux->getSTC(now, 0);
1117 eDebug("demux getSTC failed");
1121 now = pos; /* fixup supplied */
1123 off_t off = 0; /* TODO: fixme */
1124 r = m_tstools.fixupPTS(off, now);
1127 eDebug("fixup PTS failed");
1136 void eDVBChannel::flushPVR(iDVBDemux *decoding_demux)
1138 /* when seeking, we have to ensure that all buffers are flushed.
1139 there are basically 3 buffers:
1140 a.) the filepush's internal buffer
1141 b.) the PVR buffer (before demux)
1142 c.) the ratebuffer (after demux)
1144 it's important to clear them in the correct order, otherwise
1145 the ratebuffer (for example) would immediately refill from
1146 the not-yet-flushed PVR buffer.
1149 m_pvr_thread->pause();
1150 /* flush internal filepush buffer */
1151 m_pvr_thread->flush();
1152 /* HACK: flush PVR buffer */
1153 ::ioctl(m_pvr_fd_dst, 0);
1155 /* flush ratebuffers (video, audio) */
1157 decoding_demux->flush();
1159 /* demux will also flush all decoder.. */
1160 /* resume will re-query the SG */
1161 m_pvr_thread->resume();
1164 DEFINE_REF(eCueSheet);
1166 eCueSheet::eCueSheet()
1168 m_skipmode_ratio = 0;
1171 void eCueSheet::seekTo(int relative, const pts_t &pts)
1174 eSingleLock l(m_lock);
1175 m_seek_requests.push_back(std::pair<int, pts_t>(relative, pts));
1180 void eCueSheet::clear()
1182 eSingleLock l(m_lock);
1186 void eCueSheet::addSourceSpan(const pts_t &begin, const pts_t &end)
1189 eSingleLock l(m_lock);
1190 m_spans.push_back(std::pair<pts_t, pts_t>(begin, end));
1194 void eCueSheet::commitSpans()
1196 m_event(evtSpanChanged);
1199 void eCueSheet::setSkipmode(const pts_t &ratio)
1202 eSingleLock l(m_lock);
1203 m_skipmode_ratio = ratio;
1205 m_event(evtSkipmode);
1208 void eCueSheet::setDecodingDemux(iDVBDemux *demux, iTSMPEGDecoder *decoder)
1210 m_decoding_demux = demux;
1211 m_decoder = decoder;
1214 RESULT eCueSheet::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1216 connection = new eConnection(this, m_event.connect(event));