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_decoder->setAudioPID(apid, apidtype))
1742 eDebug("set audio pid failed");
1746 /* if we are not in PVR mode, timeshift is not active and we are not in pip mode, check if we need to enable the rds reader */
1747 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
1750 ePtr<iDVBDemux> data_demux;
1751 if (!h.getDataDemux(data_demux))
1753 m_rds_decoder = new eDVBRdsDecoder(data_demux);
1754 m_rds_decoder->connectEvent(slot(*this, &eDVBServicePlay::rdsDecoderEvent), m_rds_decoder_event_connection);
1758 /* if we decided that we need one, update the pid */
1760 m_rds_decoder->start(apid);
1762 /* store new pid as default only when:
1763 a.) we have an entry in the service db for the current service,
1764 b.) we are not playing back something,
1765 c.) we are not selecting the default entry. (we wouldn't change
1766 anything in the best case, or destroy the default setting in
1767 case the real default is not yet available.)
1769 if (m_dvb_service && ((i != -1)
1770 || ((m_dvb_service->getCacheEntry(eDVBService::cAPID) == -1) && (m_dvb_service->getCacheEntry(eDVBService::cAC3PID)==-1))))
1772 if (apidtype == eDVBAudio::aMPEG)
1774 m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
1775 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1777 else if (apidtype == eDVBAudio::aAC3)
1779 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1780 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
1784 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1785 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1789 h.resetCachedProgram();
1794 int eDVBServicePlay::getCurrentChannel()
1796 return m_decoder ? m_decoder->getAudioChannel() : STEREO;
1799 RESULT eDVBServicePlay::selectChannel(int i)
1801 if (i < LEFT || i > RIGHT || i == STEREO)
1804 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
1806 m_decoder->setAudioChannel(i);
1810 std::string eDVBServicePlay::getText(int x)
1816 return convertLatin1UTF8(m_rds_decoder->getRadioText());
1818 return convertLatin1UTF8(m_rds_decoder->getRtpText());
1823 void eDVBServicePlay::rdsDecoderEvent(int what)
1827 case eDVBRdsDecoder::RadioTextChanged:
1828 m_event((iPlayableService*)this, evUpdatedRadioText);
1830 case eDVBRdsDecoder::RtpTextChanged:
1831 m_event((iPlayableService*)this, evUpdatedRtpText);
1833 case eDVBRdsDecoder::RassInteractivePicMaskChanged:
1834 m_event((iPlayableService*)this, evUpdatedRassInteractivePicMask);
1836 case eDVBRdsDecoder::RecvRassSlidePic:
1837 m_event((iPlayableService*)this, evUpdatedRassSlidePic);
1842 void eDVBServicePlay::showRassSlidePicture()
1848 std::string rass_slide_pic = m_rds_decoder->getRassSlideshowPicture();
1849 if (rass_slide_pic.length())
1850 m_decoder->showSinglePic(rass_slide_pic.c_str());
1852 eDebug("empty filename for rass slide picture received!!");
1855 eDebug("no MPEG Decoder to show iframes avail");
1858 eDebug("showRassSlidePicture called.. but not decoder");
1861 void eDVBServicePlay::showRassInteractivePic(int page, int subpage)
1867 std::string rass_interactive_pic = m_rds_decoder->getRassPicture(page, subpage);
1868 if (rass_interactive_pic.length())
1869 m_decoder->showSinglePic(rass_interactive_pic.c_str());
1871 eDebug("empty filename for rass interactive picture %d/%d received!!", page, subpage);
1874 eDebug("no MPEG Decoder to show iframes avail");
1877 eDebug("showRassInteractivePic called.. but not decoder");
1880 ePyObject eDVBServicePlay::getRassInteractiveMask()
1883 return m_rds_decoder->getRassPictureMask();
1887 int eDVBServiceBase::getFrontendInfo(int w)
1889 eUsePtr<iDVBChannel> channel;
1890 if(m_service_handler.getChannel(channel))
1892 ePtr<iDVBFrontend> fe;
1893 if(channel->getFrontend(fe))
1895 return fe->readFrontendData(w);
1898 PyObject *eDVBServiceBase::getFrontendData()
1900 ePyObject ret = PyDict_New();
1903 eUsePtr<iDVBChannel> channel;
1904 if(!m_service_handler.getChannel(channel))
1906 ePtr<iDVBFrontend> fe;
1907 if(!channel->getFrontend(fe))
1908 fe->getFrontendData(ret);
1916 PyObject *eDVBServiceBase::getFrontendStatus()
1918 ePyObject ret = PyDict_New();
1921 eUsePtr<iDVBChannel> channel;
1922 if(!m_service_handler.getChannel(channel))
1924 ePtr<iDVBFrontend> fe;
1925 if(!channel->getFrontend(fe))
1926 fe->getFrontendStatus(ret);
1934 PyObject *eDVBServiceBase::getTransponderData(bool original)
1936 ePyObject ret = PyDict_New();
1939 eUsePtr<iDVBChannel> channel;
1940 if(!m_service_handler.getChannel(channel))
1942 ePtr<iDVBFrontend> fe;
1943 if(!channel->getFrontend(fe))
1944 fe->getTransponderData(ret, original);
1952 PyObject *eDVBServiceBase::getAll(bool original)
1954 ePyObject ret = getTransponderData(original);
1957 eUsePtr<iDVBChannel> channel;
1958 if(!m_service_handler.getChannel(channel))
1960 ePtr<iDVBFrontend> fe;
1961 if(!channel->getFrontend(fe))
1963 fe->getFrontendData(ret);
1964 fe->getFrontendStatus(ret);
1971 int eDVBServicePlay::getNumberOfSubservices()
1973 ePtr<eServiceEvent> evt;
1974 if (!m_event_handler.getEvent(evt, 0))
1975 return evt->getNumOfLinkageServices();
1979 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
1981 ePtr<eServiceEvent> evt;
1982 if (!m_event_handler.getEvent(evt, 0))
1984 if (!evt->getLinkageService(sub, m_reference, n))
1987 sub.type=eServiceReference::idInvalid;
1991 RESULT eDVBServicePlay::startTimeshift()
1993 ePtr<iDVBDemux> demux;
1995 eDebug("Start timeshift!");
1997 if (m_timeshift_enabled)
2000 /* start recording with the data demux. */
2001 if (m_service_handler.getDataDemux(demux))
2004 demux->createTSRecorder(m_record);
2009 if(ePythonConfigQuery::getConfigValue("config.usage.timeshift_path", tspath) == -1){
2010 eDebug("could not query ts path");
2013 tspath.append("/timeshift.XXXXXX");
2015 templ = new char[tspath.length() + 1];
2016 strcpy(templ, tspath.c_str());
2018 m_timeshift_fd = mkstemp(templ);
2019 m_timeshift_file = std::string(templ);
2021 eDebug("recording to %s", templ);
2025 if (m_timeshift_fd < 0)
2031 m_record->setTargetFD(m_timeshift_fd);
2033 m_timeshift_enabled = 1;
2035 updateTimeshiftPids();
2041 RESULT eDVBServicePlay::stopTimeshift()
2043 if (!m_timeshift_enabled)
2048 m_timeshift_enabled = 0;
2053 close(m_timeshift_fd);
2054 eDebug("remove timeshift file");
2055 eBackgroundFileEraser::getInstance()->erase(m_timeshift_file.c_str());
2060 int eDVBServicePlay::isTimeshiftActive()
2062 return m_timeshift_enabled && m_timeshift_active;
2065 RESULT eDVBServicePlay::activateTimeshift()
2067 if (!m_timeshift_enabled)
2070 if (!m_timeshift_active)
2072 switchToTimeshift();
2079 PyObject *eDVBServicePlay::getCutList()
2081 ePyObject list = PyList_New(0);
2083 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2085 ePyObject tuple = PyTuple_New(2);
2086 PyTuple_SET_ITEM(tuple, 0, PyLong_FromLongLong(i->where));
2087 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(i->what));
2088 PyList_Append(list, tuple);
2095 void eDVBServicePlay::setCutList(ePyObject list)
2097 if (!PyList_Check(list))
2099 int size = PyList_Size(list);
2102 m_cue_entries.clear();
2104 for (i=0; i<size; ++i)
2106 ePyObject tuple = PyList_GET_ITEM(list, i);
2107 if (!PyTuple_Check(tuple))
2109 eDebug("non-tuple in cutlist");
2112 if (PyTuple_Size(tuple) != 2)
2114 eDebug("cutlist entries need to be a 2-tuple");
2117 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
2118 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
2120 eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
2123 pts_t pts = PyLong_AsLongLong(ppts);
2124 int type = PyInt_AsLong(ptype);
2125 m_cue_entries.insert(cueEntry(pts, type));
2126 eDebug("adding %08llx, %d", pts, type);
2128 m_cuesheet_changed = 1;
2130 cutlistToCuesheet();
2131 m_event((iPlayableService*)this, evCuesheetChanged);
2134 void eDVBServicePlay::setCutListEnable(int enable)
2136 m_cutlist_enabled = enable;
2137 cutlistToCuesheet();
2140 void eDVBServicePlay::updateTimeshiftPids()
2145 eDVBServicePMTHandler::program program;
2146 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2148 if (h.getProgramInfo(program))
2152 std::set<int> pids_to_record;
2153 pids_to_record.insert(0); // PAT
2154 if (program.pmtPid != -1)
2155 pids_to_record.insert(program.pmtPid); // PMT
2157 if (program.textPid != -1)
2158 pids_to_record.insert(program.textPid); // Videotext
2160 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2161 i(program.videoStreams.begin());
2162 i != program.videoStreams.end(); ++i)
2163 pids_to_record.insert(i->pid);
2165 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2166 i(program.audioStreams.begin());
2167 i != program.audioStreams.end(); ++i)
2168 pids_to_record.insert(i->pid);
2170 for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
2171 i(program.subtitleStreams.begin());
2172 i != program.subtitleStreams.end(); ++i)
2173 pids_to_record.insert(i->pid);
2175 std::set<int> new_pids, obsolete_pids;
2177 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
2178 m_pids_active.begin(), m_pids_active.end(),
2179 std::inserter(new_pids, new_pids.begin()));
2181 std::set_difference(
2182 m_pids_active.begin(), m_pids_active.end(),
2183 pids_to_record.begin(), pids_to_record.end(),
2184 std::inserter(new_pids, new_pids.begin())
2187 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
2188 m_record->addPID(*i);
2190 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
2191 m_record->removePID(*i);
2195 void eDVBServicePlay::switchToLive()
2197 if (!m_timeshift_active)
2200 eDebug("SwitchToLive");
2205 m_teletext_parser = 0;
2207 m_subtitle_parser = 0;
2208 m_new_dvb_subtitle_page_connection = 0;
2209 m_new_subtitle_page_connection = 0;
2210 m_rds_decoder_event_connection = 0;
2211 m_video_event_connection = 0;
2213 /* free the timeshift service handler, we need the resources */
2214 m_service_handler_timeshift.free();
2215 m_timeshift_active = 0;
2217 m_event((iPlayableService*)this, evSeekableStatusChanged);
2222 void eDVBServicePlay::switchToTimeshift()
2224 if (m_timeshift_active)
2229 m_teletext_parser = 0;
2231 m_subtitle_parser = 0;
2232 m_new_subtitle_page_connection = 0;
2233 m_new_dvb_subtitle_page_connection = 0;
2234 m_rds_decoder_event_connection = 0;
2235 m_video_event_connection = 0;
2237 m_timeshift_active = 1;
2239 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
2240 r.path = m_timeshift_file;
2242 m_cue = new eCueSheet();
2243 m_service_handler_timeshift.tune(r, 1, m_cue, 0, m_dvb_service); /* use the decoder demux for everything */
2245 eDebug("eDVBServicePlay::switchToTimeshift, in pause mode now.");
2247 updateDecoder(); /* mainly to switch off PCR, and to set pause */
2249 m_event((iPlayableService*)this, evSeekableStatusChanged);
2252 void eDVBServicePlay::updateDecoder()
2254 int vpid = -1, vpidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
2256 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2258 eDVBServicePMTHandler::program program;
2259 if (h.getProgramInfo(program))
2260 eDebug("getting program info failed.");
2263 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
2264 if (!program.videoStreams.empty())
2266 eDebugNoNewLine(" (");
2267 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
2268 i(program.videoStreams.begin());
2269 i != program.videoStreams.end(); ++i)
2276 if (i != program.videoStreams.begin())
2277 eDebugNoNewLine(", ");
2278 eDebugNoNewLine("%04x", i->pid);
2280 eDebugNoNewLine(")");
2282 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
2283 if (!program.audioStreams.empty())
2285 eDebugNoNewLine(" (");
2286 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
2287 i(program.audioStreams.begin());
2288 i != program.audioStreams.end(); ++i)
2290 if (i != program.audioStreams.begin())
2291 eDebugNoNewLine(", ");
2292 eDebugNoNewLine("%04x", i->pid);
2294 eDebugNoNewLine(")");
2296 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
2297 pcrpid = program.pcrPid;
2298 eDebug(", and the text pid is %04x", program.textPid);
2299 tpid = program.textPid;
2304 h.getDecodeDemux(m_decode_demux);
2307 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
2309 m_decoder->connectVideoEvent(slot(*this, &eDVBServicePlay::video_event), m_video_event_connection);
2310 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
2311 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
2312 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
2313 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
2316 m_teletext_parser = 0;
2317 m_subtitle_parser = 0;
2321 m_cue->setDecodingDemux(m_decode_demux, m_decoder);
2328 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
2329 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2330 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2334 eServiceReferenceDVB ref;
2335 m_service_handler.getServiceReference(ref);
2336 eServiceReferenceDVB parent = ref.getParentServiceReference();
2341 ePtr<eDVBResourceManager> res_mgr;
2342 if (!eDVBResourceManager::getInstance(res_mgr))
2344 ePtr<iDVBChannelList> db;
2345 if (!res_mgr->getChannelList(db))
2347 ePtr<eDVBService> origService;
2348 if (!db->getService(parent, origService))
2350 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
2351 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
2358 std::string config_delay;
2359 int config_delay_int = 0;
2360 if(ePythonConfigQuery::getConfigValue("config.av.generalAC3delay", config_delay) == 0)
2361 config_delay_int = atoi(config_delay.c_str());
2362 m_decoder->setAC3Delay(ac3_delay == -1 ? config_delay_int : ac3_delay + config_delay_int);
2364 if(ePythonConfigQuery::getConfigValue("config.av.generalPCMdelay", config_delay) == 0)
2365 config_delay_int = atoi(config_delay.c_str());
2367 config_delay_int = 0;
2368 m_decoder->setPCMDelay(pcm_delay == -1 ? config_delay_int : pcm_delay + config_delay_int);
2370 m_decoder->setVideoPID(vpid, vpidtype);
2371 selectAudioStream();
2373 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
2374 m_decoder->setSyncPCR(pcrpid);
2376 m_decoder->setSyncPCR(-1);
2378 m_decoder->setTextPID(tpid);
2380 m_teletext_parser->start(program.textPid);
2382 if (vpid > 0 && vpid < 0x2000)
2386 std::string radio_pic;
2387 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
2388 m_decoder->setRadioPic(radio_pic);
2391 /* if (!m_is_primary)
2392 m_decoder->setTrickmode();
2393 else */ if (m_is_paused)
2398 m_decoder->setAudioChannel(achannel);
2400 /* don't worry about non-existing services, nor pvr services */
2403 /* (audio pid will be set in selectAudioTrack */
2404 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
2405 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
2406 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
2407 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
2410 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
2413 void eDVBServicePlay::loadCuesheet()
2415 std::string filename = m_reference.path + ".cuts";
2417 m_cue_entries.clear();
2419 FILE *f = fopen(filename.c_str(), "rb");
2423 eDebug("loading cuts..");
2426 unsigned long long where;
2429 if (!fread(&where, sizeof(where), 1, f))
2431 if (!fread(&what, sizeof(what), 1, f))
2434 #if BYTE_ORDER == LITTLE_ENDIAN
2435 where = bswap_64(where);
2442 m_cue_entries.insert(cueEntry(where, what));
2445 eDebug("%d entries", m_cue_entries.size());
2447 eDebug("cutfile not found!");
2449 m_cuesheet_changed = 0;
2450 cutlistToCuesheet();
2451 m_event((iPlayableService*)this, evCuesheetChanged);
2454 void eDVBServicePlay::saveCuesheet()
2456 std::string filename = m_reference.path + ".cuts";
2458 FILE *f = fopen(filename.c_str(), "wb");
2462 unsigned long long where;
2465 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
2467 #if BYTE_ORDER == BIG_ENDIAN
2470 where = bswap_64(i->where);
2472 what = htonl(i->what);
2473 fwrite(&where, sizeof(where), 1, f);
2474 fwrite(&what, sizeof(what), 1, f);
2480 m_cuesheet_changed = 0;
2483 void eDVBServicePlay::cutlistToCuesheet()
2487 eDebug("no cue sheet");
2492 if (!m_cutlist_enabled)
2494 m_cue->commitSpans();
2495 eDebug("cutlists were disabled");
2499 pts_t in = 0, out = 0, length = 0;
2503 std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
2505 int have_any_span = 0;
2509 if (i == m_cue_entries.end())
2515 if (i->what == 0) /* in */
2519 } else if (i->what == 1) /* out */
2521 else /* mark (2) or last play position (3) */
2540 m_cue->addSourceSpan(in, out);
2545 if (i == m_cue_entries.end())
2548 m_cue->commitSpans();
2551 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
2553 if (m_subtitle_widget)
2554 disableSubtitles(parent);
2557 int tuplesize = PyTuple_Size(tuple);
2560 if (!PyTuple_Check(tuple))
2566 entry = PyTuple_GET_ITEM(tuple, 0);
2568 if (!PyInt_Check(entry))
2571 type = PyInt_AsLong(entry);
2573 if (type == 1) // teletext subtitles
2575 int page, magazine, pid;
2579 if (!m_teletext_parser)
2581 eDebug("enable teletext subtitles.. no parser !!!");
2585 entry = PyTuple_GET_ITEM(tuple, 1);
2586 if (!PyInt_Check(entry))
2588 pid = PyInt_AsLong(entry);
2590 entry = PyTuple_GET_ITEM(tuple, 2);
2591 if (!PyInt_Check(entry))
2593 page = PyInt_AsLong(entry);
2595 entry = PyTuple_GET_ITEM(tuple, 3);
2596 if (!PyInt_Check(entry))
2598 magazine = PyInt_AsLong(entry);
2600 m_subtitle_widget = new eSubtitleWidget(parent);
2601 m_subtitle_widget->resize(parent->size()); /* full size */
2602 m_teletext_parser->setPageAndMagazine(page, magazine);
2604 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
2608 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
2609 if (!m_subtitle_parser)
2611 eDebug("enable dvb subtitles.. no parser !!!");
2617 entry = PyTuple_GET_ITEM(tuple, 1);
2618 if (!PyInt_Check(entry))
2620 pid = PyInt_AsLong(entry);
2622 entry = PyTuple_GET_ITEM(tuple, 2);
2623 if (!PyInt_Check(entry))
2625 composition_page_id = PyInt_AsLong(entry);
2627 entry = PyTuple_GET_ITEM(tuple, 3);
2628 if (!PyInt_Check(entry))
2630 ancillary_page_id = PyInt_AsLong(entry);
2632 m_subtitle_widget = new eSubtitleWidget(parent);
2633 m_subtitle_widget->resize(parent->size()); /* full size */
2634 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
2636 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
2642 eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
2643 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
2644 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
2648 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
2650 delete m_subtitle_widget;
2651 m_subtitle_widget = 0;
2652 if (m_subtitle_parser)
2654 m_subtitle_parser->stop();
2655 m_dvb_subtitle_pages.clear();
2657 if (m_teletext_parser)
2659 m_teletext_parser->setPageAndMagazine(-1, -1);
2660 m_subtitle_pages.clear();
2663 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
2667 PyObject *eDVBServicePlay::getCachedSubtitle()
2671 int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
2674 unsigned int data = (unsigned int)tmp;
2675 int pid = (data&0xFFFF0000)>>16;
2676 ePyObject tuple = PyTuple_New(4);
2677 eDVBServicePMTHandler::program program;
2678 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2679 if (!h.getProgramInfo(program))
2681 if (program.textPid==pid) // teletext
2682 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
2684 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
2685 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
2686 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
2687 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
2695 PyObject *eDVBServicePlay::getSubtitleList()
2697 if (!m_teletext_parser)
2700 ePyObject l = PyList_New(0);
2701 std::set<int> added_ttx_pages;
2703 std::set<eDVBServicePMTHandler::subtitleStream> &subs =
2704 m_teletext_parser->m_found_subtitle_pages;
2706 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2707 eDVBServicePMTHandler::program program;
2708 if (h.getProgramInfo(program))
2709 eDebug("getting program info failed.");
2712 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
2713 it != program.subtitleStreams.end(); ++it)
2715 switch(it->subtitling_type)
2717 case 0x01: // ebu teletext subtitles
2719 int page_number = it->teletext_page_number & 0xFF;
2720 int magazine_number = it->teletext_magazine_number & 7;
2721 int hash = magazine_number << 8 | page_number;
2722 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2724 ePyObject tuple = PyTuple_New(5);
2725 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2726 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2727 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2728 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2729 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2730 PyList_Append(l, tuple);
2732 added_ttx_pages.insert(hash);
2737 case 0x20 ... 0x23: // dvb subtitles
2739 ePyObject tuple = PyTuple_New(5);
2740 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
2741 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2742 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
2743 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
2744 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2745 PyList_Insert(l, 0, tuple);
2753 for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
2754 it != subs.end(); ++it)
2756 int page_number = it->teletext_page_number & 0xFF;
2757 int magazine_number = it->teletext_magazine_number & 7;
2758 int hash = magazine_number << 8 | page_number;
2759 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2761 ePyObject tuple = PyTuple_New(5);
2762 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2763 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2764 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2765 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2766 PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
2767 PyList_Append(l, tuple);
2775 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
2777 if (m_subtitle_widget)
2781 m_decoder->getPTS(0, pos);
2782 eDebug("got new subtitle page %lld %lld %d", pos, page.m_pts, page.m_have_pts);
2783 m_subtitle_pages.push_back(page);
2784 checkSubtitleTiming();
2788 void eDVBServicePlay::checkSubtitleTiming()
2790 eDebug("checkSubtitleTiming");
2791 if (!m_subtitle_widget)
2795 enum { TELETEXT, DVB } type;
2796 eDVBTeletextSubtitlePage page;
2797 eDVBSubtitlePage dvb_page;
2799 if (!m_subtitle_pages.empty())
2801 page = m_subtitle_pages.front();
2803 show_time = page.m_pts;
2805 else if (!m_dvb_subtitle_pages.empty())
2807 dvb_page = m_dvb_subtitle_pages.front();
2809 show_time = dvb_page.m_show_time;
2817 m_decoder->getPTS(0, pos);
2819 eDebug("%lld %lld", pos, show_time);
2820 int diff = show_time - pos;
2823 eDebug("[late (%d ms)]", -diff / 90);
2826 // if (diff > 900000)
2828 // eDebug("[invalid]");
2834 if (type == TELETEXT)
2836 eDebug("display teletext subtitle page %lld", show_time);
2837 m_subtitle_widget->setPage(page);
2838 m_subtitle_pages.pop_front();
2842 eDebug("display dvb subtitle Page %lld", show_time);
2843 m_subtitle_widget->setPage(dvb_page);
2844 m_dvb_subtitle_pages.pop_front();
2848 eDebug("start subtitle delay %d", diff / 90);
2849 m_subtitle_sync_timer->start(diff / 90, 1);
2855 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
2857 if (m_subtitle_widget)
2861 m_decoder->getPTS(0, pos);
2862 eDebug("got new subtitle page %lld %lld", pos, p.m_show_time);
2863 m_dvb_subtitle_pages.push_back(p);
2864 checkSubtitleTiming();
2868 int eDVBServicePlay::getAC3Delay()
2871 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2873 return m_decoder->getAC3Delay();
2878 int eDVBServicePlay::getPCMDelay()
2881 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2883 return m_decoder->getPCMDelay();
2888 void eDVBServicePlay::setAC3Delay(int delay)
2891 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2893 m_decoder->setAC3Delay(delay);
2896 void eDVBServicePlay::setPCMDelay(int delay)
2899 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2901 m_decoder->setPCMDelay(delay);
2904 void eDVBServicePlay::video_event(struct iTSMPEGDecoder::videoEvent event)
2906 switch(event.type) {
2907 case iTSMPEGDecoder::videoEvent::eventSizeChanged:
2908 m_event((iPlayableService*)this, evVideoSizeChanged);
2910 case iTSMPEGDecoder::videoEvent::eventFrameRateChanged:
2911 m_event((iPlayableService*)this, evVideoFramerateChanged);
2913 case iTSMPEGDecoder::videoEvent::eventProgressiveChanged:
2914 m_event((iPlayableService*)this, evVideoProgressiveChanged);
2921 RESULT eDVBServicePlay::stream(ePtr<iStreamableService> &ptr)
2927 PyObject *eDVBServicePlay::getStreamingData()
2929 eDVBServicePMTHandler::program program;
2930 if (m_service_handler.getProgramInfo(program))
2935 ePyObject r = program.createPythonObject();
2936 ePtr<iDVBDemux> demux;
2937 if (!m_service_handler.getDataDemux(demux))
2940 if (!demux->getCADemuxID(demux_id))
2941 PutToDict(r, "demux", demux_id);
2948 DEFINE_REF(eDVBServicePlay)
2950 PyObject *eDVBService::getInfoObject(const eServiceReference &ref, int w)
2954 case iServiceInformation::sTransponderData:
2955 return eStaticServiceDVBInformation().getInfoObject(ref, w);
2959 return iStaticServiceInformation::getInfoObject(ref, w);
2962 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");