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/estring.h>
7 #include <lib/base/init_num.h>
8 #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/components/file_eraser.h>
14 #include <lib/service/servicedvbrecord.h>
15 #include <lib/service/event.h>
16 #include <lib/dvb/metaparser.h>
17 #include <lib/dvb/tstools.h>
18 #include <lib/python/python.h>
19 #include <lib/base/nconfig.h> // access to python config
22 #include <lib/gui/esubtitle.h>
28 #include <netinet/in.h>
31 #error no byte order defined!
34 class eStaticServiceDVBInformation: public iStaticServiceInformation
36 DECLARE_REF(eStaticServiceDVBInformation);
38 RESULT getName(const eServiceReference &ref, std::string &name);
39 int getLength(const eServiceReference &ref);
40 int isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
41 PyObject *getInfoObject(const eServiceReference &ref, int);
44 DEFINE_REF(eStaticServiceDVBInformation);
46 RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
48 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
49 if ( !ref.name.empty() )
51 if (service.getParentTransportStreamID().get()) // linkage subservice
53 ePtr<iServiceHandler> service_center;
54 if (!eServiceCenter::getInstance(service_center))
56 eServiceReferenceDVB parent = service;
57 parent.setTransportStreamID( service.getParentTransportStreamID() );
58 parent.setServiceID( service.getParentServiceID() );
59 parent.setParentTransportStreamID(eTransportStreamID(0));
60 parent.setParentServiceID(eServiceID(0));
62 ePtr<iStaticServiceInformation> service_info;
63 if (!service_center->info(parent, service_info))
65 if (!service_info->getName(parent, name))
66 name=buildShortName(name) + " - ";
79 int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
84 int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore)
86 ePtr<eDVBResourceManager> res_mgr;
87 if ( eDVBResourceManager::getInstance( res_mgr ) )
88 eDebug("isPlayable... no res manager!!");
91 eDVBChannelID chid, chid_ignore;
92 ((const eServiceReferenceDVB&)ref).getChannelID(chid);
93 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
94 return res_mgr->canAllocateChannel(chid, chid_ignore);
99 extern void PutToDict(ePyObject &dict, const char*key, long value); // defined in dvb/frontend.cpp
100 extern void PutToDict(ePyObject &dict, const char*key, ePyObject item); // defined in dvb/frontend.cpp
101 extern void PutToDict(ePyObject &dict, const char*key, const char *value); // defined in dvb/frontend.cpp
103 void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &feparm)
105 PutToDict(dict, "tuner_type", "DVB-S");
106 PutToDict(dict, "frequency", feparm.frequency);
107 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
108 PutToDict(dict, "orbital_position", feparm.orbital_position);
109 PutToDict(dict, "inversion", feparm.inversion);
110 PutToDict(dict, "fec_inner", feparm.fec);
111 PutToDict(dict, "modulation", feparm.modulation);
112 PutToDict(dict, "polarization", feparm.polarisation);
113 if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
115 PutToDict(dict, "rolloff", feparm.rolloff);
116 PutToDict(dict, "pilot", feparm.pilot);
118 PutToDict(dict, "system", feparm.system);
121 void PutTerrestrialDataToDict(ePyObject &dict, eDVBFrontendParametersTerrestrial &feparm)
123 PutToDict(dict, "tuner_type", "DVB-T");
124 PutToDict(dict, "frequency", feparm.frequency);
125 PutToDict(dict, "bandwidth", feparm.bandwidth);
126 PutToDict(dict, "code_rate_lp", feparm.code_rate_LP);
127 PutToDict(dict, "code_rate_hp", feparm.code_rate_HP);
128 PutToDict(dict, "constellation", feparm.modulation);
129 PutToDict(dict, "transmission_mode", feparm.transmission_mode);
130 PutToDict(dict, "guard_interval", feparm.guard_interval);
131 PutToDict(dict, "hierarchy_information", feparm.hierarchy);
132 PutToDict(dict, "inversion", feparm.inversion);
135 void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
137 PutToDict(dict, "tuner_type", "DVB-C");
138 PutToDict(dict, "frequency", feparm.frequency);
139 PutToDict(dict, "symbol_rate", feparm.symbol_rate);
140 PutToDict(dict, "modulation", feparm.modulation);
141 PutToDict(dict, "inversion", feparm.inversion);
142 PutToDict(dict, "fec_inner", feparm.fec_inner);
145 PyObject *eStaticServiceDVBInformation::getInfoObject(const eServiceReference &r, int what)
147 if (r.type == eServiceReference::idDVB)
149 const eServiceReferenceDVB &ref = (const eServiceReferenceDVB&)r;
152 case iServiceInformation::sTransponderData:
154 ePtr<eDVBResourceManager> res;
155 if (!eDVBResourceManager::getInstance(res))
157 ePtr<iDVBChannelList> db;
158 if (!res->getChannelList(db))
161 ref.getChannelID(chid);
162 ePtr<iDVBFrontendParameters> feparm;
163 if (!db->getChannelFrontendData(chid, feparm))
166 if (!feparm->getSystem(system))
168 ePyObject dict = PyDict_New();
171 case iDVBFrontend::feSatellite:
173 eDVBFrontendParametersSatellite s;
175 PutSatelliteDataToDict(dict, s);
178 case iDVBFrontend::feTerrestrial:
180 eDVBFrontendParametersTerrestrial t;
182 PutTerrestrialDataToDict(dict, t);
185 case iDVBFrontend::feCable:
187 eDVBFrontendParametersCable c;
189 PutCableDataToDict(dict, c);
193 eDebug("unknown frontend type %d", system);
208 DEFINE_REF(eStaticServiceDVBBouquetInformation);
210 RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
212 ePtr<iDVBChannelList> db;
213 ePtr<eDVBResourceManager> res;
216 if ((err = eDVBResourceManager::getInstance(res)) != 0)
218 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
221 if ((err = res->getChannelList(db)) != 0)
223 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
228 if ((err = db->getBouquet(ref, bouquet)) != 0)
230 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
234 if ( bouquet && bouquet->m_bouquet_name.length() )
236 name = bouquet->m_bouquet_name;
243 int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate)
245 if (ref.flags & eServiceReference::isGroup)
247 ePtr<iDVBChannelList> db;
248 ePtr<eDVBResourceManager> res;
250 if (eDVBResourceManager::getInstance(res))
252 eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no resource manager!");
256 if (res->getChannelList(db))
258 eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no channel list!");
263 if (db->getBouquet(ref, bouquet))
265 eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. getBouquet failed!");
269 int prio_order = eDVBFrontend::getTypePriorityOrder();
271 eDVBChannelID chid, chid_ignore;
272 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
273 for (std::list<eServiceReference>::iterator it(bouquet->m_services.begin()); it != bouquet->m_services.end(); ++it)
275 static unsigned char prio_map[6][3] = {
276 { 3, 2, 1 }, // -S -C -T
277 { 3, 1, 2 }, // -S -T -C
278 { 2, 3, 1 }, // -C -S -T
279 { 1, 3, 2 }, // -C -T -S
280 { 1, 2, 3 }, // -T -C -S
281 { 2, 1, 3 } // -T -S -C
283 ((const eServiceReferenceDVB&)*it).getChannelID(chid);
284 int tmp=res->canAllocateChannel(chid, chid_ignore, simulate);
289 case 30000: // cached DVB-T channel
290 case 1: // DVB-T frontend
291 tmp = prio_map[prio_order][2];
293 case 40000: // cached DVB-C channel
295 tmp = prio_map[prio_order][1];
298 tmp = prio_map[prio_order][0];
303 m_playable_service = *it;
310 m_playable_service = eServiceReference();
314 int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
319 #include <lib/dvb/epgcache.h>
321 RESULT eStaticServiceDVBBouquetInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time)
323 return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr);
326 class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
328 DECLARE_REF(eStaticServiceDVBPVRInformation);
329 eServiceReference m_ref;
330 eDVBMetaParser m_parser;
332 eStaticServiceDVBPVRInformation(const eServiceReference &ref);
333 RESULT getName(const eServiceReference &ref, std::string &name);
334 int getLength(const eServiceReference &ref);
335 RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time);
336 int isPlayable(const eServiceReference &ref, const eServiceReference &ignore) { return 1; }
337 int getInfo(const eServiceReference &ref, int w);
338 std::string getInfoString(const eServiceReference &ref,int w);
341 DEFINE_REF(eStaticServiceDVBPVRInformation);
343 eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
346 m_parser.parseFile(ref.path);
349 RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
351 ASSERT(ref == m_ref);
352 if (m_parser.m_name.size())
353 name = m_parser.m_name;
357 size_t n = name.rfind('/');
358 if (n != std::string::npos)
359 name = name.substr(n + 1);
364 int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
366 ASSERT(ref == m_ref);
371 stat(ref.path.c_str(), &s);
373 if (tstools.openFile(ref.path.c_str(), 1))
376 /* check if cached data is still valid */
377 if (m_parser.m_data_ok && (s.st_size == m_parser.m_filesize) && (m_parser.m_length))
378 return m_parser.m_length / 90000;
380 /* open again, this time with stream info */
381 if (tstools.openFile(ref.path.c_str()))
384 /* otherwise, re-calc length and update meta file */
386 if (tstools.calcLen(len))
389 m_parser.m_length = len;
390 m_parser.m_filesize = s.st_size;
391 m_parser.updateMeta(ref.path);
392 return m_parser.m_length / 90000;
395 int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
399 case iServiceInformation::sDescription:
400 return iServiceInformation::resIsString;
401 case iServiceInformation::sServiceref:
402 return iServiceInformation::resIsString;
403 case iServiceInformation::sTimeCreate:
404 if (m_parser.m_time_create)
405 return m_parser.m_time_create;
407 return iServiceInformation::resNA;
409 return iServiceInformation::resNA;
413 std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
417 case iServiceInformation::sDescription:
418 return m_parser.m_description;
419 case iServiceInformation::sServiceref:
420 return m_parser.m_ref.toString();
421 case iServiceInformation::sTags:
422 return m_parser.m_tags;
428 RESULT eStaticServiceDVBPVRInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
430 if (!ref.path.empty())
432 ePtr<eServiceEvent> event = new eServiceEvent;
433 std::string filename = ref.path;
434 filename.erase(filename.length()-2, 2);
436 if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
446 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
448 DECLARE_REF(eDVBPVRServiceOfflineOperations);
449 eServiceReferenceDVB m_ref;
451 eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
453 RESULT deleteFromDisk(int simulate);
454 RESULT getListOfFilenames(std::list<std::string> &);
457 DEFINE_REF(eDVBPVRServiceOfflineOperations);
459 eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
463 RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
469 std::list<std::string> res;
470 if (getListOfFilenames(res))
473 eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
475 eDebug("FATAL !! can't get background file eraser");
477 for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
479 eDebug("Removing %s...", i->c_str());
481 eraser->erase(i->c_str());
483 ::unlink(i->c_str());
490 RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
493 res.push_back(m_ref.path);
495 // handling for old splitted recordings (enigma 1)
500 snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
502 if (stat(buf, &s) < 0)
507 res.push_back(m_ref.path + ".meta");
508 res.push_back(m_ref.path + ".ap");
509 res.push_back(m_ref.path + ".sc");
510 res.push_back(m_ref.path + ".cuts");
511 std::string tmp = m_ref.path;
512 tmp.erase(m_ref.path.length()-3);
513 res.push_back(tmp + ".eit");
517 DEFINE_REF(eServiceFactoryDVB)
519 eServiceFactoryDVB::eServiceFactoryDVB()
521 ePtr<eServiceCenter> sc;
523 eServiceCenter::getPrivInstance(sc);
526 std::list<std::string> extensions;
527 extensions.push_back("ts");
528 extensions.push_back("trp");
529 sc->addServiceFactory(eServiceFactoryDVB::id, this, extensions);
532 m_StaticServiceDVBInfo = new eStaticServiceDVBInformation;
533 m_StaticServiceDVBBouquetInfo = new eStaticServiceDVBBouquetInformation;
536 eServiceFactoryDVB::~eServiceFactoryDVB()
538 ePtr<eServiceCenter> sc;
540 eServiceCenter::getPrivInstance(sc);
542 sc->removeServiceFactory(eServiceFactoryDVB::id);
545 DEFINE_REF(eDVBServiceList);
547 eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
551 eDVBServiceList::~eDVBServiceList()
555 RESULT eDVBServiceList::startQuery()
557 ePtr<iDVBChannelList> db;
558 ePtr<eDVBResourceManager> res;
561 if ((err = eDVBResourceManager::getInstance(res)) != 0)
563 eDebug("no resource manager");
566 if ((err = res->getChannelList(db)) != 0)
568 eDebug("no channel list");
572 ePtr<eDVBChannelQuery> q;
574 if (!m_parent.path.empty())
576 eDVBChannelQuery::compile(q, m_parent.path);
579 eDebug("compile query failed");
584 if ((err = db->startQuery(m_query, q, m_parent)) != 0)
586 eDebug("startQuery failed");
593 RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
595 eServiceReferenceDVB ref;
600 while (!m_query->getNextResult(ref))
604 list.sort(iListableServiceCompare(this));
609 // The first argument of this function is a format string to specify the order and
610 // the content of the returned list
611 // useable format options are
612 // R = Service Reference (as swig object .. this is very slow)
613 // S = Service Reference (as python string object .. same as ref.toString())
614 // C = Service Reference (as python string object .. same as ref.toCompareString())
615 // N = Service Name (as python string object)
616 // n = Short Service Name (short name brakets used) (as python string object)
617 // when exactly one return value per service is selected in the format string,
618 // then each value is directly a list entry
619 // when more than one value is returned per service, then the list is a list of
621 // unknown format string chars are returned as python None values !
622 PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
625 std::list<eServiceReference> tmplist;
628 if (!format || !(retcount=strlen(format)))
629 format = "R"; // just return service reference swig object ...
631 if (!getContent(tmplist, sorted))
633 int services=tmplist.size();
634 ePtr<iStaticServiceInformation> sptr;
635 eServiceCenterPtr service_center;
637 if (strchr(format, 'N') || strchr(format, 'n'))
638 eServiceCenter::getPrivInstance(service_center);
640 ret = PyList_New(services);
641 std::list<eServiceReference>::iterator it(tmplist.begin());
643 for (int cnt=0; cnt < services; ++cnt)
645 eServiceReference &ref=*it++;
646 ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject();
647 for (int i=0; i < retcount; ++i)
652 case 'R': // service reference (swig)object
653 tmp = NEW_eServiceReference(ref);
655 case 'C': // service reference compare string
656 tmp = PyString_FromString(ref.toCompareString().c_str());
658 case 'S': // service reference string
659 tmp = PyString_FromString(ref.toString().c_str());
661 case 'N': // service name
664 service_center->info(ref, sptr);
668 sptr->getName(ref, name);
670 // filter short name brakets
672 while((pos = name.find("\xc2\x86")) != std::string::npos)
674 while((pos = name.find("\xc2\x87")) != std::string::npos)
678 tmp = PyString_FromString(name.c_str());
682 tmp = PyString_FromString("<n/a>");
684 case 'n': // short service name
687 service_center->info(ref, sptr);
691 sptr->getName(ref, name);
692 name = buildShortName(name);
694 tmp = PyString_FromString(name.c_str());
698 tmp = PyString_FromString("<n/a>");
711 PyTuple_SET_ITEM(tuple, i, tmp);
713 PyList_SET_ITEM(ret, cnt, tmp);
717 PyList_SET_ITEM(ret, cnt, tuple);
720 return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
723 RESULT eDVBServiceList::getNext(eServiceReference &ref)
728 return m_query->getNextResult((eServiceReferenceDVB&)ref);
731 RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
733 if (m_parent.flags & eServiceReference::canDescent) // bouquet
735 ePtr<iDVBChannelList> db;
736 ePtr<eDVBResourceManager> resm;
738 if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
741 if (db->getBouquet(m_parent, m_bouquet) != 0)
752 RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
756 return m_bouquet->addService(ref, before);
759 RESULT eDVBServiceList::removeService(eServiceReference &ref)
763 return m_bouquet->removeService(ref);
766 RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
770 return m_bouquet->moveService(ref, pos);
773 RESULT eDVBServiceList::flushChanges()
777 return m_bouquet->flushChanges();
780 RESULT eDVBServiceList::setListName(const std::string &name)
784 return m_bouquet->setListName(name);
787 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
789 ePtr<eDVBService> service;
790 int r = lookupService(service, ref);
793 // check resources...
794 ptr = new eDVBServicePlay(ref, service);
798 RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
800 if (ref.path.empty())
802 ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
811 RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
813 ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
814 if (list->startQuery())
824 RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
826 /* is a listable service? */
827 if (ref.flags & eServiceReference::canDescent) // bouquet
829 if ( !ref.name.empty() ) // satellites or providers list
830 ptr = m_StaticServiceDVBInfo;
831 else // a dvb bouquet
832 ptr = m_StaticServiceDVBBouquetInfo;
834 else if (!ref.path.empty()) /* do we have a PVR service? */
835 ptr = new eStaticServiceDVBPVRInformation(ref);
836 else // normal dvb service
838 ePtr<eDVBService> service;
839 if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
840 ptr = m_StaticServiceDVBInfo;
842 /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
848 RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
850 if (ref.path.empty())
856 ptr = new eDVBPVRServiceOfflineOperations(ref);
861 RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
863 if (!ref.path.empty()) // playback
865 eDVBMetaParser parser;
866 int ret=parser.parseFile(ref.path);
867 service = new eDVBService;
869 eDVBDB::getInstance()->parseServiceData(service, parser.m_service_data);
873 // TODO: handle the listing itself
874 // if (ref.... == -1) .. return "... bouquets ...";
875 // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
877 ePtr<iDVBChannelList> db;
878 ePtr<eDVBResourceManager> res;
881 if ((err = eDVBResourceManager::getInstance(res)) != 0)
883 eDebug("no resource manager");
886 if ((err = res->getChannelList(db)) != 0)
888 eDebug("no channel list");
892 /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
893 if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
895 eDebug("getService failed!");
903 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
904 m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
907 m_is_pvr = !m_reference.path.empty();
909 m_timeshift_enabled = m_timeshift_active = 0;
912 CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
913 CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
914 CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
916 m_cuesheet_changed = 0;
917 m_cutlist_enabled = 1;
919 m_subtitle_widget = 0;
923 m_subtitle_sync_timer = eTimer::create(eApp);
925 CONNECT(m_subtitle_sync_timer->timeout, eDVBServicePlay::checkSubtitleTiming);
928 eDVBServicePlay::~eDVBServicePlay()
933 int ret=meta.parseFile(m_reference.path);
937 meta.m_service_data="";
938 sprintf(tmp, "f:%x", m_dvb_service->m_flags);
939 meta.m_service_data += tmp;
941 for (int x=0; x < eDVBService::cacheMax; ++x)
943 int entry = m_dvb_service->getCacheEntry((eDVBService::cacheID)x);
946 sprintf(tmp, ",c:%02d%04x", x, entry);
947 meta.m_service_data += tmp;
950 meta.updateMeta(m_reference.path);
953 delete m_subtitle_widget;
956 void eDVBServicePlay::gotNewEvent()
960 ePtr<eServiceEvent> m_event_now, m_event_next;
961 getEvent(m_event_now, 0);
962 getEvent(m_event_next, 1);
965 eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
967 eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
969 m_event((iPlayableService*)this, evUpdatedEventInfo);
972 void eDVBServicePlay::serviceEvent(int event)
974 m_tune_state = event;
978 case eDVBServicePMTHandler::eventTuned:
980 ePtr<iDVBDemux> m_demux;
981 if (!m_service_handler.getDataDemux(m_demux))
983 eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
984 int sid = ref.getParentServiceID().get();
986 sid = ref.getServiceID().get();
987 if ( ref.getParentTransportStreamID().get() &&
988 ref.getParentTransportStreamID() != ref.getTransportStreamID() )
989 m_event_handler.startOther(m_demux, sid);
991 m_event_handler.start(m_demux, sid);
993 m_event((iPlayableService*)this, evTunedIn);
996 case eDVBServicePMTHandler::eventNoResources:
997 case eDVBServicePMTHandler::eventNoPAT:
998 case eDVBServicePMTHandler::eventNoPATEntry:
999 case eDVBServicePMTHandler::eventNoPMT:
1000 case eDVBServicePMTHandler::eventTuneFailed:
1001 case eDVBServicePMTHandler::eventMisconfiguration:
1003 eDebug("DVB service failed to tune - error %d", event);
1004 m_event((iPlayableService*)this, evTuneFailed);
1007 case eDVBServicePMTHandler::eventNewProgramInfo:
1009 eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
1010 if (m_timeshift_enabled)
1011 updateTimeshiftPids();
1012 if (!m_timeshift_active)
1014 if (m_first_program_info && m_is_pvr)
1016 m_first_program_info = 0;
1019 m_event((iPlayableService*)this, evUpdatedInfo);
1022 case eDVBServicePMTHandler::eventEOF:
1023 m_event((iPlayableService*)this, evEOF);
1025 case eDVBServicePMTHandler::eventSOF:
1026 m_event((iPlayableService*)this, evSOF);
1031 void eDVBServicePlay::serviceEventTimeshift(int event)
1035 case eDVBServicePMTHandler::eventNewProgramInfo:
1036 if (m_timeshift_active)
1039 case eDVBServicePMTHandler::eventSOF:
1040 m_event((iPlayableService*)this, evSOF);
1042 case eDVBServicePMTHandler::eventEOF:
1043 if ((!m_is_paused) && (m_skipmode >= 0))
1045 eDebug("timeshift EOF, so let's go live");
1052 RESULT eDVBServicePlay::start()
1055 /* in pvr mode, we only want to use one demux. in tv mode, we're using
1056 two (one for decoding, one for data source), as we must be prepared
1057 to start recording from the data demux. */
1059 m_cue = new eCueSheet();
1061 m_event(this, evStart);
1063 m_first_program_info = 1;
1064 eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
1065 r = m_service_handler.tune(service, m_is_pvr, m_cue, false, m_dvb_service);
1067 /* inject EIT if there is a stored one */
1070 std::string filename = service.path;
1071 filename.erase(filename.length()-2, 2);
1073 ePtr<eServiceEvent> event = new eServiceEvent;
1074 if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
1076 ePtr<eServiceEvent> empty;
1077 m_event_handler.inject(event, 0);
1078 m_event_handler.inject(empty, 1);
1085 m_event(this, evStart);
1090 RESULT eDVBServicePlay::stop()
1092 /* add bookmark for last play position */
1095 pts_t play_position, length;
1096 if (!getPlayPosition(play_position))
1098 /* remove last position */
1099 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
1101 if (i->what == 3) /* current play position */
1103 m_cue_entries.erase(i);
1104 i = m_cue_entries.begin();
1110 if (getLength(length))
1115 int perc = play_position * 100LL / length;
1117 /* only store last play position when between 1% and 99% */
1118 if ((1 < perc) && (perc < 99))
1119 m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
1121 m_cuesheet_changed = 1;
1125 stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
1127 m_service_handler_timeshift.free();
1128 m_service_handler.free();
1130 if (m_is_pvr && m_cuesheet_changed)
1133 /* save cuesheet only when main file is accessible. */
1134 if (!::stat(m_reference.path.c_str(), &s))
1137 m_event((iPlayableService*)this, evStopped);
1141 RESULT eDVBServicePlay::setTarget(int target)
1143 m_is_primary = !target;
1147 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
1149 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
1153 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
1155 /* note: we check for timeshift to be enabled,
1156 not neccessary active. if you pause when timeshift
1157 is not active, you should activate it when unpausing */
1158 if ((!m_is_pvr) && (!m_timeshift_enabled))
1168 RESULT eDVBServicePlay::setSlowMotion(int ratio)
1170 ASSERT(ratio); /* The API changed: instead of calling setSlowMotion(0), call play! */
1171 eDebug("eDVBServicePlay::setSlowMotion(%d)", ratio);
1172 setFastForward_internal(0);
1174 return m_decoder->setSlowMotion(ratio);
1179 RESULT eDVBServicePlay::setFastForward(int ratio)
1181 eDebug("eDVBServicePlay::setFastForward(%d)", ratio);
1183 return setFastForward_internal(ratio);
1186 RESULT eDVBServicePlay::setFastForward_internal(int ratio)
1188 int skipmode, ffratio;
1194 } else if (ratio > 0)
1202 } else // if (ratio < 0)
1208 if (m_skipmode != skipmode)
1210 eDebug("setting cue skipmode to %d", skipmode);
1212 m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
1215 m_skipmode = skipmode;
1221 ; /* return m_decoder->play(); is done in caller*/
1222 else if (ffratio != 1)
1223 return m_decoder->setFastForward(ffratio);
1225 return m_decoder->setTrickmode();
1228 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
1230 if (m_is_pvr || m_timeshift_enabled)
1240 /* TODO: when timeshift is enabled but not active, this doesn't work. */
1241 RESULT eDVBServicePlay::getLength(pts_t &len)
1243 ePtr<iDVBPVRChannel> pvr_channel;
1245 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1248 return pvr_channel->getLength(len);
1251 RESULT eDVBServicePlay::pause()
1253 eDebug("eDVBServicePlay::pause");
1254 setFastForward_internal(0);
1258 return m_decoder->pause();
1263 RESULT eDVBServicePlay::unpause()
1265 eDebug("eDVBServicePlay::unpause");
1266 setFastForward_internal(0);
1270 return m_decoder->play();
1275 RESULT eDVBServicePlay::seekTo(pts_t to)
1277 eDebug("eDVBServicePlay::seekTo: jump %lld", to);
1279 if (!m_decode_demux)
1282 ePtr<iDVBPVRChannel> pvr_channel;
1284 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1290 m_cue->seekTo(0, to);
1291 m_dvb_subtitle_pages.clear();
1292 m_subtitle_pages.clear();
1297 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
1299 eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
1301 if (!m_decode_demux)
1304 ePtr<iDVBPVRChannel> pvr_channel;
1306 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1311 /* HACK until we have skip-AP api */
1312 if ((to > 0) && (to < 100))
1320 m_cue->seekTo(mode, to);
1321 m_dvb_subtitle_pages.clear();
1322 m_subtitle_pages.clear();
1326 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
1328 ePtr<iDVBPVRChannel> pvr_channel;
1330 if (!m_decode_demux)
1333 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1338 /* if there is a decoder, use audio or video PTS */
1341 r = m_decoder->getPTS(0, pos);
1347 return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder ? 1 : 0);
1350 RESULT eDVBServicePlay::setTrickmode(int trick)
1352 /* currently unimplemented */
1356 RESULT eDVBServicePlay::isCurrentlySeekable()
1358 return m_is_pvr || m_timeshift_active;
1361 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1367 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1373 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1379 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1385 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1391 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1394 if (m_have_video_pid && // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
1395 (m_timeshift_enabled || !m_is_pvr))
1397 if (!m_timeshift_enabled)
1399 /* query config path */
1401 if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
1402 eDebug("could not query ts path from config");
1406 /* we need enough diskspace */
1408 if (statfs(tspath.c_str(), &fs) < 0)
1410 eDebug("statfs failed!");
1414 if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
1416 eDebug("not enough diskspace for timeshift! (less than 1GB)");
1426 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1437 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1443 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1449 RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
1455 RESULT eDVBServicePlay::getName(std::string &name)
1459 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1460 return i->getName(m_reference, name);
1462 else if (m_dvb_service)
1464 m_dvb_service->getName(m_reference, name);
1468 else if (!m_reference.name.empty())
1469 eStaticServiceDVBInformation().getName(m_reference, name);
1471 name = "DVB service";
1475 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1477 return m_event_handler.getEvent(evt, nownext);
1480 int eDVBServicePlay::getInfo(int w)
1482 eDVBServicePMTHandler::program program;
1485 return resIsPyObject;
1487 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1489 int no_program_info = 0;
1491 if (h.getProgramInfo(program))
1492 no_program_info = 1;
1498 return m_decoder->getVideoHeight();
1502 return m_decoder->getVideoWidth();
1506 return m_decoder->getVideoFrameRate();
1510 return m_decoder->getVideoProgressive();
1516 aspect = m_decoder->getVideoAspect();
1517 if (no_program_info)
1519 else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1521 ePtr<eServiceEvent> evt;
1522 if (!m_event_handler.getEvent(evt, 0))
1524 ePtr<eComponentData> data;
1525 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1527 if ( data->getStreamContent() == 1 )
1529 switch(data->getComponentType())
1532 case 1: // 4:3 SD PAL
1534 case 3: // 16:9 SD PAL
1535 case 4: // > 16:9 PAL
1536 case 5: // 4:3 SD NTSC
1538 case 7: // 16:9 SD NTSC
1539 case 8: // > 16:9 NTSC
1542 case 9: // 4:3 HD PAL
1544 case 0xB: // 16:9 HD PAL
1545 case 0xC: // > 16:9 HD PAL
1546 case 0xD: // 4:3 HD NTSC
1548 case 0xF: // 16:9 HD NTSC
1549 case 0x10: // > 16:9 HD PAL
1550 return data->getComponentType();
1560 case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
1564 int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
1568 if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1569 case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1573 int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
1576 apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
1580 if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1584 int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
1588 if (no_program_info) return -1; return program.pcrPid;
1589 case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
1590 case sTXTPID: if (no_program_info) return -1; return program.textPid;
1591 case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1592 case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1593 case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1594 case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1595 case sProvider: if (!m_dvb_service) return -1; return -2;
1596 case sServiceref: return resIsString;
1597 case sDVBState: return m_tune_state;
1604 std::string eDVBServicePlay::getInfoString(int w)
1609 if (!m_dvb_service) return "";
1610 return m_dvb_service->m_provider_name;
1612 return m_reference.toString();
1616 return iServiceInformation::getInfoString(w);
1619 PyObject *eDVBServicePlay::getInfoObject(int w)
1624 return m_service_handler.getCaIds();
1625 case sTransponderData:
1626 return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
1630 return iServiceInformation::getInfoObject(w);
1633 int eDVBServicePlay::getNumberOfTracks()
1635 eDVBServicePMTHandler::program program;
1636 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1637 if (h.getProgramInfo(program))
1639 return program.audioStreams.size();
1642 int eDVBServicePlay::getCurrentTrack()
1644 eDVBServicePMTHandler::program program;
1645 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1646 if (h.getProgramInfo(program))
1649 int max = program.audioStreams.size();
1652 for (i = 0; i < max; ++i)
1653 if (program.audioStreams[i].pid == m_current_audio_pid)
1659 RESULT eDVBServicePlay::selectTrack(unsigned int i)
1661 int ret = selectAudioStream(i);
1663 if (m_decoder->set())
1669 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
1671 eDVBServicePMTHandler::program program;
1672 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1674 if (h.getProgramInfo(program))
1677 if (i >= program.audioStreams.size())
1680 info.m_pid = program.audioStreams[i].pid;
1682 if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
1683 info.m_description = "MPEG";
1684 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
1685 info.m_description = "AC3";
1686 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
1687 info.m_description = "AAC";
1688 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
1689 info.m_description = "AAC-HE";
1690 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
1691 info.m_description = "DTS";
1693 info.m_description = "???";
1695 if (program.audioStreams[i].component_tag != -1)
1697 ePtr<eServiceEvent> evt;
1698 if (!m_event_handler.getEvent(evt, 0))
1700 ePtr<eComponentData> data;
1701 if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
1702 info.m_language = data->getText();
1706 if (info.m_language.empty())
1707 info.m_language = program.audioStreams[i].language_code;
1712 int eDVBServicePlay::selectAudioStream(int i)
1714 eDVBServicePMTHandler::program program;
1715 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1717 if (h.getProgramInfo(program))
1720 if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
1728 stream = program.defaultAudioStream;
1730 int apid = -1, apidtype = -1;
1732 if (((unsigned int)stream) < program.audioStreams.size())
1734 apid = program.audioStreams[stream].pid;
1735 apidtype = program.audioStreams[stream].type;
1738 m_current_audio_pid = apid;
1740 if (m_is_primary && m_decoder->setAudioPID(apid, apidtype))
1742 eDebug("set audio pid failed");
1746 /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
1747 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
1750 ePtr<iDVBDemux> data_demux;
1751 if (!h.getDataDemux(data_demux))
1753 m_rds_decoder = new eDVBRdsDecoder(data_demux);
1754 m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
1758 /* if we decided that we need one, update the pid */
1760 m_rds_decoder->start(apid);
1762 /* store new pid as default only when:
1763 a.) we have an entry in the service db for the current service,
1764 b.) we are not playing back something,
1765 c.) we are not selecting the default entry. (we wouldn't change
1766 anything in the best case, or destroy the default setting in
1767 case the real default is not yet available.)
1769 if (m_dvb_service && ((i != -1)
1770 || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
1772 if (apidtype == eDVBAudio::aMPEG)
1774 m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
1775 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1777 else if (apidtype == eDVBAudio::aAC3)
1779 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1780 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
1784 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1785 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1789 h.resetCachedProgram();
1794 int eDVBServicePlay::getCurrentChannel()
1796 return m_decoder ? m_decoder->getAudioChannel() : STEREO;
1799 RESULT eDVBServicePlay::selectChannel(int i)
1801 if (i < LEFT || i > RIGHT || i == STEREO)
1804 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
1806 m_decoder->setAudioChannel(i);
1810 std::string eDVBServicePlay::getText(int x)
1816 return convertLatin1UTF8(m_rds_decoder->getRadioText());
1818 return convertLatin1UTF8(m_rds_decoder->getRtpText());
1823 void eDVBServicePlay::rdsDecoderEvent(int what)
1827 case eDVBRdsDecoder::RadioTextChanged:
1828 m_event((iPlayableService*)this, evUpdatedRadioText);
1830 case eDVBRdsDecoder::RtpTextChanged:
1831 m_event((iPlayableService*)this, evUpdatedRtpText);
1833 case eDVBRdsDecoder::RassInteractivePicMaskChanged:
1834 m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
1836 case eDVBRdsDecoder::RecvRassSlidePic:
1837 m_event((iPlayableService*)this, evUpdatedRassSlidePic);
1842 void eDVBServicePlay::showRassSlidePicture()
1848 std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
1849 if (rass_slide_pic.length())
1850 m_decoder->showSinglePic(rass_slide_pic.c_str());
1852 eDebug("empty filename for rass slide picture received!!");
1855 eDebug("no MPEG Decoder to show iframes avail");
1858 eDebug("showRassSlidePicture called.. but not decoder");
1861 void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
1867 std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
1868 if (rass_interactive_pic.length())
1869 m_decoder->showSinglePic(rass_interactive_pic.c_str());
1871 eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
1874 eDebug("no MPEG Decoder to show iframes avail");
1877 eDebug("showRassInteractivePic called.. but not decoder");
1880 ePyObject eDVBServicePlay::getRassInteractiveMask()
1883 return m_rds_decoder->getRassPictureMask();
1887 int eDVBServiceBase::getFrontendInfo(int w)
1889 eUsePtr<iDVBChannel> channel;
1890 if(m_service_handler.getChannel(channel))
1892 ePtr<iDVBFrontend> fe;
1893 if(channel->getFrontend(fe))
1895 return fe->readFrontendData(w);
1898 PyObject *eDVBServiceBase::getFrontendData()
1900 ePyObject ret = PyDict_New();
1903 eUsePtr<iDVBChannel> channel;
1904 if(!m_service_handler.getChannel(channel))
1906 ePtr<iDVBFrontend> fe;
1907 if(!channel->getFrontend(fe))
1908 fe->getFrontendData(ret);
1916 PyObject *eDVBServiceBase::getFrontendStatus()
1918 ePyObject ret = PyDict_New();
1921 eUsePtr<iDVBChannel> channel;
1922 if(!m_service_handler.getChannel(channel))
1924 ePtr<iDVBFrontend> fe;
1925 if(!channel->getFrontend(fe))
1926 fe->getFrontendStatus(ret);
1934 PyObject *eDVBServiceBase::getTransponderData(bool original)
1936 ePyObject ret = PyDict_New();
1939 eUsePtr<iDVBChannel> channel;
1940 if(!m_service_handler.getChannel(channel))
1942 ePtr<iDVBFrontend> fe;
1943 if(!channel->getFrontend(fe))
1944 fe->getTransponderData(ret, original);
1952 PyObject *eDVBServiceBase::getAll(bool original)
1954 ePyObject ret = getTransponderData(original);
1957 eUsePtr<iDVBChannel> channel;
1958 if(!m_service_handler.getChannel(channel))
1960 ePtr<iDVBFrontend> fe;
1961 if(!channel->getFrontend(fe))
1963 fe->getFrontendData(ret);
1964 fe->getFrontendStatus(ret);
1971 int eDVBServicePlay::getNumberOfSubservices()
1973 ePtr<eServiceEvent> evt;
1974 if (!m_event_handler.getEvent(evt, 0))
1975 return evt->getNumOfLinkageServices();
1979 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
1981 ePtr<eServiceEvent> evt;
1982 if (!m_event_handler.getEvent(evt, 0))
1984 if (!evt->getLinkageService(sub, m_reference, n))
1987 sub.type=eServiceReference::idInvalid;
1991 RESULT eDVBServicePlay::startTimeshift()
1993 ePtr<iDVBDemux> demux;
1995 eDebug("Start timeshift!");
1997 if (m_timeshift_enabled)
2000 /* start recording with the data demux. */
2001 if (m_service_handler.getDataDemux(demux))
2004 demux->createTSRecorder(m_record);
2009 if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
2010 eDebug("could not query ts path");
2013 tspath.append("/timeshift.XXXXXX");
2015 templ = new char[tspath.length() + 1];
2016 strcpy(templ, tspath.c_str());
2018 m_timeshift_fd = mkstemp(templ);
2019 m_timeshift_file = std::string(templ);
2021 eDebug("recording to %s", templ);
2025 if (m_timeshift_fd < 0)
2031 m_record->setTargetFD(m_timeshift_fd);
2033 m_timeshift_enabled = 1;
2035 updateTimeshiftPids();
2041 RESULT eDVBServicePlay::stopTimeshift()
2043 if (!m_timeshift_enabled)
2048 m_timeshift_enabled = 0;
2053 close(m_timeshift_fd);
2054 eDebug("remove timeshift file");
2055 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
2060 int eDVBServicePlay::isTimeshiftActive()
2062 return m_timeshift_enabled && m_timeshift_active;
2065 RESULT eDVBServicePlay::activateTimeshift()
2067 if (!m_timeshift_enabled)
2070 if (!m_timeshift_active)
2072 switchToTimeshift();
2079 PyObject *eDVBServicePlay::getCutList()
2081 ePyObject list = PyList_New(0);
2083 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2085 ePyObject tuple = PyTuple_New(2);
2086 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
2087 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
2088 PyList_Append(list, tuple);
2095 void eDVBServicePlay::setCutList(ePyObject list)
2097 if (!PyList_Check(list))
2099 int size = PyList_Size(list);
2102 m_cue_entries.clear();
2104 for (i=0; i<size; ++i)
2106 ePyObject tuple = PyList_GET_ITEM(list, i);
2107 if (!PyTuple_Check(tuple))
2109 eDebug("non-tuple in cutlist");
2112 if (PyTuple_Size(tuple) != 2)
2114 eDebug("cutlist entries need to be a 2-tuple");
2117 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
2118 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
2120 eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
2123 pts_t pts = PyLong_AsLongLong(ppts);
2124 int type = PyInt_AsLong(ptype);
2125 m_cue_entries.insert(cueEntry(pts, type));
2126 eDebug("adding %08llx, %d", pts, type);
2128 m_cuesheet_changed = 1;
2130 cutlistToCuesheet();
2131 m_event((iPlayableService*)this, evCuesheetChanged);
2134 void eDVBServicePlay::setCutListEnable(int enable)
2136 m_cutlist_enabled = enable;
2137 cutlistToCuesheet();
2140 void eDVBServicePlay::updateTimeshiftPids()
2145 eDVBServicePMTHandler::program program;
2146 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2148 if (h.getProgramInfo(program))
2152 std::set<int> pids_to_record;
2153 pids_to_record.insert(0); // PAT
2154 if (program.pmtPid != -1)
2155 pids_to_record.insert(program.pmtPid); // PMT
2157 if (program.textPid != -1)
2158 pids_to_record.insert(program.textPid); // Videotext
2160 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2161 i(program.videoStreams.begin());
2162 i != program.videoStreams.end(); ++i)
2163 pids_to_record.insert(i->pid);
2165 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2166 i(program.audioStreams.begin());
2167 i != program.audioStreams.end(); ++i)
2168 pids_to_record.insert(i->pid);
2170 for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
2171 i(program.subtitleStreams.begin());
2172 i != program.subtitleStreams.end(); ++i)
2173 pids_to_record.insert(i->pid);
2175 std::set<int> new_pids, obsolete_pids;
2177 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
2178 m_pids_active.begin(), m_pids_active.end(),
2179 std::inserter(new_pids, new_pids.begin()));
2181 std::set_difference(
2182 m_pids_active.begin(), m_pids_active.end(),
2183 pids_to_record.begin(), pids_to_record.end(),
2184 std::inserter(new_pids, new_pids.begin())
2187 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
2188 m_record->addPID(*i);
2190 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
2191 m_record->removePID(*i);
2195 void eDVBServicePlay::switchToLive()
2197 if (!m_timeshift_active)
2200 eDebug("SwitchToLive");
2205 m_teletext_parser = 0;
2207 m_subtitle_parser = 0;
2208 m_new_dvb_subtitle_page_connection = 0;
2209 m_new_subtitle_page_connection = 0;
2210 m_rds_decoder_event_connection = 0;
2211 m_video_event_connection = 0;
2213 /* free the timeshift service handler, we need the resources */
2214 m_service_handler_timeshift.free();
2215 m_timeshift_active = 0;
2217 m_event((iPlayableService*)this, evSeekableStatusChanged);
2222 void eDVBServicePlay::switchToTimeshift()
2224 if (m_timeshift_active)
2229 m_teletext_parser = 0;
2231 m_subtitle_parser = 0;
2232 m_new_subtitle_page_connection = 0;
2233 m_new_dvb_subtitle_page_connection = 0;
2234 m_rds_decoder_event_connection = 0;
2235 m_video_event_connection = 0;
2237 m_timeshift_active = 1;
2239 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2240 r.path = m_timeshift_file;
2242 m_cue = new eCueSheet();
2243 m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
2245 eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
2247 updateDecoder(); /* mainly to switch off PCR, and to set pause */
2249 m_event((iPlayableService*)this, evSeekableStatusChanged);
2252 void eDVBServicePlay::updateDecoder()
2254 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2256 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2258 eDVBServicePMTHandler::program program;
2259 if (h.getProgramInfo(program))
2260 eDebug("getting program info failed.");
2263 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
2264 if (!program.videoStreams.empty())
2266 eDebugNoNewLine(" (");
2267 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2268 i(program.videoStreams.begin());
2269 i != program.videoStreams.end(); ++i)
2276 if (i != program.videoStreams.begin())
2277 eDebugNoNewLine(", ");
2278 eDebugNoNewLine("%04x", i->pid);
2280 eDebugNoNewLine(")");
2282 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
2283 if (!program.audioStreams.empty())
2285 eDebugNoNewLine(" (");
2286 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2287 i(program.audioStreams.begin());
2288 i != program.audioStreams.end(); ++i)
2290 if (i != program.audioStreams.begin())
2291 eDebugNoNewLine(", ");
2292 eDebugNoNewLine("%04x", i->pid);
2294 eDebugNoNewLine(")");
2296 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2297 pcrpid = program.pcrPid;
2298 eDebug(", and the text pid is %04x", program.textPid);
2299 tpid = program.textPid;
2304 h.getDecodeDemux(m_decode_demux);
2307 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
2309 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2311 if (m_decode_demux && m_is_primary)
2313 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2314 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2315 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2316 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2319 m_teletext_parser = 0;
2320 m_subtitle_parser = 0;
2324 m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2331 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2332 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2333 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2337 eServiceReferenceDVB ref;
2338 m_service_handler.getServiceReference(ref);
2339 eServiceReferenceDVB parent = ref.getParentServiceReference();
2344 ePtr<eDVBResourceManager> res_mgr;
2345 if (!eDVBResourceManager::getInstance(res_mgr))
2347 ePtr<iDVBChannelList> db;
2348 if (!res_mgr->getChannelList(db))
2350 ePtr<eDVBService> origService;
2351 if (!db->getService(parent, origService))
2353 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2354 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2361 std::string config_delay;
2362 int config_delay_int = 0;
2363 if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
2364 config_delay_int = atoi(config_delay.c_str());
2365 m_decoder->setAC3Delay(ac3_delay == -1 ? config_delay_int : ac3_delay + config_delay_int);
2367 if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
2368 config_delay_int = atoi(config_delay.c_str());
2370 config_delay_int = 0;
2371 m_decoder->setPCMDelay(pcm_delay == -1 ? config_delay_int : pcm_delay + config_delay_int);
2373 m_decoder->setVideoPID(vpid, vpidtype);
2374 selectAudioStream();
2376 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
2377 m_decoder->setSyncPCR(pcrpid);
2379 m_decoder->setSyncPCR(-1);
2383 m_decoder->setTextPID(tpid);
2384 m_teletext_parser->start(program.textPid);
2387 if (vpid > 0 && vpid < 0x2000)
2391 std::string radio_pic;
2392 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
2393 m_decoder->setRadioPic(radio_pic);
2396 /* if (!m_is_primary)
2397 m_decoder->setTrickmode();
2398 else */ if (m_is_paused)
2403 m_decoder->setAudioChannel(achannel);
2405 /* don't worry about non-existing services, nor pvr services */
2408 /* (audio pid will be set in selectAudioTrack */
2409 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2410 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2411 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2412 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2415 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2418 void eDVBServicePlay::loadCuesheet()
2420 std::string filename = m_reference.path + ".cuts";
2422 m_cue_entries.clear();
2424 FILE *f = fopen(filename.c_str(), "rb");
2428 eDebug("loading cuts..");
2431 unsigned long long where;
2434 if (!fread(&where, sizeof(where), 1, f))
2436 if (!fread(&what, sizeof(what), 1, f))
2439 #if BYTE_ORDER == LITTLE_ENDIAN
2440 where = bswap_64(where);
2447 m_cue_entries.insert(cueEntry(where, what));
2450 eDebug("%d entries", m_cue_entries.size());
2452 eDebug("cutfile not found!");
2454 m_cuesheet_changed = 0;
2455 cutlistToCuesheet();
2456 m_event((iPlayableService*)this, evCuesheetChanged);
2459 void eDVBServicePlay::saveCuesheet()
2461 std::string filename = m_reference.path + ".cuts";
2463 FILE *f = fopen(filename.c_str(), "wb");
2467 unsigned long long where;
2470 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2472 #if BYTE_ORDER == BIG_ENDIAN
2475 where = bswap_64(i->where);
2477 what = htonl(i->what);
2478 fwrite(&where, sizeof(where), 1, f);
2479 fwrite(&what, sizeof(what), 1, f);
2485 m_cuesheet_changed = 0;
2488 void eDVBServicePlay::cutlistToCuesheet()
2492 eDebug("no cue sheet");
2497 if (!m_cutlist_enabled)
2499 m_cue->commitSpans();
2500 eDebug("cutlists were disabled");
2504 pts_t in = 0, out = 0, length = 0;
2508 std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
2510 int have_any_span = 0;
2514 if (i == m_cue_entries.end())
2520 if (i->what == 0) /* in */
2524 } else if (i->what == 1) /* out */
2526 else /* mark (2) or last play position (3) */
2545 m_cue->addSourceSpan(in, out);
2550 if (i == m_cue_entries.end())
2553 m_cue->commitSpans();
2556 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
2558 if (m_subtitle_widget)
2559 disableSubtitles(parent);
2562 int tuplesize = PyTuple_Size(tuple);
2565 if (!PyTuple_Check(tuple))
2571 entry = PyTuple_GET_ITEM(tuple, 0);
2573 if (!PyInt_Check(entry))
2576 type = PyInt_AsLong(entry);
2578 if (type == 1) // teletext subtitles
2580 int page, magazine, pid;
2584 if (!m_teletext_parser)
2586 eDebug("enable teletext subtitles.. no parser !!!");
2590 entry = PyTuple_GET_ITEM(tuple, 1);
2591 if (!PyInt_Check(entry))
2593 pid = PyInt_AsLong(entry);
2595 entry = PyTuple_GET_ITEM(tuple, 2);
2596 if (!PyInt_Check(entry))
2598 page = PyInt_AsLong(entry);
2600 entry = PyTuple_GET_ITEM(tuple, 3);
2601 if (!PyInt_Check(entry))
2603 magazine = PyInt_AsLong(entry);
2605 m_subtitle_widget = new eSubtitleWidget(parent);
2606 m_subtitle_widget->resize(parent->size()); /* full size */
2607 m_teletext_parser->setPageAndMagazine(page, magazine);
2609 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
2613 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
2614 if (!m_subtitle_parser)
2616 eDebug("enable dvb subtitles.. no parser !!!");
2622 entry = PyTuple_GET_ITEM(tuple, 1);
2623 if (!PyInt_Check(entry))
2625 pid = PyInt_AsLong(entry);
2627 entry = PyTuple_GET_ITEM(tuple, 2);
2628 if (!PyInt_Check(entry))
2630 composition_page_id = PyInt_AsLong(entry);
2632 entry = PyTuple_GET_ITEM(tuple, 3);
2633 if (!PyInt_Check(entry))
2635 ancillary_page_id = PyInt_AsLong(entry);
2637 m_subtitle_widget = new eSubtitleWidget(parent);
2638 m_subtitle_widget->resize(parent->size()); /* full size */
2639 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
2641 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
2647 eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
2648 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
2649 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
2653 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
2655 delete m_subtitle_widget;
2656 m_subtitle_widget = 0;
2657 if (m_subtitle_parser)
2659 m_subtitle_parser->stop();
2660 m_dvb_subtitle_pages.clear();
2662 if (m_teletext_parser)
2664 m_teletext_parser->setPageAndMagazine(-1, -1);
2665 m_subtitle_pages.clear();
2668 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
2672 PyObject *eDVBServicePlay::getCachedSubtitle()
2676 int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
2679 unsigned int data = (unsigned int)tmp;
2680 int pid = (data&0xFFFF0000)>>16;
2681 ePyObject tuple = PyTuple_New(4);
2682 eDVBServicePMTHandler::program program;
2683 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2684 if (!h.getProgramInfo(program))
2686 if (program.textPid==pid) // teletext
2687 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
2689 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
2690 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
2691 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
2692 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
2700 PyObject *eDVBServicePlay::getSubtitleList()
2702 if (!m_teletext_parser)
2705 ePyObject l = PyList_New(0);
2706 std::set<int> added_ttx_pages;
2708 std::set<eDVBServicePMTHandler::subtitleStream> &subs =
2709 m_teletext_parser->m_found_subtitle_pages;
2711 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2712 eDVBServicePMTHandler::program program;
2713 if (h.getProgramInfo(program))
2714 eDebug("getting program info failed.");
2717 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
2718 it != program.subtitleStreams.end(); ++it)
2720 switch(it->subtitling_type)
2722 case 0x01: // ebu teletext subtitles
2724 int page_number = it->teletext_page_number & 0xFF;
2725 int magazine_number = it->teletext_magazine_number & 7;
2726 int hash = magazine_number << 8 | page_number;
2727 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2729 ePyObject tuple = PyTuple_New(5);
2730 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2731 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2732 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2733 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2734 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2735 PyList_Append(l, tuple);
2737 added_ttx_pages.insert(hash);
2742 case 0x20 ... 0x23: // dvb subtitles
2744 ePyObject tuple = PyTuple_New(5);
2745 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
2746 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2747 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
2748 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
2749 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2750 PyList_Insert(l, 0, tuple);
2758 for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
2759 it != subs.end(); ++it)
2761 int page_number = it->teletext_page_number & 0xFF;
2762 int magazine_number = it->teletext_magazine_number & 7;
2763 int hash = magazine_number << 8 | page_number;
2764 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2766 ePyObject tuple = PyTuple_New(5);
2767 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2768 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2769 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2770 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2771 PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
2772 PyList_Append(l, tuple);
2780 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
2782 if (m_subtitle_widget)
2786 m_decoder->getPTS(0, pos);
2787 eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
2788 m_subtitle_pages.push_back(page);
2789 checkSubtitleTiming();
2793 void eDVBServicePlay::checkSubtitleTiming()
2795 eDebug("checkSubtitleTiming");
2796 if (!m_subtitle_widget)
2800 enum { TELETEXT, DVB } type;
2801 eDVBTeletextSubtitlePage page;
2802 eDVBSubtitlePage dvb_page;
2804 if (!m_subtitle_pages.empty())
2806 page = m_subtitle_pages.front();
2808 show_time = page.m_pts;
2810 else if (!m_dvb_subtitle_pages.empty())
2812 dvb_page = m_dvb_subtitle_pages.front();
2814 show_time = dvb_page.m_show_time;
2822 m_decoder->getPTS(0, pos);
2824 eDebug("%lld %lld", pos, show_time);
2825 int diff = show_time - pos;
2828 eDebug("[late (%d ms)]", -diff / 90);
2831 // if (diff > 900000)
2833 // eDebug("[invalid]");
2839 if (type == TELETEXT)
2841 eDebug("display teletext subtitle page %lld", show_time);
2842 m_subtitle_widget->setPage(page);
2843 m_subtitle_pages.pop_front();
2847 eDebug("display dvb subtitle Page %lld", show_time);
2848 m_subtitle_widget->setPage(dvb_page);
2849 m_dvb_subtitle_pages.pop_front();
2853 eDebug("start subtitle delay %d", diff / 90);
2854 m_subtitle_sync_timer->start(diff / 90, 1);
2860 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
2862 if (m_subtitle_widget)
2866 m_decoder->getPTS(0, pos);
2867 eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
2868 m_dvb_subtitle_pages.push_back(p);
2869 checkSubtitleTiming();
2873 int eDVBServicePlay::getAC3Delay()
2876 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2878 return m_decoder->getAC3Delay();
2883 int eDVBServicePlay::getPCMDelay()
2886 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2888 return m_decoder->getPCMDelay();
2893 void eDVBServicePlay::setAC3Delay(int delay)
2896 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2898 m_decoder->setAC3Delay(delay);
2901 void eDVBServicePlay::setPCMDelay(int delay)
2904 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2906 m_decoder->setPCMDelay(delay);
2909 void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
2911 switch(event.type) {
2912 case iTSMPEGDecoder::videoEvent::eventSizeChanged:
2913 m_event((iPlayableService*)this, evVideoSizeChanged);
2915 case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
2916 m_event((iPlayableService*)this, evVideoFramerateChanged);
2918 case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
2919 m_event((iPlayableService*)this, evVideoProgressiveChanged);
2926 RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
2932 PyObject *eDVBServicePlay::getStreamingData()
2934 eDVBServicePMTHandler::program program;
2935 if (m_service_handler.getProgramInfo(program))
2940 ePyObject r = program.createPythonObject();
2941 ePtr<iDVBDemux> demux;
2942 if (!m_service_handler.getDataDemux(demux))
2945 if (!demux->getCADemuxID(demux_id))
2946 PutToDict(r, "demux", demux_id);
2953 DEFINE_REF(eDVBServicePlay)
2955 PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
2959 case iServiceInformation::sTransponderData:
2960 return eStaticServiceDVBInformation().getInfoObject(ref, w);
2964 return iStaticServiceInformation::getInfoObject(ref, w);
2967 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");