1 #include <lib/base/eerror.h>
2 #include <lib/base/object.h>
4 #include <lib/service/servicedvb.h>
5 #include <lib/service/service.h>
6 #include <lib/base/init_num.h>
7 #include <lib/base/init.h>
9 #include <lib/dvb/dvb.h>
10 #include <lib/dvb/db.h>
11 #include <lib/dvb/decoder.h>
13 #include <lib/service/servicedvbrecord.h>
14 #include <lib/dvb/metaparser.h>
15 #include <lib/dvb/tstools.h>
17 class eStaticServiceDVBInformation: public iStaticServiceInformation
19 DECLARE_REF(eStaticServiceDVBInformation);
21 RESULT getName(const eServiceReference &ref, std::string &name);
22 int getLength(const eServiceReference &ref);
25 DEFINE_REF(eStaticServiceDVBInformation);
27 RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
29 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
30 if ( !ref.name.empty() )
32 if (service.getParentTransportStreamID().get()) // linkage subservice
34 ePtr<iServiceHandler> service_center;
35 if (!eServiceCenter::getInstance(service_center))
37 eServiceReferenceDVB parent = service;
38 parent.setTransportStreamID( service.getParentTransportStreamID() );
39 parent.setServiceID( service.getParentServiceID() );
40 parent.setParentTransportStreamID(eTransportStreamID(0));
41 parent.setParentServiceID(eServiceID(0));
43 ePtr<iStaticServiceInformation> service_info;
44 if (!service_center->info(parent, service_info))
46 if (!service_info->getName(parent, name))
48 // just show short name
49 unsigned int pos = name.find("\xc2\x86");
50 if ( pos != std::string::npos )
52 pos = name.find("\xc2\x87");
53 if ( pos != std::string::npos )
69 int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
74 class eStaticServiceDVBBouquetInformation: public iStaticServiceInformation
76 DECLARE_REF(eStaticServiceDVBBouquetInformation);
78 RESULT getName(const eServiceReference &ref, std::string &name);
79 int getLength(const eServiceReference &ref);
82 DEFINE_REF(eStaticServiceDVBBouquetInformation);
84 RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
86 ePtr<iDVBChannelList> db;
87 ePtr<eDVBResourceManager> res;
90 if ((err = eDVBResourceManager::getInstance(res)) != 0)
92 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
95 if ((err = res->getChannelList(db)) != 0)
97 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
102 if ((err = db->getBouquet(ref, bouquet)) != 0)
104 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
108 if ( bouquet && bouquet->m_bouquet_name.length() )
110 name = bouquet->m_bouquet_name;
117 int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
122 class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
124 DECLARE_REF(eStaticServiceDVBPVRInformation);
125 eServiceReference m_ref;
126 eDVBMetaParser m_parser;
128 eStaticServiceDVBPVRInformation(const eServiceReference &ref);
129 RESULT getName(const eServiceReference &ref, std::string &name);
130 int getLength(const eServiceReference &ref);
132 int getInfo(const eServiceReference &ref, int w);
133 std::string getInfoString(const eServiceReference &ref,int w);
136 DEFINE_REF(eStaticServiceDVBPVRInformation);
138 eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
141 m_parser.parseFile(ref.path);
144 RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
146 ASSERT(ref == m_ref);
147 name = m_parser.m_name.size() ? m_parser.m_name : ref.path;
151 int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
153 ASSERT(ref == m_ref);
157 if (tstools.openFile(ref.path.c_str()))
161 if (tstools.calcLen(len))
167 int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
171 case iServiceInformation::sDescription:
172 return iServiceInformation::resIsString;
173 case iServiceInformation::sTimeCreate:
174 if (m_parser.m_time_create)
175 return m_parser.m_time_create;
177 return iServiceInformation::resNA;
179 return iServiceInformation::resNA;
183 std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
187 case iServiceInformation::sDescription:
188 return m_parser.m_description;
194 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
196 DECLARE_REF(eDVBPVRServiceOfflineOperations);
197 eServiceReferenceDVB m_ref;
199 eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
201 RESULT deleteFromDisk(int simulate);
202 RESULT getListOfFilenames(std::list<std::string> &);
205 DEFINE_REF(eDVBPVRServiceOfflineOperations);
207 eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
211 RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
217 std::list<std::string> res;
218 if (getListOfFilenames(res))
221 /* TODO: deferred removing.. */
222 for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
224 eDebug("Removing %s...", i->c_str());
225 ::unlink(i->c_str());
232 RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
235 res.push_back(m_ref.path);
236 res.push_back(m_ref.path + ".meta");
240 DEFINE_REF(eServiceFactoryDVB)
242 eServiceFactoryDVB::eServiceFactoryDVB()
244 ePtr<eServiceCenter> sc;
246 eServiceCenter::getPrivInstance(sc);
248 sc->addServiceFactory(eServiceFactoryDVB::id, this);
251 eServiceFactoryDVB::~eServiceFactoryDVB()
253 ePtr<eServiceCenter> sc;
255 eServiceCenter::getPrivInstance(sc);
257 sc->removeServiceFactory(eServiceFactoryDVB::id);
260 DEFINE_REF(eDVBServiceList);
262 eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
266 eDVBServiceList::~eDVBServiceList()
270 RESULT eDVBServiceList::startQuery()
272 ePtr<iDVBChannelList> db;
273 ePtr<eDVBResourceManager> res;
276 if ((err = eDVBResourceManager::getInstance(res)) != 0)
278 eDebug("no resource manager");
281 if ((err = res->getChannelList(db)) != 0)
283 eDebug("no channel list");
287 ePtr<eDVBChannelQuery> q;
289 if (!m_parent.path.empty())
291 eDVBChannelQuery::compile(q, m_parent.path);
294 eDebug("compile query failed");
299 if ((err = db->startQuery(m_query, q, m_parent)) != 0)
301 eDebug("startQuery failed");
308 RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list)
310 eServiceReferenceDVB ref;
315 while (!m_query->getNextResult(ref))
320 RESULT eDVBServiceList::getNext(eServiceReference &ref)
325 return m_query->getNextResult((eServiceReferenceDVB&)ref);
328 int eDVBServiceList::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
330 return m_query->compareLessEqual((const eServiceReferenceDVB&)a, (const eServiceReferenceDVB&)b);
333 RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
335 if (m_parent.flags & eServiceReference::flagDirectory) // bouquet
337 ePtr<iDVBChannelList> db;
338 ePtr<eDVBResourceManager> resm;
340 if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
343 if (db->getBouquet(m_parent, m_bouquet) != 0)
354 RESULT eDVBServiceList::addService(eServiceReference &ref)
358 return m_bouquet->addService(ref);
361 RESULT eDVBServiceList::removeService(eServiceReference &ref)
365 return m_bouquet->removeService(ref);
368 RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
372 return m_bouquet->moveService(ref, pos);
375 RESULT eDVBServiceList::flushChanges()
379 return m_bouquet->flushChanges();
382 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
384 ePtr<eDVBService> service;
385 int r = lookupService(service, ref);
388 // check resources...
389 ptr = new eDVBServicePlay(ref, service);
393 RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
395 if (ref.path.empty())
397 ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
406 RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
408 ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
409 if (list->startQuery())
419 RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
421 /* is a listable service? */
422 if ((ref.flags & eServiceReference::flagDirectory) == eServiceReference::flagDirectory) // bouquet
424 if ( !ref.name.empty() ) // satellites or providers list
425 ptr = new eStaticServiceDVBInformation;
426 else // a dvb bouquet
427 ptr = new eStaticServiceDVBBouquetInformation;
429 else if (!ref.path.empty()) /* do we have a PVR service? */
430 ptr = new eStaticServiceDVBPVRInformation(ref);
431 else // normal dvb service
433 ePtr<eDVBService> service;
434 if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
435 ptr = new eStaticServiceDVBInformation;
437 /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
443 RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
445 if (ref.path.empty())
451 ptr = new eDVBPVRServiceOfflineOperations(ref);
456 RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
458 // TODO: handle the listing itself
459 // if (ref.... == -1) .. return "... bouquets ...";
460 // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
462 ePtr<iDVBChannelList> db;
463 ePtr<eDVBResourceManager> res;
466 if ((err = eDVBResourceManager::getInstance(res)) != 0)
468 eDebug("no resource manager");
471 if ((err = res->getChannelList(db)) != 0)
473 eDebug("no channel list");
477 /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
478 if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
480 eDebug("getService failed!");
487 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
488 m_reference(ref), m_dvb_service(service), m_is_paused(0)
490 m_is_pvr = !ref.path.empty();
491 m_timeshift_enabled = m_timeshift_active = 0;
493 CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
494 CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
495 CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
498 eDVBServicePlay::~eDVBServicePlay()
502 void eDVBServicePlay::gotNewEvent()
506 ePtr<eServiceEvent> m_event_now, m_event_next;
507 getEvent(m_event_now, 0);
508 getEvent(m_event_next, 1);
511 eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
513 eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
515 m_event((iPlayableService*)this, evUpdatedEventInfo);
518 void eDVBServicePlay::serviceEvent(int event)
522 case eDVBServicePMTHandler::eventTuned:
524 ePtr<iDVBDemux> m_demux;
525 if (!m_service_handler.getDataDemux(m_demux))
527 eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
528 int sid = ref.getParentServiceID().get();
530 sid = ref.getServiceID().get();
531 if ( ref.getParentTransportStreamID().get() &&
532 ref.getParentTransportStreamID() != ref.getTransportStreamID() )
533 m_event_handler.startOther(m_demux, sid);
535 m_event_handler.start(m_demux, sid);
539 case eDVBServicePMTHandler::eventTuneFailed:
541 eDebug("DVB service failed to tune");
542 m_event((iPlayableService*)this, evTuneFailed);
545 case eDVBServicePMTHandler::eventNewProgramInfo:
547 eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
548 if (m_timeshift_enabled)
549 updateTimeshiftPids();
550 if (!m_timeshift_active)
552 m_event((iPlayableService*)this, evUpdatedInfo);
555 case eDVBServicePMTHandler::eventEOF:
557 m_event((iPlayableService*)this, evEnd);
563 void eDVBServicePlay::serviceEventTimeshift(int event)
567 case eDVBServicePMTHandler::eventNewProgramInfo:
568 if (m_timeshift_active)
571 case eDVBServicePMTHandler::eventEOF:
577 RESULT eDVBServicePlay::start()
580 /* in pvr mode, we only want to use one demux. in tv mode, we're using
581 two (one for decoding, one for data source), as we must be prepared
582 to start recording from the data demux. */
583 r = m_service_handler.tune((eServiceReferenceDVB&)m_reference, m_is_pvr);
584 m_event(this, evStart);
588 RESULT eDVBServicePlay::stop()
593 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
595 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
599 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
601 if ((!m_is_pvr) && (!m_timeshift_enabled))
611 RESULT eDVBServicePlay::setSlowMotion(int ratio)
614 return m_decoder->setSlowMotion(ratio);
619 RESULT eDVBServicePlay::setFastForward(int ratio)
622 return m_decoder->setFastForward(ratio);
627 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
629 if (m_is_pvr || m_timeshift_active)
639 RESULT eDVBServicePlay::getLength(pts_t &len)
641 ePtr<iDVBPVRChannel> pvr_channel;
643 if (m_service_handler.getPVRChannel(pvr_channel))
645 eDebug("getPVRChannel failed!");
649 return pvr_channel->getLength(len);
652 RESULT eDVBServicePlay::pause()
654 if (!m_is_paused && m_decoder)
657 return m_decoder->freeze(0);
662 RESULT eDVBServicePlay::unpause()
664 if (m_is_paused && m_decoder)
667 return m_decoder->unfreeze();
672 RESULT eDVBServicePlay::seekTo(pts_t to)
674 eDebug("eDVBServicePlay::seekTo: jump %lld", to);
679 ePtr<iDVBPVRChannel> pvr_channel;
681 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
684 return pvr_channel->seekTo(m_decode_demux, 0, to);
687 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
689 eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
694 ePtr<iDVBPVRChannel> pvr_channel;
696 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
701 return pvr_channel->seekTo(m_decode_demux, 1, to);
704 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
706 ePtr<iDVBPVRChannel> pvr_channel;
711 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
714 return pvr_channel->getCurrentPosition(m_decode_demux, pos, 1);
717 RESULT eDVBServicePlay::setTrickmode(int trick)
720 m_decoder->setTrickmode(trick);
724 RESULT eDVBServicePlay::frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr)
730 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
736 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
742 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
748 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
750 if (m_timeshift_enabled || !m_is_pvr)
759 RESULT eDVBServicePlay::getName(std::string &name)
763 m_dvb_service->getName(m_reference, name);
767 else if (!m_reference.name.empty())
768 eStaticServiceDVBInformation().getName(m_reference, name);
770 name = "DVB service";
774 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
776 return m_event_handler.getEvent(evt, nownext);
779 int eDVBServicePlay::getInfo(int w)
781 eDVBServicePMTHandler::program program;
783 if (m_service_handler.getProgramInfo(program))
789 if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
791 ePtr<eServiceEvent> evt;
792 if (!m_event_handler.getEvent(evt, 0))
794 ePtr<eComponentData> data;
795 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
797 if ( data->getStreamContent() == 1 )
799 switch(data->getComponentType())
802 case 1: // 4:3 SD PAL
804 case 3: // 16:9 SD PAL
805 case 4: // > 16:9 PAL
806 case 5: // 4:3 SD NTSC
808 case 7: // 16:9 SD NTSC
809 case 8: // > 16:9 NTSC
812 case 9: // 4:3 HD PAL
814 case 0xB: // 16:9 HD PAL
815 case 0xC: // > 16:9 HD PAL
816 case 0xD: // 4:3 HD NTSC
818 case 0xF: // 16:9 HD NTSC
819 case 0x10: // > 16:9 HD PAL
820 return data->getComponentType();
827 case sIsCrypted: return program.isCrypted;
828 case sVideoPID: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
829 case sAudioPID: if (program.audioStreams.empty()) return -1; return program.audioStreams[m_current_audio_stream].pid;
830 case sPCRPID: return program.pcrPid;
831 case sPMTPID: return program.pmtPid;
832 case sTXTPID: return -1;
833 case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
834 case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
835 case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
836 case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
837 case sProvider: if (!m_dvb_service) return -1; return -2;
843 std::string eDVBServicePlay::getInfoString(int w)
848 if (!m_dvb_service) return "";
849 return m_dvb_service->m_provider_name;
855 int eDVBServicePlay::getNumberOfTracks()
857 eDVBServicePMTHandler::program program;
858 if (m_service_handler.getProgramInfo(program))
860 return program.audioStreams.size();
863 RESULT eDVBServicePlay::selectTrack(unsigned int i)
865 int ret = selectAudioStream(i);
867 if (m_decoder->start())
873 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
875 eDVBServicePMTHandler::program program;
877 if (m_service_handler.getProgramInfo(program))
880 if (i >= program.audioStreams.size())
883 if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
884 info.m_description = "MPEG";
885 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
886 info.m_description = "AC3";
887 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
888 info.m_description = "DTS";
890 info.m_description = "???";
892 if (program.audioStreams[i].component_tag != -1)
894 ePtr<eServiceEvent> evt;
895 if (!m_event_handler.getEvent(evt, 0))
897 ePtr<eComponentData> data;
898 if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
899 info.m_language = data->getText();
903 if (info.m_language.empty())
904 info.m_language = program.audioStreams[i].language_code;
909 int eDVBServicePlay::selectAudioStream(int i)
911 eDVBServicePMTHandler::program program;
913 if (m_service_handler.getProgramInfo(program))
916 if ((unsigned int)i >= program.audioStreams.size())
922 if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
925 if (m_dvb_service && !m_is_pvr)
927 if (program.audioStreams[i].type == eDVBAudio::aMPEG)
929 m_dvb_service->setCachePID(eDVBService::cAPID, program.audioStreams[i].pid);
930 m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
933 m_dvb_service->setCachePID(eDVBService::cAPID, -1);
934 m_dvb_service->setCachePID(eDVBService::cAC3PID, program.audioStreams[i].pid);
938 m_current_audio_stream = i;
943 int eDVBServicePlay::getFrontendInfo(int w)
947 eUsePtr<iDVBChannel> channel;
948 if(m_service_handler.getChannel(channel))
950 ePtr<iDVBFrontend> fe;
951 if(channel->getFrontend(fe))
953 return fe->readFrontendData(w);
956 int eDVBServicePlay::getNumberOfSubservices()
958 ePtr<eServiceEvent> evt;
959 if (!m_event_handler.getEvent(evt, 0))
960 return evt->getNumOfLinkageServices();
964 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
966 ePtr<eServiceEvent> evt;
967 if (!m_event_handler.getEvent(evt, 0))
969 if (!evt->getLinkageService(sub, m_reference, n))
972 sub.type=eServiceReference::idInvalid;
976 RESULT eDVBServicePlay::startTimeshift()
978 ePtr<iDVBDemux> demux;
980 eDebug("Start timeshift!");
982 if (m_timeshift_enabled)
985 /* start recording with the data demux. */
986 if (m_service_handler.getDataDemux(demux))
989 demux->createTSRecorder(m_record);
993 char templ[]="/media/hdd/timeshift.XXXXXX";
994 m_timeshift_fd = mkstemp(templ);
995 m_timeshift_file = templ;
997 eDebug("recording to %s", templ);
999 if (m_timeshift_fd < 0)
1005 m_record->setTargetFD(m_timeshift_fd);
1007 m_timeshift_enabled = 1;
1009 updateTimeshiftPids();
1015 RESULT eDVBServicePlay::stopTimeshift()
1017 if (!m_timeshift_enabled)
1022 m_timeshift_enabled = 0;
1027 close(m_timeshift_fd);
1028 remove(m_timeshift_file.c_str());
1030 eDebug("timeshift disabled");
1034 int eDVBServicePlay::isTimeshiftActive()
1036 return m_timeshift_enabled && m_timeshift_active;
1039 RESULT eDVBServicePlay::activateTimeshift()
1041 if (!m_timeshift_enabled)
1044 if (!m_timeshift_active)
1046 switchToTimeshift();
1053 void eDVBServicePlay::updateTimeshiftPids()
1058 eDVBServicePMTHandler::program program;
1059 if (m_service_handler.getProgramInfo(program))
1063 std::set<int> pids_to_record;
1064 pids_to_record.insert(0); // PAT
1065 if (program.pmtPid != -1)
1066 pids_to_record.insert(program.pmtPid); // PMT
1068 if (program.textPid != -1)
1069 pids_to_record.insert(program.textPid); // Videotext
1071 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1072 i(program.videoStreams.begin());
1073 i != program.videoStreams.end(); ++i)
1074 pids_to_record.insert(i->pid);
1076 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1077 i(program.audioStreams.begin());
1078 i != program.audioStreams.end(); ++i)
1079 pids_to_record.insert(i->pid);
1081 std::set<int> new_pids, obsolete_pids;
1083 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
1084 m_pids_active.begin(), m_pids_active.end(),
1085 std::inserter(new_pids, new_pids.begin()));
1087 std::set_difference(
1088 m_pids_active.begin(), m_pids_active.end(),
1089 pids_to_record.begin(), pids_to_record.end(),
1090 std::inserter(new_pids, new_pids.begin())
1093 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
1094 m_record->addPID(*i);
1096 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
1097 m_record->removePID(*i);
1101 void eDVBServicePlay::switchToLive()
1103 eDebug("SwitchToLive");
1104 if (!m_timeshift_active)
1109 /* free the timeshift service handler, we need the resources */
1110 m_service_handler_timeshift.free();
1111 m_timeshift_active = 0;
1113 m_event((iPlayableService*)this, evSeekableStatusChanged);
1118 void eDVBServicePlay::switchToTimeshift()
1120 eDebug("SwitchToTimeshift");
1121 if (m_timeshift_active)
1127 m_timeshift_active = 1;
1129 m_event((iPlayableService*)this, evSeekableStatusChanged);
1131 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1132 r.path = m_timeshift_file;
1134 eDebug("ok, re-tuning to %s", r.toString().c_str());
1135 m_service_handler_timeshift.tune(r, 1); /* use the decoder demux for everything */
1138 void eDVBServicePlay::updateDecoder()
1140 int vpid = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1;
1141 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1143 eDVBServicePMTHandler::program program;
1144 if (h.getProgramInfo(program))
1145 eDebug("getting program info failed.");
1148 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
1149 if (!program.videoStreams.empty())
1151 eDebugNoNewLine(" (");
1152 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1153 i(program.videoStreams.begin());
1154 i != program.videoStreams.end(); ++i)
1158 if (i != program.videoStreams.begin())
1159 eDebugNoNewLine(", ");
1160 eDebugNoNewLine("%04x", i->pid);
1162 eDebugNoNewLine(")");
1164 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
1165 if (!program.audioStreams.empty())
1167 eDebugNoNewLine(" (");
1168 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1169 i(program.audioStreams.begin());
1170 i != program.audioStreams.end(); ++i)
1177 if (i != program.audioStreams.begin())
1178 eDebugNoNewLine(", ");
1179 eDebugNoNewLine("%04x", i->pid);
1181 eDebugNoNewLine(")");
1183 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
1184 pcrpid = program.pcrPid;
1185 eDebug(", and the text pid is %04x", program.textPid);
1186 tpid = program.textPid;
1191 h.getDecodeDemux(m_decode_demux);
1193 m_decode_demux->getMPEGDecoder(m_decoder);
1198 m_decoder->setVideoPID(vpid);
1199 m_current_audio_stream = 0;
1200 m_decoder->setAudioPID(apid, apidtype);
1201 if (!(m_is_pvr || m_timeshift_active))
1202 m_decoder->setSyncPCR(pcrpid);
1204 m_decoder->setSyncPCR(-1);
1205 m_decoder->setTextPID(tpid);
1207 // how we can do this better?
1208 // update cache pid when the user changed the audio track or video track
1209 // TODO handling of difference audio types.. default audio types..
1211 /* don't worry about non-existing services, nor pvr services */
1212 if (m_dvb_service && !m_is_pvr)
1214 if (apidtype == eDVBAudio::aMPEG)
1216 m_dvb_service->setCachePID(eDVBService::cAPID, apid);
1217 m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
1221 m_dvb_service->setCachePID(eDVBService::cAPID, -1);
1222 m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
1224 m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
1225 m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
1226 m_dvb_service->setCachePID(eDVBService::cTPID, tpid);
1231 DEFINE_REF(eDVBServicePlay)
1233 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");