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;
2212 m_is_paused = m_skipmode = 0; /* not supported in live mode */
2214 /* free the timeshift service handler, we need the resources */
2215 m_service_handler_timeshift.free();
2216 m_timeshift_active = 0;
2218 m_event((iPlayableService*)this, evSeekableStatusChanged);
2223 void eDVBServicePlay::switchToTimeshift()
2225 if (m_timeshift_active)
2230 m_teletext_parser = 0;
2232 m_subtitle_parser = 0;
2233 m_new_subtitle_page_connection = 0;
2234 m_new_dvb_subtitle_page_connection = 0;
2235 m_rds_decoder_event_connection = 0;
2236 m_video_event_connection = 0;
2238 m_timeshift_active = 1;
2240 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2241 r.path = m_timeshift_file;
2243 m_cue = new eCueSheet();
2244 m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
2246 eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
2248 updateDecoder(); /* mainly to switch off PCR, and to set pause */
2250 m_event((iPlayableService*)this, evSeekableStatusChanged);
2253 void eDVBServicePlay::updateDecoder()
2255 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2257 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2259 eDVBServicePMTHandler::program program;
2260 if (h.getProgramInfo(program))
2261 eDebug("getting program info failed.");
2264 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
2265 if (!program.videoStreams.empty())
2267 eDebugNoNewLine(" (");
2268 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2269 i(program.videoStreams.begin());
2270 i != program.videoStreams.end(); ++i)
2277 if (i != program.videoStreams.begin())
2278 eDebugNoNewLine(", ");
2279 eDebugNoNewLine("%04x", i->pid);
2281 eDebugNoNewLine(")");
2283 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
2284 if (!program.audioStreams.empty())
2286 eDebugNoNewLine(" (");
2287 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2288 i(program.audioStreams.begin());
2289 i != program.audioStreams.end(); ++i)
2291 if (i != program.audioStreams.begin())
2292 eDebugNoNewLine(", ");
2293 eDebugNoNewLine("%04x", i->pid);
2295 eDebugNoNewLine(")");
2297 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2298 pcrpid = program.pcrPid;
2299 eDebug(", and the text pid is %04x", program.textPid);
2300 tpid = program.textPid;
2305 h.getDecodeDemux(m_decode_demux);
2308 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
2310 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2312 if (m_decode_demux && m_is_primary)
2314 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2315 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2316 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2317 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2320 m_teletext_parser = 0;
2321 m_subtitle_parser = 0;
2325 m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2332 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2333 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2334 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2338 eServiceReferenceDVB ref;
2339 m_service_handler.getServiceReference(ref);
2340 eServiceReferenceDVB parent = ref.getParentServiceReference();
2345 ePtr<eDVBResourceManager> res_mgr;
2346 if (!eDVBResourceManager::getInstance(res_mgr))
2348 ePtr<iDVBChannelList> db;
2349 if (!res_mgr->getChannelList(db))
2351 ePtr<eDVBService> origService;
2352 if (!db->getService(parent, origService))
2354 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2355 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2362 std::string config_delay;
2363 int config_delay_int = 0;
2364 if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
2365 config_delay_int = atoi(config_delay.c_str());
2366 m_decoder->setAC3Delay(ac3_delay == -1 ? config_delay_int : ac3_delay + config_delay_int);
2368 if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
2369 config_delay_int = atoi(config_delay.c_str());
2371 config_delay_int = 0;
2372 m_decoder->setPCMDelay(pcm_delay == -1 ? config_delay_int : pcm_delay + config_delay_int);
2374 m_decoder->setVideoPID(vpid, vpidtype);
2375 selectAudioStream();
2377 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
2378 m_decoder->setSyncPCR(pcrpid);
2380 m_decoder->setSyncPCR(-1);
2384 m_decoder->setTextPID(tpid);
2385 m_teletext_parser->start(program.textPid);
2388 if (vpid > 0 && vpid < 0x2000)
2392 std::string radio_pic;
2393 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
2394 m_decoder->setRadioPic(radio_pic);
2397 /* if (!m_is_primary)
2398 m_decoder->setTrickmode();
2399 else */ if (m_is_paused)
2404 m_decoder->setAudioChannel(achannel);
2406 /* don't worry about non-existing services, nor pvr services */
2409 /* (audio pid will be set in selectAudioTrack */
2410 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2411 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2412 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2413 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2416 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2419 void eDVBServicePlay::loadCuesheet()
2421 std::string filename = m_reference.path + ".cuts";
2423 m_cue_entries.clear();
2425 FILE *f = fopen(filename.c_str(), "rb");
2429 eDebug("loading cuts..");
2432 unsigned long long where;
2435 if (!fread(&where, sizeof(where), 1, f))
2437 if (!fread(&what, sizeof(what), 1, f))
2440 #if BYTE_ORDER == LITTLE_ENDIAN
2441 where = bswap_64(where);
2448 m_cue_entries.insert(cueEntry(where, what));
2451 eDebug("%d entries", m_cue_entries.size());
2453 eDebug("cutfile not found!");
2455 m_cuesheet_changed = 0;
2456 cutlistToCuesheet();
2457 m_event((iPlayableService*)this, evCuesheetChanged);
2460 void eDVBServicePlay::saveCuesheet()
2462 std::string filename = m_reference.path + ".cuts";
2464 FILE *f = fopen(filename.c_str(), "wb");
2468 unsigned long long where;
2471 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2473 #if BYTE_ORDER == BIG_ENDIAN
2476 where = bswap_64(i->where);
2478 what = htonl(i->what);
2479 fwrite(&where, sizeof(where), 1, f);
2480 fwrite(&what, sizeof(what), 1, f);
2486 m_cuesheet_changed = 0;
2489 void eDVBServicePlay::cutlistToCuesheet()
2493 eDebug("no cue sheet");
2498 if (!m_cutlist_enabled)
2500 m_cue->commitSpans();
2501 eDebug("cutlists were disabled");
2505 pts_t in = 0, out = 0, length = 0;
2509 std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
2511 int have_any_span = 0;
2515 if (i == m_cue_entries.end())
2521 if (i->what == 0) /* in */
2525 } else if (i->what == 1) /* out */
2527 else /* mark (2) or last play position (3) */
2546 m_cue->addSourceSpan(in, out);
2551 if (i == m_cue_entries.end())
2554 m_cue->commitSpans();
2557 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
2559 if (m_subtitle_widget)
2560 disableSubtitles(parent);
2563 int tuplesize = PyTuple_Size(tuple);
2566 if (!PyTuple_Check(tuple))
2572 entry = PyTuple_GET_ITEM(tuple, 0);
2574 if (!PyInt_Check(entry))
2577 type = PyInt_AsLong(entry);
2579 if (type == 1) // teletext subtitles
2581 int page, magazine, pid;
2585 if (!m_teletext_parser)
2587 eDebug("enable teletext subtitles.. no parser !!!");
2591 entry = PyTuple_GET_ITEM(tuple, 1);
2592 if (!PyInt_Check(entry))
2594 pid = PyInt_AsLong(entry);
2596 entry = PyTuple_GET_ITEM(tuple, 2);
2597 if (!PyInt_Check(entry))
2599 page = PyInt_AsLong(entry);
2601 entry = PyTuple_GET_ITEM(tuple, 3);
2602 if (!PyInt_Check(entry))
2604 magazine = PyInt_AsLong(entry);
2606 m_subtitle_widget = new eSubtitleWidget(parent);
2607 m_subtitle_widget->resize(parent->size()); /* full size */
2608 m_teletext_parser->setPageAndMagazine(page, magazine);
2610 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
2614 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
2615 if (!m_subtitle_parser)
2617 eDebug("enable dvb subtitles.. no parser !!!");
2623 entry = PyTuple_GET_ITEM(tuple, 1);
2624 if (!PyInt_Check(entry))
2626 pid = PyInt_AsLong(entry);
2628 entry = PyTuple_GET_ITEM(tuple, 2);
2629 if (!PyInt_Check(entry))
2631 composition_page_id = PyInt_AsLong(entry);
2633 entry = PyTuple_GET_ITEM(tuple, 3);
2634 if (!PyInt_Check(entry))
2636 ancillary_page_id = PyInt_AsLong(entry);
2638 m_subtitle_widget = new eSubtitleWidget(parent);
2639 m_subtitle_widget->resize(parent->size()); /* full size */
2640 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
2642 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
2648 eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
2649 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
2650 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
2654 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
2656 delete m_subtitle_widget;
2657 m_subtitle_widget = 0;
2658 if (m_subtitle_parser)
2660 m_subtitle_parser->stop();
2661 m_dvb_subtitle_pages.clear();
2663 if (m_teletext_parser)
2665 m_teletext_parser->setPageAndMagazine(-1, -1);
2666 m_subtitle_pages.clear();
2669 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
2673 PyObject *eDVBServicePlay::getCachedSubtitle()
2677 int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
2680 unsigned int data = (unsigned int)tmp;
2681 int pid = (data&0xFFFF0000)>>16;
2682 ePyObject tuple = PyTuple_New(4);
2683 eDVBServicePMTHandler::program program;
2684 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2685 if (!h.getProgramInfo(program))
2687 if (program.textPid==pid) // teletext
2688 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
2690 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
2691 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
2692 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
2693 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
2701 PyObject *eDVBServicePlay::getSubtitleList()
2703 if (!m_teletext_parser)
2706 ePyObject l = PyList_New(0);
2707 std::set<int> added_ttx_pages;
2709 std::set<eDVBServicePMTHandler::subtitleStream> &subs =
2710 m_teletext_parser->m_found_subtitle_pages;
2712 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2713 eDVBServicePMTHandler::program program;
2714 if (h.getProgramInfo(program))
2715 eDebug("getting program info failed.");
2718 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
2719 it != program.subtitleStreams.end(); ++it)
2721 switch(it->subtitling_type)
2723 case 0x01: // ebu teletext subtitles
2725 int page_number = it->teletext_page_number & 0xFF;
2726 int magazine_number = it->teletext_magazine_number & 7;
2727 int hash = magazine_number << 8 | page_number;
2728 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2730 ePyObject tuple = PyTuple_New(5);
2731 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2732 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2733 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2734 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2735 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2736 PyList_Append(l, tuple);
2738 added_ttx_pages.insert(hash);
2743 case 0x20 ... 0x23: // dvb subtitles
2745 ePyObject tuple = PyTuple_New(5);
2746 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
2747 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2748 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
2749 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
2750 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2751 PyList_Insert(l, 0, tuple);
2759 for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
2760 it != subs.end(); ++it)
2762 int page_number = it->teletext_page_number & 0xFF;
2763 int magazine_number = it->teletext_magazine_number & 7;
2764 int hash = magazine_number << 8 | page_number;
2765 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2767 ePyObject tuple = PyTuple_New(5);
2768 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2769 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2770 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2771 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2772 PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
2773 PyList_Append(l, tuple);
2781 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
2783 if (m_subtitle_widget)
2787 m_decoder->getPTS(0, pos);
2788 eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
2789 m_subtitle_pages.push_back(page);
2790 checkSubtitleTiming();
2794 void eDVBServicePlay::checkSubtitleTiming()
2796 eDebug("checkSubtitleTiming");
2797 if (!m_subtitle_widget)
2801 enum { TELETEXT, DVB } type;
2802 eDVBTeletextSubtitlePage page;
2803 eDVBSubtitlePage dvb_page;
2805 if (!m_subtitle_pages.empty())
2807 page = m_subtitle_pages.front();
2809 show_time = page.m_pts;
2811 else if (!m_dvb_subtitle_pages.empty())
2813 dvb_page = m_dvb_subtitle_pages.front();
2815 show_time = dvb_page.m_show_time;
2823 m_decoder->getPTS(0, pos);
2825 eDebug("%lld %lld", pos, show_time);
2826 int diff = show_time - pos;
2829 eDebug("[late (%d ms)]", -diff / 90);
2832 // if (diff > 900000)
2834 // eDebug("[invalid]");
2840 if (type == TELETEXT)
2842 eDebug("display teletext subtitle page %lld", show_time);
2843 m_subtitle_widget->setPage(page);
2844 m_subtitle_pages.pop_front();
2848 eDebug("display dvb subtitle Page %lld", show_time);
2849 m_subtitle_widget->setPage(dvb_page);
2850 m_dvb_subtitle_pages.pop_front();
2854 eDebug("start subtitle delay %d", diff / 90);
2855 m_subtitle_sync_timer->start(diff / 90, 1);
2861 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
2863 if (m_subtitle_widget)
2867 m_decoder->getPTS(0, pos);
2868 eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
2869 m_dvb_subtitle_pages.push_back(p);
2870 checkSubtitleTiming();
2874 int eDVBServicePlay::getAC3Delay()
2877 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2879 return m_decoder->getAC3Delay();
2884 int eDVBServicePlay::getPCMDelay()
2887 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2889 return m_decoder->getPCMDelay();
2894 void eDVBServicePlay::setAC3Delay(int delay)
2897 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2899 m_decoder->setAC3Delay(delay);
2902 void eDVBServicePlay::setPCMDelay(int delay)
2905 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2907 m_decoder->setPCMDelay(delay);
2910 void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
2912 switch(event.type) {
2913 case iTSMPEGDecoder::videoEvent::eventSizeChanged:
2914 m_event((iPlayableService*)this, evVideoSizeChanged);
2916 case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
2917 m_event((iPlayableService*)this, evVideoFramerateChanged);
2919 case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
2920 m_event((iPlayableService*)this, evVideoProgressiveChanged);
2927 RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
2933 PyObject *eDVBServicePlay::getStreamingData()
2935 eDVBServicePMTHandler::program program;
2936 if (m_service_handler.getProgramInfo(program))
2941 ePyObject r = program.createPythonObject();
2942 ePtr<iDVBDemux> demux;
2943 if (!m_service_handler.getDataDemux(demux))
2946 if (!demux->getCADemuxID(demux_id))
2947 PutToDict(r, "demux", demux_id);
2954 DEFINE_REF(eDVBServicePlay)
2956 PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
2960 case iServiceInformation::sTransponderData:
2961 return eStaticServiceDVBInformation().getInfoObject(ref, w);
2965 return iStaticServiceInformation::getInfoObject(ref, w);
2968 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");