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:
556 m_event((iPlayableService*)this, evEnd);
560 void eDVBServicePlay::serviceEventTimeshift(int event)
564 case eDVBServicePMTHandler::eventNewProgramInfo:
565 if (m_timeshift_active)
571 RESULT eDVBServicePlay::start()
574 /* in pvr mode, we only want to use one demux. in tv mode, we're using
575 two (one for decoding, one for data source), as we must be prepared
576 to start recording from the data demux. */
577 r = m_service_handler.tune((eServiceReferenceDVB&)m_reference, m_is_pvr);
578 m_event(this, evStart);
582 RESULT eDVBServicePlay::stop()
587 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
589 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
593 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
595 if ((!m_is_pvr) && (!m_timeshift_enabled))
605 RESULT eDVBServicePlay::setSlowMotion(int ratio)
608 return m_decoder->setSlowMotion(ratio);
613 RESULT eDVBServicePlay::setFastForward(int ratio)
616 return m_decoder->setFastForward(ratio);
621 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
623 if (m_is_pvr || m_timeshift_enabled)
633 RESULT eDVBServicePlay::getLength(pts_t &len)
635 ePtr<iDVBPVRChannel> pvr_channel;
637 if (m_service_handler.getPVRChannel(pvr_channel))
639 eDebug("getPVRChannel failed!");
643 return pvr_channel->getLength(len);
646 RESULT eDVBServicePlay::pause()
648 if (m_timeshift_enabled && !m_timeshift_active)
653 if (!m_is_paused && m_decoder)
656 return m_decoder->freeze(0);
661 RESULT eDVBServicePlay::unpause()
663 if (m_is_paused && m_decoder)
666 return m_decoder->unfreeze();
671 RESULT eDVBServicePlay::seekTo(pts_t to)
673 eDebug("eDVBServicePlay::seekTo: jump %lld", to);
678 ePtr<iDVBPVRChannel> pvr_channel;
680 if (m_service_handler.getPVRChannel(pvr_channel))
683 return pvr_channel->seekTo(m_decode_demux, 0, to);
686 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
688 eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
693 ePtr<iDVBPVRChannel> pvr_channel;
695 if (m_service_handler.getPVRChannel(pvr_channel))
700 return pvr_channel->seekTo(m_decode_demux, 1, to);
703 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
705 ePtr<iDVBPVRChannel> pvr_channel;
710 if (m_service_handler.getPVRChannel(pvr_channel))
713 return pvr_channel->getCurrentPosition(m_decode_demux, pos, 1);
716 RESULT eDVBServicePlay::setTrickmode(int trick)
719 m_decoder->setTrickmode(trick);
723 RESULT eDVBServicePlay::frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr)
729 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
735 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
741 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
747 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
749 if (m_timeshift_enabled || !m_is_pvr)
758 RESULT eDVBServicePlay::getName(std::string &name)
762 m_dvb_service->getName(m_reference, name);
766 else if (!m_reference.name.empty())
767 eStaticServiceDVBInformation().getName(m_reference, name);
769 name = "DVB service";
773 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
775 return m_event_handler.getEvent(evt, nownext);
778 int eDVBServicePlay::getInfo(int w)
780 eDVBServicePMTHandler::program program;
782 if (m_service_handler.getProgramInfo(program))
788 if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
790 ePtr<eServiceEvent> evt;
791 if (!m_event_handler.getEvent(evt, 0))
793 ePtr<eComponentData> data;
794 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
796 if ( data->getStreamContent() == 1 )
798 switch(data->getComponentType())
801 case 1: // 4:3 SD PAL
803 case 3: // 16:9 SD PAL
804 case 4: // > 16:9 PAL
805 case 5: // 4:3 SD NTSC
807 case 7: // 16:9 SD NTSC
808 case 8: // > 16:9 NTSC
811 case 9: // 4:3 HD PAL
813 case 0xB: // 16:9 HD PAL
814 case 0xC: // > 16:9 HD PAL
815 case 0xD: // 4:3 HD NTSC
817 case 0xF: // 16:9 HD NTSC
818 case 0x10: // > 16:9 HD PAL
819 return data->getComponentType();
826 case sIsCrypted: return program.isCrypted;
827 case sVideoPID: if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
828 case sAudioPID: if (program.audioStreams.empty()) return -1; return program.audioStreams[m_current_audio_stream].pid;
829 case sPCRPID: return program.pcrPid;
830 case sPMTPID: return program.pmtPid;
831 case sTXTPID: return -1;
832 case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
833 case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
834 case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
835 case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
836 case sProvider: if (!m_dvb_service) return -1; return -2;
842 std::string eDVBServicePlay::getInfoString(int w)
847 if (!m_dvb_service) return "";
848 return m_dvb_service->m_provider_name;
854 int eDVBServicePlay::getNumberOfTracks()
856 eDVBServicePMTHandler::program program;
857 if (m_service_handler.getProgramInfo(program))
859 return program.audioStreams.size();
862 RESULT eDVBServicePlay::selectTrack(unsigned int i)
864 int ret = selectAudioStream(i);
866 if (m_decoder->start())
872 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
874 eDVBServicePMTHandler::program program;
876 if (m_service_handler.getProgramInfo(program))
879 if (i >= program.audioStreams.size())
882 if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
883 info.m_description = "MPEG";
884 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
885 info.m_description = "AC3";
886 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
887 info.m_description = "DTS";
889 info.m_description = "???";
891 if (program.audioStreams[i].component_tag != -1)
893 ePtr<eServiceEvent> evt;
894 if (!m_event_handler.getEvent(evt, 0))
896 ePtr<eComponentData> data;
897 if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
898 info.m_language = data->getText();
902 if (info.m_language.empty())
903 info.m_language = program.audioStreams[i].language_code;
908 int eDVBServicePlay::selectAudioStream(int i)
910 eDVBServicePMTHandler::program program;
912 if (m_service_handler.getProgramInfo(program))
915 if ((unsigned int)i >= program.audioStreams.size())
921 if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
924 if (m_dvb_service && !m_is_pvr)
926 if (program.audioStreams[i].type == eDVBAudio::aMPEG)
928 m_dvb_service->setCachePID(eDVBService::cAPID, program.audioStreams[i].pid);
929 m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
932 m_dvb_service->setCachePID(eDVBService::cAPID, -1);
933 m_dvb_service->setCachePID(eDVBService::cAC3PID, program.audioStreams[i].pid);
937 m_current_audio_stream = i;
942 int eDVBServicePlay::getFrontendInfo(int w)
946 eUsePtr<iDVBChannel> channel;
947 if(m_service_handler.getChannel(channel))
949 ePtr<iDVBFrontend> fe;
950 if(channel->getFrontend(fe))
952 return fe->readFrontendData(w);
955 int eDVBServicePlay::getNumberOfSubservices()
957 ePtr<eServiceEvent> evt;
958 if (!m_event_handler.getEvent(evt, 0))
959 return evt->getNumOfLinkageServices();
963 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
965 ePtr<eServiceEvent> evt;
966 if (!m_event_handler.getEvent(evt, 0))
968 if (!evt->getLinkageService(sub, m_reference, n))
971 sub.type=eServiceReference::idInvalid;
975 RESULT eDVBServicePlay::startTimeshift()
977 ePtr<iDVBDemux> demux;
979 eDebug("Start timeshift!");
981 if (m_timeshift_enabled)
984 /* start recording with the data demux. */
985 if (m_service_handler.getDataDemux(demux))
988 demux->createTSRecorder(m_record);
992 char templ[]="/media/hdd/timeshift.XXXXXX";
993 m_timeshift_fd = mkstemp(templ);
994 m_timeshift_file = templ;
996 eDebug("recording to %s", templ);
998 if (m_timeshift_fd < 0)
1004 m_record->setTargetFD(m_timeshift_fd);
1006 m_timeshift_enabled = 1;
1008 updateTimeshiftPids();
1014 RESULT eDVBServicePlay::stopTimeshift()
1016 if (!m_timeshift_enabled)
1021 m_timeshift_enabled = 0;
1026 close(m_timeshift_fd);
1027 remove(m_timeshift_file.c_str());
1029 eDebug("timeshift disabled");
1033 void eDVBServicePlay::updateTimeshiftPids()
1038 eDVBServicePMTHandler::program program;
1039 if (m_service_handler.getProgramInfo(program))
1043 std::set<int> pids_to_record;
1044 pids_to_record.insert(0); // PAT
1045 if (program.pmtPid != -1)
1046 pids_to_record.insert(program.pmtPid); // PMT
1048 if (program.textPid != -1)
1049 pids_to_record.insert(program.textPid); // Videotext
1051 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1052 i(program.videoStreams.begin());
1053 i != program.videoStreams.end(); ++i)
1054 pids_to_record.insert(i->pid);
1056 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1057 i(program.audioStreams.begin());
1058 i != program.audioStreams.end(); ++i)
1059 pids_to_record.insert(i->pid);
1061 std::set<int> new_pids, obsolete_pids;
1063 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
1064 m_pids_active.begin(), m_pids_active.end(),
1065 std::inserter(new_pids, new_pids.begin()));
1067 std::set_difference(
1068 m_pids_active.begin(), m_pids_active.end(),
1069 pids_to_record.begin(), pids_to_record.end(),
1070 std::inserter(new_pids, new_pids.begin())
1073 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
1074 m_record->addPID(*i);
1076 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
1077 m_record->removePID(*i);
1081 void eDVBServicePlay::switchToLive()
1083 eDebug("SwitchToLive");
1084 if (!m_timeshift_active)
1089 /* free the timeshift service handler, we need the resources */
1090 m_service_handler_timeshift.free();
1091 m_timeshift_active = 0;
1096 void eDVBServicePlay::switchToTimeshift()
1098 eDebug("SwitchToTimeshift");
1099 if (m_timeshift_active)
1105 m_timeshift_active = 1;
1107 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1108 r.path = m_timeshift_file;
1110 eDebug("ok, re-tuning to %s", r.toString().c_str());
1111 m_service_handler_timeshift.tune(r, 1); /* use the decoder demux for everything */
1114 void eDVBServicePlay::updateDecoder()
1116 int vpid = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1;
1117 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1119 eDVBServicePMTHandler::program program;
1120 if (h.getProgramInfo(program))
1121 eDebug("getting program info failed.");
1124 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
1125 if (!program.videoStreams.empty())
1127 eDebugNoNewLine(" (");
1128 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1129 i(program.videoStreams.begin());
1130 i != program.videoStreams.end(); ++i)
1134 if (i != program.videoStreams.begin())
1135 eDebugNoNewLine(", ");
1136 eDebugNoNewLine("%04x", i->pid);
1138 eDebugNoNewLine(")");
1140 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
1141 if (!program.audioStreams.empty())
1143 eDebugNoNewLine(" (");
1144 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1145 i(program.audioStreams.begin());
1146 i != program.audioStreams.end(); ++i)
1153 if (i != program.audioStreams.begin())
1154 eDebugNoNewLine(", ");
1155 eDebugNoNewLine("%04x", i->pid);
1157 eDebugNoNewLine(")");
1159 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
1160 pcrpid = program.pcrPid;
1161 eDebug(", and the text pid is %04x", program.textPid);
1162 tpid = program.textPid;
1167 h.getDecodeDemux(m_decode_demux);
1169 m_decode_demux->getMPEGDecoder(m_decoder);
1174 m_decoder->setVideoPID(vpid);
1175 m_current_audio_stream = 0;
1176 m_decoder->setAudioPID(apid, apidtype);
1177 if (!(m_is_pvr || m_timeshift_active))
1178 m_decoder->setSyncPCR(pcrpid);
1180 m_decoder->setSyncPCR(-1);
1181 m_decoder->setTextPID(tpid);
1183 // how we can do this better?
1184 // update cache pid when the user changed the audio track or video track
1185 // TODO handling of difference audio types.. default audio types..
1187 /* don't worry about non-existing services, nor pvr services */
1188 if (m_dvb_service && !m_is_pvr)
1190 if (apidtype == eDVBAudio::aMPEG)
1192 m_dvb_service->setCachePID(eDVBService::cAPID, apid);
1193 m_dvb_service->setCachePID(eDVBService::cAC3PID, -1);
1197 m_dvb_service->setCachePID(eDVBService::cAPID, -1);
1198 m_dvb_service->setCachePID(eDVBService::cAC3PID, apid);
1200 m_dvb_service->setCachePID(eDVBService::cVPID, vpid);
1201 m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid);
1202 m_dvb_service->setCachePID(eDVBService::cTPID, tpid);
1207 DEFINE_REF(eDVBServicePlay)
1209 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");