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();
1229 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
1231 if (m_is_pvr || m_timeshift_enabled)
1241 /* TODO: when timeshift is enabled but not active, this doesn't work. */
1242 RESULT eDVBServicePlay::getLength(pts_t &len)
1244 ePtr<iDVBPVRChannel> pvr_channel;
1246 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1249 return pvr_channel->getLength(len);
1252 RESULT eDVBServicePlay::pause()
1254 eDebug("eDVBServicePlay::pause");
1255 setFastForward_internal(0);
1259 return m_decoder->pause();
1264 RESULT eDVBServicePlay::unpause()
1266 eDebug("eDVBServicePlay::unpause");
1267 setFastForward_internal(0);
1271 return m_decoder->play();
1276 RESULT eDVBServicePlay::seekTo(pts_t to)
1278 eDebug("eDVBServicePlay::seekTo: jump %lld", to);
1280 if (!m_decode_demux)
1283 ePtr<iDVBPVRChannel> pvr_channel;
1285 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1291 m_cue->seekTo(0, to);
1292 m_dvb_subtitle_pages.clear();
1293 m_subtitle_pages.clear();
1298 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
1300 eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
1302 if (!m_decode_demux)
1305 ePtr<iDVBPVRChannel> pvr_channel;
1307 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1312 /* HACK until we have skip-AP api */
1313 if ((to > 0) && (to < 100))
1321 m_cue->seekTo(mode, to);
1322 m_dvb_subtitle_pages.clear();
1323 m_subtitle_pages.clear();
1327 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
1329 ePtr<iDVBPVRChannel> pvr_channel;
1331 if (!m_decode_demux)
1334 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1339 /* if there is a decoder, use audio or video PTS */
1342 r = m_decoder->getPTS(0, pos);
1348 return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder ? 1 : 0);
1351 RESULT eDVBServicePlay::setTrickmode(int trick)
1353 /* currently unimplemented */
1357 RESULT eDVBServicePlay::isCurrentlySeekable()
1359 return m_is_pvr || m_timeshift_active;
1362 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1368 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1374 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1380 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1386 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1392 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1395 if (m_have_video_pid && // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
1396 (m_timeshift_enabled || !m_is_pvr))
1398 if (!m_timeshift_enabled)
1400 /* query config path */
1402 if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
1403 eDebug("could not query ts path from config");
1407 /* we need enough diskspace */
1409 if (statfs(tspath.c_str(), &fs) < 0)
1411 eDebug("statfs failed!");
1415 if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
1417 eDebug("not enough diskspace for timeshift! (less than 1GB)");
1427 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1438 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1444 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1450 RESULT eDVBServicePlay::rdsDecoder(ePtr<iRdsDecoder> &ptr)
1456 RESULT eDVBServicePlay::getName(std::string &name)
1460 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1461 return i->getName(m_reference, name);
1463 else if (m_dvb_service)
1465 m_dvb_service->getName(m_reference, name);
1469 else if (!m_reference.name.empty())
1470 eStaticServiceDVBInformation().getName(m_reference, name);
1472 name = "DVB service";
1476 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1478 return m_event_handler.getEvent(evt, nownext);
1481 int eDVBServicePlay::getInfo(int w)
1483 eDVBServicePMTHandler::program program;
1486 return resIsPyObject;
1488 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1490 int no_program_info = 0;
1492 if (h.getProgramInfo(program))
1493 no_program_info = 1;
1499 return m_decoder->getVideoHeight();
1503 return m_decoder->getVideoWidth();
1507 return m_decoder->getVideoFrameRate();
1511 return m_decoder->getVideoProgressive();
1517 aspect = m_decoder->getVideoAspect();
1518 if (no_program_info)
1520 else if (aspect == -1 && !program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1522 ePtr<eServiceEvent> evt;
1523 if (!m_event_handler.getEvent(evt, 0))
1525 ePtr<eComponentData> data;
1526 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1528 if ( data->getStreamContent() == 1 )
1530 switch(data->getComponentType())
1533 case 1: // 4:3 SD PAL
1535 case 3: // 16:9 SD PAL
1536 case 4: // > 16:9 PAL
1537 case 5: // 4:3 SD NTSC
1539 case 7: // 16:9 SD NTSC
1540 case 8: // > 16:9 NTSC
1543 case 9: // 4:3 HD PAL
1545 case 0xB: // 16:9 HD PAL
1546 case 0xC: // > 16:9 HD PAL
1547 case 0xD: // 4:3 HD NTSC
1549 case 0xF: // 16:9 HD NTSC
1550 case 0x10: // > 16:9 HD PAL
1551 return data->getComponentType();
1561 case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
1565 int vpid = m_dvb_service->getCacheEntry(eDVBService::cVPID);
1569 if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1570 case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1574 int apid = m_dvb_service->getCacheEntry(eDVBService::cAPID);
1577 apid = m_dvb_service->getCacheEntry(eDVBService::cAC3PID);
1581 if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1585 int pcrpid = m_dvb_service->getCacheEntry(eDVBService::cPCRPID);
1589 if (no_program_info) return -1; return program.pcrPid;
1590 case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
1591 case sTXTPID: if (no_program_info) return -1; return program.textPid;
1592 case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1593 case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1594 case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1595 case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1596 case sProvider: if (!m_dvb_service) return -1; return -2;
1597 case sServiceref: return resIsString;
1598 case sDVBState: return m_tune_state;
1605 std::string eDVBServicePlay::getInfoString(int w)
1610 if (!m_dvb_service) return "";
1611 return m_dvb_service->m_provider_name;
1613 return m_reference.toString();
1617 return iServiceInformation::getInfoString(w);
1620 PyObject *eDVBServicePlay::getInfoObject(int w)
1625 return m_service_handler.getCaIds();
1626 case sTransponderData:
1627 return eStaticServiceDVBInformation().getInfoObject(m_reference, w);
1631 return iServiceInformation::getInfoObject(w);
1634 int eDVBServicePlay::getNumberOfTracks()
1636 eDVBServicePMTHandler::program program;
1637 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1638 if (h.getProgramInfo(program))
1640 return program.audioStreams.size();
1643 int eDVBServicePlay::getCurrentTrack()
1645 eDVBServicePMTHandler::program program;
1646 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1647 if (h.getProgramInfo(program))
1650 int max = program.audioStreams.size();
1653 for (i = 0; i < max; ++i)
1654 if (program.audioStreams[i].pid == m_current_audio_pid)
1660 RESULT eDVBServicePlay::selectTrack(unsigned int i)
1662 int ret = selectAudioStream(i);
1664 if (m_decoder->set())
1670 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
1672 eDVBServicePMTHandler::program program;
1673 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1675 if (h.getProgramInfo(program))
1678 if (i >= program.audioStreams.size())
1681 info.m_pid = program.audioStreams[i].pid;
1683 if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
1684 info.m_description = "MPEG";
1685 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
1686 info.m_description = "AC3";
1687 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
1688 info.m_description = "AAC";
1689 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE)
1690 info.m_description = "AAC-HE";
1691 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
1692 info.m_description = "DTS";
1694 info.m_description = "???";
1696 if (program.audioStreams[i].component_tag != -1)
1698 ePtr<eServiceEvent> evt;
1699 if (!m_event_handler.getEvent(evt, 0))
1701 ePtr<eComponentData> data;
1702 if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
1703 info.m_language = data->getText();
1707 if (info.m_language.empty())
1708 info.m_language = program.audioStreams[i].language_code;
1713 int eDVBServicePlay::selectAudioStream(int i)
1715 eDVBServicePMTHandler::program program;
1716 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1718 if (h.getProgramInfo(program))
1721 if ((i != -1) && ((unsigned int)i >= program.audioStreams.size()))
1729 stream = program.defaultAudioStream;
1731 int apid = -1, apidtype = -1;
1733 if (((unsigned int)stream) < program.audioStreams.size())
1735 apid = program.audioStreams[stream].pid;
1736 apidtype = program.audioStreams[stream].type;
1739 m_current_audio_pid = apid;
1741 if (m_is_primary && m_decoder->setAudioPID(apid, apidtype))
1743 eDebug("set audio pid failed");
1747 /* 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 */
1748 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
1751 ePtr<iDVBDemux> data_demux;
1752 if (!h.getDataDemux(data_demux))
1754 m_rds_decoder = new eDVBRdsDecoder(data_demux);
1755 m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
1759 /* if we decided that we need one, update the pid */
1761 m_rds_decoder->start(apid);
1763 /* store new pid as default only when:
1764 a.) we have an entry in the service db for the current service,
1765 b.) we are not playing back something,
1766 c.) we are not selecting the default entry. (we wouldn't change
1767 anything in the best case, or destroy the default setting in
1768 case the real default is not yet available.)
1770 if (m_dvb_service && ((i != -1)
1771 || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
1773 if (apidtype == eDVBAudio::aMPEG)
1775 m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
1776 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1778 else if (apidtype == eDVBAudio::aAC3)
1780 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1781 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
1785 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1786 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1790 h.resetCachedProgram();
1795 int eDVBServicePlay::getCurrentChannel()
1797 return m_decoder ? m_decoder->getAudioChannel() : STEREO;
1800 RESULT eDVBServicePlay::selectChannel(int i)
1802 if (i < LEFT || i > RIGHT || i == STEREO)
1805 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
1807 m_decoder->setAudioChannel(i);
1811 std::string eDVBServicePlay::getText(int x)
1817 return convertLatin1UTF8(m_rds_decoder->getRadioText());
1819 return convertLatin1UTF8(m_rds_decoder->getRtpText());
1824 void eDVBServicePlay::rdsDecoderEvent(int what)
1828 case eDVBRdsDecoder::RadioTextChanged:
1829 m_event((iPlayableService*)this, evUpdatedRadioText);
1831 case eDVBRdsDecoder::RtpTextChanged:
1832 m_event((iPlayableService*)this, evUpdatedRtpText);
1834 case eDVBRdsDecoder::RassInteractivePicMaskChanged:
1835 m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
1837 case eDVBRdsDecoder::RecvRassSlidePic:
1838 m_event((iPlayableService*)this, evUpdatedRassSlidePic);
1843 void eDVBServicePlay::showRassSlidePicture()
1849 std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
1850 if (rass_slide_pic.length())
1851 m_decoder->showSinglePic(rass_slide_pic.c_str());
1853 eDebug("empty filename for rass slide picture received!!");
1856 eDebug("no MPEG Decoder to show iframes avail");
1859 eDebug("showRassSlidePicture called.. but not decoder");
1862 void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
1868 std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
1869 if (rass_interactive_pic.length())
1870 m_decoder->showSinglePic(rass_interactive_pic.c_str());
1872 eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
1875 eDebug("no MPEG Decoder to show iframes avail");
1878 eDebug("showRassInteractivePic called.. but not decoder");
1881 ePyObject eDVBServicePlay::getRassInteractiveMask()
1884 return m_rds_decoder->getRassPictureMask();
1888 int eDVBServiceBase::getFrontendInfo(int w)
1890 eUsePtr<iDVBChannel> channel;
1891 if(m_service_handler.getChannel(channel))
1893 ePtr<iDVBFrontend> fe;
1894 if(channel->getFrontend(fe))
1896 return fe->readFrontendData(w);
1899 PyObject *eDVBServiceBase::getFrontendData()
1901 ePyObject ret = PyDict_New();
1904 eUsePtr<iDVBChannel> channel;
1905 if(!m_service_handler.getChannel(channel))
1907 ePtr<iDVBFrontend> fe;
1908 if(!channel->getFrontend(fe))
1909 fe->getFrontendData(ret);
1917 PyObject *eDVBServiceBase::getFrontendStatus()
1919 ePyObject ret = PyDict_New();
1922 eUsePtr<iDVBChannel> channel;
1923 if(!m_service_handler.getChannel(channel))
1925 ePtr<iDVBFrontend> fe;
1926 if(!channel->getFrontend(fe))
1927 fe->getFrontendStatus(ret);
1935 PyObject *eDVBServiceBase::getTransponderData(bool original)
1937 ePyObject ret = PyDict_New();
1940 eUsePtr<iDVBChannel> channel;
1941 if(!m_service_handler.getChannel(channel))
1943 ePtr<iDVBFrontend> fe;
1944 if(!channel->getFrontend(fe))
1945 fe->getTransponderData(ret, original);
1953 PyObject *eDVBServiceBase::getAll(bool original)
1955 ePyObject ret = getTransponderData(original);
1958 eUsePtr<iDVBChannel> channel;
1959 if(!m_service_handler.getChannel(channel))
1961 ePtr<iDVBFrontend> fe;
1962 if(!channel->getFrontend(fe))
1964 fe->getFrontendData(ret);
1965 fe->getFrontendStatus(ret);
1972 int eDVBServicePlay::getNumberOfSubservices()
1974 ePtr<eServiceEvent> evt;
1975 if (!m_event_handler.getEvent(evt, 0))
1976 return evt->getNumOfLinkageServices();
1980 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
1982 ePtr<eServiceEvent> evt;
1983 if (!m_event_handler.getEvent(evt, 0))
1985 if (!evt->getLinkageService(sub, m_reference, n))
1988 sub.type=eServiceReference::idInvalid;
1992 RESULT eDVBServicePlay::startTimeshift()
1994 ePtr<iDVBDemux> demux;
1996 eDebug("Start timeshift!");
1998 if (m_timeshift_enabled)
2001 /* start recording with the data demux. */
2002 if (m_service_handler.getDataDemux(demux))
2005 demux->createTSRecorder(m_record);
2010 if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
2011 eDebug("could not query ts path");
2014 tspath.append("/timeshift.XXXXXX");
2016 templ = new char[tspath.length() + 1];
2017 strcpy(templ, tspath.c_str());
2019 m_timeshift_fd = mkstemp(templ);
2020 m_timeshift_file = std::string(templ);
2022 eDebug("recording to %s", templ);
2026 if (m_timeshift_fd < 0)
2032 m_record->setTargetFD(m_timeshift_fd);
2034 m_timeshift_enabled = 1;
2036 updateTimeshiftPids();
2042 RESULT eDVBServicePlay::stopTimeshift()
2044 if (!m_timeshift_enabled)
2049 m_timeshift_enabled = 0;
2054 close(m_timeshift_fd);
2055 eDebug("remove timeshift file");
2056 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
2061 int eDVBServicePlay::isTimeshiftActive()
2063 return m_timeshift_enabled && m_timeshift_active;
2066 RESULT eDVBServicePlay::activateTimeshift()
2068 if (!m_timeshift_enabled)
2071 if (!m_timeshift_active)
2073 switchToTimeshift();
2080 PyObject *eDVBServicePlay::getCutList()
2082 ePyObject list = PyList_New(0);
2084 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2086 ePyObject tuple = PyTuple_New(2);
2087 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
2088 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
2089 PyList_Append(list, tuple);
2096 void eDVBServicePlay::setCutList(ePyObject list)
2098 if (!PyList_Check(list))
2100 int size = PyList_Size(list);
2103 m_cue_entries.clear();
2105 for (i=0; i<size; ++i)
2107 ePyObject tuple = PyList_GET_ITEM(list, i);
2108 if (!PyTuple_Check(tuple))
2110 eDebug("non-tuple in cutlist");
2113 if (PyTuple_Size(tuple) != 2)
2115 eDebug("cutlist entries need to be a 2-tuple");
2118 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
2119 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
2121 eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
2124 pts_t pts = PyLong_AsLongLong(ppts);
2125 int type = PyInt_AsLong(ptype);
2126 m_cue_entries.insert(cueEntry(pts, type));
2127 eDebug("adding %08llx, %d", pts, type);
2129 m_cuesheet_changed = 1;
2131 cutlistToCuesheet();
2132 m_event((iPlayableService*)this, evCuesheetChanged);
2135 void eDVBServicePlay::setCutListEnable(int enable)
2137 m_cutlist_enabled = enable;
2138 cutlistToCuesheet();
2141 void eDVBServicePlay::updateTimeshiftPids()
2146 eDVBServicePMTHandler::program program;
2147 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2149 if (h.getProgramInfo(program))
2153 std::set<int> pids_to_record;
2154 pids_to_record.insert(0); // PAT
2155 if (program.pmtPid != -1)
2156 pids_to_record.insert(program.pmtPid); // PMT
2158 if (program.textPid != -1)
2159 pids_to_record.insert(program.textPid); // Videotext
2161 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2162 i(program.videoStreams.begin());
2163 i != program.videoStreams.end(); ++i)
2164 pids_to_record.insert(i->pid);
2166 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2167 i(program.audioStreams.begin());
2168 i != program.audioStreams.end(); ++i)
2169 pids_to_record.insert(i->pid);
2171 for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
2172 i(program.subtitleStreams.begin());
2173 i != program.subtitleStreams.end(); ++i)
2174 pids_to_record.insert(i->pid);
2176 std::set<int> new_pids, obsolete_pids;
2178 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
2179 m_pids_active.begin(), m_pids_active.end(),
2180 std::inserter(new_pids, new_pids.begin()));
2182 std::set_difference(
2183 m_pids_active.begin(), m_pids_active.end(),
2184 pids_to_record.begin(), pids_to_record.end(),
2185 std::inserter(new_pids, new_pids.begin())
2188 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
2189 m_record->addPID(*i);
2191 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
2192 m_record->removePID(*i);
2196 void eDVBServicePlay::switchToLive()
2198 if (!m_timeshift_active)
2201 eDebug("SwitchToLive");
2206 m_teletext_parser = 0;
2208 m_subtitle_parser = 0;
2209 m_new_dvb_subtitle_page_connection = 0;
2210 m_new_subtitle_page_connection = 0;
2211 m_rds_decoder_event_connection = 0;
2212 m_video_event_connection = 0;
2213 m_is_paused = m_skipmode = 0; /* not supported in live mode */
2215 /* free the timeshift service handler, we need the resources */
2216 m_service_handler_timeshift.free();
2217 m_timeshift_active = 0;
2219 m_event((iPlayableService*)this, evSeekableStatusChanged);
2224 void eDVBServicePlay::switchToTimeshift()
2226 if (m_timeshift_active)
2231 m_teletext_parser = 0;
2233 m_subtitle_parser = 0;
2234 m_new_subtitle_page_connection = 0;
2235 m_new_dvb_subtitle_page_connection = 0;
2236 m_rds_decoder_event_connection = 0;
2237 m_video_event_connection = 0;
2239 m_timeshift_active = 1;
2241 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2242 r.path = m_timeshift_file;
2244 m_cue = new eCueSheet();
2245 m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
2247 eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
2249 updateDecoder(); /* mainly to switch off PCR, and to set pause */
2251 m_event((iPlayableService*)this, evSeekableStatusChanged);
2254 void eDVBServicePlay::updateDecoder()
2256 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2258 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2260 eDVBServicePMTHandler::program program;
2261 if (h.getProgramInfo(program))
2262 eDebug("getting program info failed.");
2265 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
2266 if (!program.videoStreams.empty())
2268 eDebugNoNewLine(" (");
2269 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2270 i(program.videoStreams.begin());
2271 i != program.videoStreams.end(); ++i)
2278 if (i != program.videoStreams.begin())
2279 eDebugNoNewLine(", ");
2280 eDebugNoNewLine("%04x", i->pid);
2282 eDebugNoNewLine(")");
2284 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
2285 if (!program.audioStreams.empty())
2287 eDebugNoNewLine(" (");
2288 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2289 i(program.audioStreams.begin());
2290 i != program.audioStreams.end(); ++i)
2292 if (i != program.audioStreams.begin())
2293 eDebugNoNewLine(", ");
2294 eDebugNoNewLine("%04x", i->pid);
2296 eDebugNoNewLine(")");
2298 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2299 pcrpid = program.pcrPid;
2300 eDebug(", and the text pid is %04x", program.textPid);
2301 tpid = program.textPid;
2306 h.getDecodeDemux(m_decode_demux);
2309 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
2311 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2313 if (m_decode_demux && m_is_primary)
2315 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2316 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2317 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2318 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2321 m_teletext_parser = 0;
2322 m_subtitle_parser = 0;
2326 m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2333 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2334 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2335 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2339 eServiceReferenceDVB ref;
2340 m_service_handler.getServiceReference(ref);
2341 eServiceReferenceDVB parent = ref.getParentServiceReference();
2346 ePtr<eDVBResourceManager> res_mgr;
2347 if (!eDVBResourceManager::getInstance(res_mgr))
2349 ePtr<iDVBChannelList> db;
2350 if (!res_mgr->getChannelList(db))
2352 ePtr<eDVBService> origService;
2353 if (!db->getService(parent, origService))
2355 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2356 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2363 std::string config_delay;
2364 int config_delay_int = 0;
2365 if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
2366 config_delay_int = atoi(config_delay.c_str());
2367 m_decoder->setAC3Delay(ac3_delay == -1 ? config_delay_int : ac3_delay + config_delay_int);
2369 if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
2370 config_delay_int = atoi(config_delay.c_str());
2372 config_delay_int = 0;
2373 m_decoder->setPCMDelay(pcm_delay == -1 ? config_delay_int : pcm_delay + config_delay_int);
2375 m_decoder->setVideoPID(vpid, vpidtype);
2376 selectAudioStream();
2378 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
2379 m_decoder->setSyncPCR(pcrpid);
2381 m_decoder->setSyncPCR(-1);
2385 m_decoder->setTextPID(tpid);
2386 m_teletext_parser->start(program.textPid);
2389 if (vpid > 0 && vpid < 0x2000)
2393 std::string radio_pic;
2394 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
2395 m_decoder->setRadioPic(radio_pic);
2398 /* if (!m_is_primary)
2399 m_decoder->setTrickmode();
2400 else */ if (m_is_paused)
2405 m_decoder->setAudioChannel(achannel);
2407 /* don't worry about non-existing services, nor pvr services */
2410 /* (audio pid will be set in selectAudioTrack */
2411 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2412 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2413 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2414 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2417 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2420 void eDVBServicePlay::loadCuesheet()
2422 std::string filename = m_reference.path + ".cuts";
2424 m_cue_entries.clear();
2426 FILE *f = fopen(filename.c_str(), "rb");
2430 eDebug("loading cuts..");
2433 unsigned long long where;
2436 if (!fread(&where, sizeof(where), 1, f))
2438 if (!fread(&what, sizeof(what), 1, f))
2441 #if BYTE_ORDER == LITTLE_ENDIAN
2442 where = bswap_64(where);
2449 m_cue_entries.insert(cueEntry(where, what));
2452 eDebug("%d entries", m_cue_entries.size());
2454 eDebug("cutfile not found!");
2456 m_cuesheet_changed = 0;
2457 cutlistToCuesheet();
2458 m_event((iPlayableService*)this, evCuesheetChanged);
2461 void eDVBServicePlay::saveCuesheet()
2463 std::string filename = m_reference.path + ".cuts";
2465 FILE *f = fopen(filename.c_str(), "wb");
2469 unsigned long long where;
2472 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2474 #if BYTE_ORDER == BIG_ENDIAN
2477 where = bswap_64(i->where);
2479 what = htonl(i->what);
2480 fwrite(&where, sizeof(where), 1, f);
2481 fwrite(&what, sizeof(what), 1, f);
2487 m_cuesheet_changed = 0;
2490 void eDVBServicePlay::cutlistToCuesheet()
2494 eDebug("no cue sheet");
2499 if (!m_cutlist_enabled)
2501 m_cue->commitSpans();
2502 eDebug("cutlists were disabled");
2506 pts_t in = 0, out = 0, length = 0;
2510 std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
2512 int have_any_span = 0;
2516 if (i == m_cue_entries.end())
2522 if (i->what == 0) /* in */
2526 } else if (i->what == 1) /* out */
2528 else /* mark (2) or last play position (3) */
2547 m_cue->addSourceSpan(in, out);
2552 if (i == m_cue_entries.end())
2555 m_cue->commitSpans();
2558 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
2560 if (m_subtitle_widget)
2561 disableSubtitles(parent);
2564 int tuplesize = PyTuple_Size(tuple);
2567 if (!PyTuple_Check(tuple))
2573 entry = PyTuple_GET_ITEM(tuple, 0);
2575 if (!PyInt_Check(entry))
2578 type = PyInt_AsLong(entry);
2580 if (type == 1) // teletext subtitles
2582 int page, magazine, pid;
2586 if (!m_teletext_parser)
2588 eDebug("enable teletext subtitles.. no parser !!!");
2592 entry = PyTuple_GET_ITEM(tuple, 1);
2593 if (!PyInt_Check(entry))
2595 pid = PyInt_AsLong(entry);
2597 entry = PyTuple_GET_ITEM(tuple, 2);
2598 if (!PyInt_Check(entry))
2600 page = PyInt_AsLong(entry);
2602 entry = PyTuple_GET_ITEM(tuple, 3);
2603 if (!PyInt_Check(entry))
2605 magazine = PyInt_AsLong(entry);
2607 m_subtitle_widget = new eSubtitleWidget(parent);
2608 m_subtitle_widget->resize(parent->size()); /* full size */
2609 m_teletext_parser->setPageAndMagazine(page, magazine);
2611 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
2615 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
2616 if (!m_subtitle_parser)
2618 eDebug("enable dvb subtitles.. no parser !!!");
2624 entry = PyTuple_GET_ITEM(tuple, 1);
2625 if (!PyInt_Check(entry))
2627 pid = PyInt_AsLong(entry);
2629 entry = PyTuple_GET_ITEM(tuple, 2);
2630 if (!PyInt_Check(entry))
2632 composition_page_id = PyInt_AsLong(entry);
2634 entry = PyTuple_GET_ITEM(tuple, 3);
2635 if (!PyInt_Check(entry))
2637 ancillary_page_id = PyInt_AsLong(entry);
2639 m_subtitle_widget = new eSubtitleWidget(parent);
2640 m_subtitle_widget->resize(parent->size()); /* full size */
2641 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
2643 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
2649 eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
2650 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
2651 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
2655 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
2657 delete m_subtitle_widget;
2658 m_subtitle_widget = 0;
2659 if (m_subtitle_parser)
2661 m_subtitle_parser->stop();
2662 m_dvb_subtitle_pages.clear();
2664 if (m_teletext_parser)
2666 m_teletext_parser->setPageAndMagazine(-1, -1);
2667 m_subtitle_pages.clear();
2670 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
2674 PyObject *eDVBServicePlay::getCachedSubtitle()
2678 int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
2681 unsigned int data = (unsigned int)tmp;
2682 int pid = (data&0xFFFF0000)>>16;
2683 ePyObject tuple = PyTuple_New(4);
2684 eDVBServicePMTHandler::program program;
2685 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2686 if (!h.getProgramInfo(program))
2688 if (program.textPid==pid) // teletext
2689 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
2691 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
2692 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
2693 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
2694 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
2702 PyObject *eDVBServicePlay::getSubtitleList()
2704 if (!m_teletext_parser)
2707 ePyObject l = PyList_New(0);
2708 std::set<int> added_ttx_pages;
2710 std::set<eDVBServicePMTHandler::subtitleStream> &subs =
2711 m_teletext_parser->m_found_subtitle_pages;
2713 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2714 eDVBServicePMTHandler::program program;
2715 if (h.getProgramInfo(program))
2716 eDebug("getting program info failed.");
2719 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
2720 it != program.subtitleStreams.end(); ++it)
2722 switch(it->subtitling_type)
2724 case 0x01: // ebu teletext subtitles
2726 int page_number = it->teletext_page_number & 0xFF;
2727 int magazine_number = it->teletext_magazine_number & 7;
2728 int hash = magazine_number << 8 | page_number;
2729 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2731 ePyObject tuple = PyTuple_New(5);
2732 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2733 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2734 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2735 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2736 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2737 PyList_Append(l, tuple);
2739 added_ttx_pages.insert(hash);
2744 case 0x20 ... 0x23: // dvb subtitles
2746 ePyObject tuple = PyTuple_New(5);
2747 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
2748 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2749 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
2750 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
2751 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2752 PyList_Insert(l, 0, tuple);
2760 for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
2761 it != subs.end(); ++it)
2763 int page_number = it->teletext_page_number & 0xFF;
2764 int magazine_number = it->teletext_magazine_number & 7;
2765 int hash = magazine_number << 8 | page_number;
2766 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2768 ePyObject tuple = PyTuple_New(5);
2769 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2770 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2771 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2772 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2773 PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
2774 PyList_Append(l, tuple);
2782 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
2784 if (m_subtitle_widget)
2788 m_decoder->getPTS(0, pos);
2789 eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
2790 m_subtitle_pages.push_back(page);
2791 checkSubtitleTiming();
2795 void eDVBServicePlay::checkSubtitleTiming()
2797 eDebug("checkSubtitleTiming");
2798 if (!m_subtitle_widget)
2802 enum { TELETEXT, DVB } type;
2803 eDVBTeletextSubtitlePage page;
2804 eDVBSubtitlePage dvb_page;
2806 if (!m_subtitle_pages.empty())
2808 page = m_subtitle_pages.front();
2810 show_time = page.m_pts;
2812 else if (!m_dvb_subtitle_pages.empty())
2814 dvb_page = m_dvb_subtitle_pages.front();
2816 show_time = dvb_page.m_show_time;
2824 m_decoder->getPTS(0, pos);
2826 eDebug("%lld %lld", pos, show_time);
2827 int diff = show_time - pos;
2830 eDebug("[late (%d ms)]", -diff / 90);
2833 // if (diff > 900000)
2835 // eDebug("[invalid]");
2841 if (type == TELETEXT)
2843 eDebug("display teletext subtitle page %lld", show_time);
2844 m_subtitle_widget->setPage(page);
2845 m_subtitle_pages.pop_front();
2849 eDebug("display dvb subtitle Page %lld", show_time);
2850 m_subtitle_widget->setPage(dvb_page);
2851 m_dvb_subtitle_pages.pop_front();
2855 eDebug("start subtitle delay %d", diff / 90);
2856 m_subtitle_sync_timer->start(diff / 90, 1);
2862 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
2864 if (m_subtitle_widget)
2868 m_decoder->getPTS(0, pos);
2869 eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
2870 m_dvb_subtitle_pages.push_back(p);
2871 checkSubtitleTiming();
2875 int eDVBServicePlay::getAC3Delay()
2878 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2880 return m_decoder->getAC3Delay();
2885 int eDVBServicePlay::getPCMDelay()
2888 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2890 return m_decoder->getPCMDelay();
2895 void eDVBServicePlay::setAC3Delay(int delay)
2898 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2900 m_decoder->setAC3Delay(delay);
2903 void eDVBServicePlay::setPCMDelay(int delay)
2906 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2908 m_decoder->setPCMDelay(delay);
2911 void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
2913 switch(event.type) {
2914 case iTSMPEGDecoder::videoEvent::eventSizeChanged:
2915 m_event((iPlayableService*)this, evVideoSizeChanged);
2917 case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
2918 m_event((iPlayableService*)this, evVideoFramerateChanged);
2920 case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
2921 m_event((iPlayableService*)this, evVideoProgressiveChanged);
2928 RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
2934 PyObject *eDVBServicePlay::getStreamingData()
2936 eDVBServicePMTHandler::program program;
2937 if (m_service_handler.getProgramInfo(program))
2942 ePyObject r = program.createPythonObject();
2943 ePtr<iDVBDemux> demux;
2944 if (!m_service_handler.getDataDemux(demux))
2947 if (!demux->getCADemuxID(demux_id))
2948 PutToDict(r, "demux", demux_id);
2955 DEFINE_REF(eDVBServicePlay)
2957 PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
2961 case iServiceInformation::sTransponderData:
2962 return eStaticServiceDVBInformation().getInfoObject(ref, w);
2966 return iStaticServiceInformation::getInfoObject(ref, w);
2969 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");