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/base/nconfig.h> // access to python config
10 #include <lib/dvb/dvb.h>
11 #include <lib/dvb/db.h>
12 #include <lib/dvb/decoder.h>
14 #include <lib/components/file_eraser.h>
15 #include <lib/service/servicedvbrecord.h>
16 #include <lib/service/event.h>
17 #include <lib/dvb/metaparser.h>
18 #include <lib/dvb/tstools.h>
19 #include <lib/python/python.h>
22 #include <lib/gui/esubtitle.h>
28 #include <netinet/in.h>
31 #error no byte order defined!
34 #define TSPATH "/media/hdd"
36 class eStaticServiceDVBInformation: public iStaticServiceInformation
38 DECLARE_REF(eStaticServiceDVBInformation);
40 RESULT getName(const eServiceReference &ref, std::string &name);
41 int getLength(const eServiceReference &ref);
42 int isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
45 DEFINE_REF(eStaticServiceDVBInformation);
47 RESULT eStaticServiceDVBInformation::getName(const eServiceReference &ref, std::string &name)
49 eServiceReferenceDVB &service = (eServiceReferenceDVB&)ref;
50 if ( !ref.name.empty() )
52 if (service.getParentTransportStreamID().get()) // linkage subservice
54 ePtr<iServiceHandler> service_center;
55 if (!eServiceCenter::getInstance(service_center))
57 eServiceReferenceDVB parent = service;
58 parent.setTransportStreamID( service.getParentTransportStreamID() );
59 parent.setServiceID( service.getParentServiceID() );
60 parent.setParentTransportStreamID(eTransportStreamID(0));
61 parent.setParentServiceID(eServiceID(0));
63 ePtr<iStaticServiceInformation> service_info;
64 if (!service_center->info(parent, service_info))
66 if (!service_info->getName(parent, name))
68 // just show short name
69 unsigned int pos = name.find("\xc2\x86");
70 if ( pos != std::string::npos )
72 pos = name.find("\xc2\x87");
73 if ( pos != std::string::npos )
89 int eStaticServiceDVBInformation::getLength(const eServiceReference &ref)
94 int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore)
96 ePtr<eDVBResourceManager> res_mgr;
97 if ( eDVBResourceManager::getInstance( res_mgr ) )
98 eDebug("isPlayble... no res manager!!");
101 eDVBChannelID chid, chid_ignore;
102 ((const eServiceReferenceDVB&)ref).getChannelID(chid);
103 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
104 return res_mgr->canAllocateChannel(chid, chid_ignore);
109 DEFINE_REF(eStaticServiceDVBBouquetInformation);
111 RESULT eStaticServiceDVBBouquetInformation::getName(const eServiceReference &ref, std::string &name)
113 ePtr<iDVBChannelList> db;
114 ePtr<eDVBResourceManager> res;
117 if ((err = eDVBResourceManager::getInstance(res)) != 0)
119 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no resource manager!");
122 if ((err = res->getChannelList(db)) != 0)
124 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. no channel list!");
129 if ((err = db->getBouquet(ref, bouquet)) != 0)
131 eDebug("eStaticServiceDVBBouquetInformation::getName failed.. getBouquet failed!");
135 if ( bouquet && bouquet->m_bouquet_name.length() )
137 name = bouquet->m_bouquet_name;
144 int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref, const eServiceReference &ignore)
146 if (ref.flags & eServiceReference::isGroup)
148 ePtr<iDVBChannelList> db;
149 ePtr<eDVBResourceManager> res;
151 if (eDVBResourceManager::getInstance(res))
153 eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no resource manager!");
157 if (res->getChannelList(db))
159 eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. no channel list!");
164 if (db->getBouquet(ref, bouquet))
166 eDebug("eStaticServiceDVBBouquetInformation::isPlayable failed.. getBouquet failed!");
171 eDVBChannelID chid, chid_ignore;
172 ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore);
173 for (std::list<eServiceReference>::iterator it(bouquet->m_services.begin()); it != bouquet->m_services.end(); ++it)
175 ((const eServiceReferenceDVB&)*it).getChannelID(chid);
176 int tmp=res->canAllocateChannel(chid, chid_ignore);
179 m_playable_service = *it;
186 m_playable_service = eServiceReference();
190 int eStaticServiceDVBBouquetInformation::getLength(const eServiceReference &ref)
195 #include <lib/dvb/epgcache.h>
197 RESULT eStaticServiceDVBBouquetInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &ptr, time_t start_time)
199 return eEPGCache::getInstance()->lookupEventTime(ref, start_time, ptr);
202 class eStaticServiceDVBPVRInformation: public iStaticServiceInformation
204 DECLARE_REF(eStaticServiceDVBPVRInformation);
205 eServiceReference m_ref;
206 eDVBMetaParser m_parser;
208 eStaticServiceDVBPVRInformation(const eServiceReference &ref);
209 RESULT getName(const eServiceReference &ref, std::string &name);
210 int getLength(const eServiceReference &ref);
211 RESULT getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time);
212 int isPlayable(const eServiceReference &ref, const eServiceReference &ignore) { return 1; }
213 int getInfo(const eServiceReference &ref, int w);
214 std::string getInfoString(const eServiceReference &ref,int w);
217 DEFINE_REF(eStaticServiceDVBPVRInformation);
219 eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref)
222 m_parser.parseFile(ref.path);
225 RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name)
227 ASSERT(ref == m_ref);
228 name = m_parser.m_name.size() ? m_parser.m_name : ref.path;
232 int eStaticServiceDVBPVRInformation::getLength(const eServiceReference &ref)
234 ASSERT(ref == m_ref);
238 if (tstools.openFile(ref.path.c_str()))
242 if (tstools.calcLen(len))
248 int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
252 case iServiceInformation::sDescription:
253 return iServiceInformation::resIsString;
254 case iServiceInformation::sServiceref:
255 return iServiceInformation::resIsString;
256 case iServiceInformation::sTimeCreate:
257 if (m_parser.m_time_create)
258 return m_parser.m_time_create;
260 return iServiceInformation::resNA;
262 return iServiceInformation::resNA;
266 std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
270 case iServiceInformation::sDescription:
271 return m_parser.m_description;
272 case iServiceInformation::sServiceref:
273 return m_parser.m_ref.toString();
274 case iServiceInformation::sTags:
275 return m_parser.m_tags;
281 RESULT eStaticServiceDVBPVRInformation::getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &evt, time_t start_time)
283 if (!ref.path.empty())
285 ePtr<eServiceEvent> event = new eServiceEvent;
286 std::string filename = ref.path;
287 filename.erase(filename.length()-2, 2);
289 if (!event->parseFrom(filename, (m_parser.m_ref.getTransportStreamID().get()<<16)|m_parser.m_ref.getOriginalNetworkID().get()))
299 class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
301 DECLARE_REF(eDVBPVRServiceOfflineOperations);
302 eServiceReferenceDVB m_ref;
304 eDVBPVRServiceOfflineOperations(const eServiceReference &ref);
306 RESULT deleteFromDisk(int simulate);
307 RESULT getListOfFilenames(std::list<std::string> &);
310 DEFINE_REF(eDVBPVRServiceOfflineOperations);
312 eDVBPVRServiceOfflineOperations::eDVBPVRServiceOfflineOperations(const eServiceReference &ref): m_ref((const eServiceReferenceDVB&)ref)
316 RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
322 std::list<std::string> res;
323 if (getListOfFilenames(res))
326 eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
328 eDebug("FATAL !! can't get background file eraser");
330 for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
332 eDebug("Removing %s...", i->c_str());
334 eraser->erase(i->c_str());
336 ::unlink(i->c_str());
343 RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string> &res)
346 res.push_back(m_ref.path);
348 // handling for old splitted recordings (enigma 1)
353 snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
355 if (stat(buf, &s) < 0)
360 res.push_back(m_ref.path + ".meta");
361 res.push_back(m_ref.path + ".ap");
362 res.push_back(m_ref.path + ".cuts");
363 std::string tmp = m_ref.path;
364 tmp.erase(m_ref.path.length()-3);
365 res.push_back(tmp + ".eit");
369 DEFINE_REF(eServiceFactoryDVB)
371 eServiceFactoryDVB::eServiceFactoryDVB()
373 ePtr<eServiceCenter> sc;
375 eServiceCenter::getPrivInstance(sc);
377 sc->addServiceFactory(eServiceFactoryDVB::id, this);
379 m_StaticServiceDVBInfo = new eStaticServiceDVBInformation;
380 m_StaticServiceDVBBouquetInfo = new eStaticServiceDVBBouquetInformation;
383 eServiceFactoryDVB::~eServiceFactoryDVB()
385 ePtr<eServiceCenter> sc;
387 eServiceCenter::getPrivInstance(sc);
389 sc->removeServiceFactory(eServiceFactoryDVB::id);
392 DEFINE_REF(eDVBServiceList);
394 eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent)
398 eDVBServiceList::~eDVBServiceList()
402 RESULT eDVBServiceList::startQuery()
404 ePtr<iDVBChannelList> db;
405 ePtr<eDVBResourceManager> res;
408 if ((err = eDVBResourceManager::getInstance(res)) != 0)
410 eDebug("no resource manager");
413 if ((err = res->getChannelList(db)) != 0)
415 eDebug("no channel list");
419 ePtr<eDVBChannelQuery> q;
421 if (!m_parent.path.empty())
423 eDVBChannelQuery::compile(q, m_parent.path);
426 eDebug("compile query failed");
431 if ((err = db->startQuery(m_query, q, m_parent)) != 0)
433 eDebug("startQuery failed");
440 RESULT eDVBServiceList::getContent(std::list<eServiceReference> &list, bool sorted)
442 eServiceReferenceDVB ref;
447 while (!m_query->getNextResult(ref))
451 list.sort(iListableServiceCompare(this));
456 // The first argument of this function is a format string to specify the order and
457 // the content of the returned list
458 // useable format options are
459 // R = Service Reference (as swig object .. this is very slow)
460 // S = Service Reference (as python string object .. same as ref.toString())
461 // C = Service Reference (as python string object .. same as ref.toCompareString())
462 // N = Service Name (as python string object)
463 // when exactly one return value per service is selected in the format string,
464 // then each value is directly a list entry
465 // when more than one value is returned per service, then the list is a list of
467 // unknown format string chars are returned as python None values !
468 PyObject *eDVBServiceList::getContent(const char* format, bool sorted)
471 std::list<eServiceReference> tmplist;
474 if (!format || !(retcount=strlen(format)))
475 format = "R"; // just return service reference swig object ...
477 if (!getContent(tmplist, sorted))
479 int services=tmplist.size();
480 ePtr<iStaticServiceInformation> sptr;
481 eServiceCenterPtr service_center;
483 if (strchr(format, 'N'))
484 eServiceCenter::getPrivInstance(service_center);
486 ret = PyList_New(services);
487 std::list<eServiceReference>::iterator it(tmplist.begin());
489 for (int cnt=0; cnt < services; ++cnt)
491 eServiceReference &ref=*it++;
492 ePyObject tuple = retcount > 1 ? PyTuple_New(retcount) : ePyObject();
493 for (int i=0; i < retcount; ++i)
498 case 'R': // service reference (swig)object
499 tmp = NEW_eServiceReference(ref);
501 case 'C': // service reference compare string
502 tmp = PyString_FromString(ref.toCompareString().c_str());
504 case 'S': // service reference string
505 tmp = PyString_FromString(ref.toString().c_str());
507 case 'N': // service name
510 service_center->info(ref, sptr);
514 sptr->getName(ref, name);
516 tmp = PyString_FromString(name.c_str());
520 tmp = PyString_FromString("<n/a>");
533 PyTuple_SET_ITEM(tuple, i, tmp);
535 PyList_SET_ITEM(ret, cnt, tmp);
539 PyList_SET_ITEM(ret, cnt, tuple);
542 return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
545 RESULT eDVBServiceList::getNext(eServiceReference &ref)
550 return m_query->getNextResult((eServiceReferenceDVB&)ref);
553 RESULT eDVBServiceList::startEdit(ePtr<iMutableServiceList> &res)
555 if (m_parent.flags & eServiceReference::canDescent) // bouquet
557 ePtr<iDVBChannelList> db;
558 ePtr<eDVBResourceManager> resm;
560 if (eDVBResourceManager::getInstance(resm) || resm->getChannelList(db))
563 if (db->getBouquet(m_parent, m_bouquet) != 0)
574 RESULT eDVBServiceList::addService(eServiceReference &ref, eServiceReference before)
578 return m_bouquet->addService(ref, before);
581 RESULT eDVBServiceList::removeService(eServiceReference &ref)
585 return m_bouquet->removeService(ref);
588 RESULT eDVBServiceList::moveService(eServiceReference &ref, int pos)
592 return m_bouquet->moveService(ref, pos);
595 RESULT eDVBServiceList::flushChanges()
599 return m_bouquet->flushChanges();
602 RESULT eDVBServiceList::setListName(const std::string &name)
606 return m_bouquet->setListName(name);
609 RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
611 ePtr<eDVBService> service;
612 int r = lookupService(service, ref);
615 // check resources...
616 ptr = new eDVBServicePlay(ref, service);
620 RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
622 if (ref.path.empty())
624 ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref);
633 RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
635 ePtr<eDVBServiceList> list = new eDVBServiceList(ref);
636 if (list->startQuery())
646 RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
648 /* is a listable service? */
649 if (ref.flags & eServiceReference::canDescent) // bouquet
651 if ( !ref.name.empty() ) // satellites or providers list
652 ptr = m_StaticServiceDVBInfo;
653 else // a dvb bouquet
654 ptr = m_StaticServiceDVBBouquetInfo;
656 else if (!ref.path.empty()) /* do we have a PVR service? */
657 ptr = new eStaticServiceDVBPVRInformation(ref);
658 else // normal dvb service
660 ePtr<eDVBService> service;
661 if (lookupService(service, ref)) // no eDVBService avail for this reference ( Linkage Services... )
662 ptr = m_StaticServiceDVBInfo;
664 /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */
670 RESULT eServiceFactoryDVB::offlineOperations(const eServiceReference &ref, ePtr<iServiceOfflineOperations> &ptr)
672 if (ref.path.empty())
678 ptr = new eDVBPVRServiceOfflineOperations(ref);
683 RESULT eServiceFactoryDVB::lookupService(ePtr<eDVBService> &service, const eServiceReference &ref)
685 // TODO: handle the listing itself
686 // if (ref.... == -1) .. return "... bouquets ...";
687 // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists
689 ePtr<iDVBChannelList> db;
690 ePtr<eDVBResourceManager> res;
693 if ((err = eDVBResourceManager::getInstance(res)) != 0)
695 eDebug("no resource manager");
698 if ((err = res->getChannelList(db)) != 0)
700 eDebug("no channel list");
704 /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */
705 if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0)
707 eDebug("getService failed!");
714 eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service):
715 m_reference(ref), m_dvb_service(service), m_have_video_pid(0), m_is_paused(0)
718 m_is_pvr = !m_reference.path.empty();
720 m_timeshift_enabled = m_timeshift_active = 0;
723 CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
724 CONNECT(m_service_handler_timeshift.serviceEvent, eDVBServicePlay::serviceEventTimeshift);
725 CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
727 m_cuesheet_changed = 0;
728 m_cutlist_enabled = 1;
730 m_subtitle_widget = 0;
734 CONNECT(m_subtitle_sync_timer.timeout, eDVBServicePlay::checkSubtitleTiming);
737 eDVBServicePlay::~eDVBServicePlay()
739 delete m_subtitle_widget;
742 void eDVBServicePlay::gotNewEvent()
746 ePtr<eServiceEvent> m_event_now, m_event_next;
747 getEvent(m_event_now, 0);
748 getEvent(m_event_next, 1);
751 eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration);
753 eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration);
755 m_event((iPlayableService*)this, evUpdatedEventInfo);
758 void eDVBServicePlay::serviceEvent(int event)
760 m_tune_state = event;
764 case eDVBServicePMTHandler::eventTuned:
766 ePtr<iDVBDemux> m_demux;
767 if (!m_service_handler.getDataDemux(m_demux))
769 eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
770 int sid = ref.getParentServiceID().get();
772 sid = ref.getServiceID().get();
773 if ( ref.getParentTransportStreamID().get() &&
774 ref.getParentTransportStreamID() != ref.getTransportStreamID() )
775 m_event_handler.startOther(m_demux, sid);
777 m_event_handler.start(m_demux, sid);
781 case eDVBServicePMTHandler::eventNoPAT:
782 case eDVBServicePMTHandler::eventNoPATEntry:
783 case eDVBServicePMTHandler::eventNoPMT:
784 case eDVBServicePMTHandler::eventTuneFailed:
786 eDebug("DVB service failed to tune - error %d", event);
787 m_event((iPlayableService*)this, evTuneFailed);
790 case eDVBServicePMTHandler::eventNewProgramInfo:
792 eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
793 if (m_timeshift_enabled)
794 updateTimeshiftPids();
795 if (!m_timeshift_active)
797 if (m_first_program_info && m_is_pvr)
799 m_first_program_info = 0;
802 m_event((iPlayableService*)this, evUpdatedInfo);
805 case eDVBServicePMTHandler::eventEOF:
806 m_event((iPlayableService*)this, evEOF);
808 case eDVBServicePMTHandler::eventSOF:
809 m_event((iPlayableService*)this, evSOF);
814 void eDVBServicePlay::serviceEventTimeshift(int event)
818 case eDVBServicePMTHandler::eventNewProgramInfo:
819 if (m_timeshift_active)
822 case eDVBServicePMTHandler::eventSOF:
823 m_event((iPlayableService*)this, evSOF);
825 case eDVBServicePMTHandler::eventEOF:
831 RESULT eDVBServicePlay::start()
834 /* in pvr mode, we only want to use one demux. in tv mode, we're using
835 two (one for decoding, one for data source), as we must be prepared
836 to start recording from the data demux. */
838 m_cue = new eCueSheet();
840 m_first_program_info = 1;
841 eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
842 r = m_service_handler.tune(service, m_is_pvr, m_cue);
844 /* inject EIT if there is a stored one */
847 std::string filename = service.path;
848 filename.erase(filename.length()-2, 2);
850 ePtr<eServiceEvent> event = new eServiceEvent;
851 if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
853 ePtr<eServiceEvent> empty;
854 m_event_handler.inject(event, 0);
855 m_event_handler.inject(empty, 1);
862 m_event(this, evStart);
863 m_event((iPlayableService*)this, evSeekableStatusChanged);
867 RESULT eDVBServicePlay::stop()
869 /* add bookmark for last play position */
873 if (!getPlayPosition(play_position))
875 /* remove last position */
876 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
878 if (i->what == 3) /* current play position */
880 m_cue_entries.erase(i);
881 i = m_cue_entries.begin();
887 m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
888 m_cuesheet_changed = 1;
892 stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
894 m_service_handler_timeshift.free();
895 m_service_handler.free();
897 if (m_is_pvr && m_cuesheet_changed)
900 /* save cuesheet only when main file is accessible. */
901 if (!::stat(m_reference.path.c_str(), &s))
908 RESULT eDVBServicePlay::setTarget(int target)
910 m_is_primary = !target;
914 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
916 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
920 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
922 /* note: we check for timeshift to be enabled,
923 not neccessary active. if you pause when timeshift
924 is not active, you should activate it when unpausing */
925 if ((!m_is_pvr) && (!m_timeshift_enabled))
935 RESULT eDVBServicePlay::setSlowMotion(int ratio)
938 return m_decoder->setSlowMotion(ratio);
943 RESULT eDVBServicePlay::setFastForward(int ratio)
945 int skipmode, ffratio;
951 } else if (ratio > 0)
959 } else // if (ratio < 0)
965 if (m_skipmode != skipmode)
967 eDebug("setting cue skipmode to %d", skipmode);
969 m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
972 m_skipmode = skipmode;
977 return m_decoder->setFastForward(ffratio);
980 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
982 if (m_is_pvr || m_timeshift_enabled)
992 /* TODO: when timeshift is enabled but not active, this doesn't work. */
993 RESULT eDVBServicePlay::getLength(pts_t &len)
995 ePtr<iDVBPVRChannel> pvr_channel;
997 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1000 return pvr_channel->getLength(len);
1003 RESULT eDVBServicePlay::pause()
1005 if (!m_is_paused && m_decoder)
1008 return m_decoder->freeze(0);
1013 RESULT eDVBServicePlay::unpause()
1015 if (m_is_paused && m_decoder)
1018 return m_decoder->unfreeze();
1023 RESULT eDVBServicePlay::seekTo(pts_t to)
1025 eDebug("eDVBServicePlay::seekTo: jump %lld", to);
1027 if (!m_decode_demux)
1030 ePtr<iDVBPVRChannel> pvr_channel;
1032 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1038 m_cue->seekTo(0, to);
1042 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
1044 eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
1046 if (!m_decode_demux)
1049 ePtr<iDVBPVRChannel> pvr_channel;
1051 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1056 /* HACK until we have skip-AP api */
1057 if ((to > 0) && (to < 100))
1065 m_cue->seekTo(mode, to);
1069 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
1071 ePtr<iDVBPVRChannel> pvr_channel;
1073 if (!m_decode_demux)
1076 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1081 /* if there is a decoder, use audio or video PTS */
1084 r = m_decoder->getPTS(0, pos);
1090 return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder ? 1 : 0);
1093 RESULT eDVBServicePlay::setTrickmode(int trick)
1096 m_decoder->setTrickmode(trick);
1100 RESULT eDVBServicePlay::isCurrentlySeekable()
1102 return m_is_pvr || m_timeshift_active;
1105 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1111 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1117 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1123 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1129 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1135 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1138 if (m_have_video_pid && // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
1139 (m_timeshift_enabled || !m_is_pvr))
1141 if (!m_timeshift_enabled)
1143 /* we need enough diskspace */
1145 if (statfs(TSPATH "/.", &fs) < 0)
1147 eDebug("statfs failed!");
1151 if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
1153 eDebug("not enough diskspace for timeshift! (less than 1GB)");
1163 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1174 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1180 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1186 RESULT eDVBServicePlay::radioText(ePtr<iRadioText> &ptr)
1192 RESULT eDVBServicePlay::getName(std::string &name)
1196 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1197 return i->getName(m_reference, name);
1201 m_dvb_service->getName(m_reference, name);
1205 else if (!m_reference.name.empty())
1206 eStaticServiceDVBInformation().getName(m_reference, name);
1208 name = "DVB service";
1212 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1214 return m_event_handler.getEvent(evt, nownext);
1217 int eDVBServicePlay::getInfo(int w)
1219 eDVBServicePMTHandler::program program;
1222 return resIsPyObject;
1224 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1226 int no_program_info = 0;
1228 if (h.getProgramInfo(program))
1229 no_program_info = 1;
1234 if (no_program_info) return -1;
1235 if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1237 ePtr<eServiceEvent> evt;
1238 if (!m_event_handler.getEvent(evt, 0))
1240 ePtr<eComponentData> data;
1241 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1243 if ( data->getStreamContent() == 1 )
1245 switch(data->getComponentType())
1248 case 1: // 4:3 SD PAL
1250 case 3: // 16:9 SD PAL
1251 case 4: // > 16:9 PAL
1252 case 5: // 4:3 SD NTSC
1254 case 7: // 16:9 SD NTSC
1255 case 8: // > 16:9 NTSC
1258 case 9: // 4:3 HD PAL
1260 case 0xB: // 16:9 HD PAL
1261 case 0xC: // > 16:9 HD PAL
1262 case 0xD: // 4:3 HD NTSC
1264 case 0xF: // 16:9 HD NTSC
1265 case 0x10: // > 16:9 HD PAL
1266 return data->getComponentType();
1273 case sIsCrypted: if (no_program_info) return -1; return program.isCrypted();
1274 case sVideoPID: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1275 case sVideoType: if (no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1276 case sAudioPID: if (no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1277 case sPCRPID: if (no_program_info) return -1; return program.pcrPid;
1278 case sPMTPID: if (no_program_info) return -1; return program.pmtPid;
1279 case sTXTPID: if (no_program_info) return -1; return program.textPid;
1280 case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1281 case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1282 case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1283 case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1284 case sProvider: if (!m_dvb_service) return -1; return -2;
1285 case sServiceref: return resIsString;
1286 case sDVBState: return m_tune_state;
1292 std::string eDVBServicePlay::getInfoString(int w)
1297 if (!m_dvb_service) return "";
1298 return m_dvb_service->m_provider_name;
1300 return m_reference.toString();
1304 return iServiceInformation::getInfoString(w);
1307 PyObject *eDVBServicePlay::getInfoObject(int w)
1312 return m_service_handler.getCaIds();
1316 return iServiceInformation::getInfoObject(w);
1319 int eDVBServicePlay::getNumberOfTracks()
1321 eDVBServicePMTHandler::program program;
1322 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1323 if (h.getProgramInfo(program))
1325 return program.audioStreams.size();
1328 RESULT eDVBServicePlay::selectTrack(unsigned int i)
1330 int ret = selectAudioStream(i);
1332 if (m_decoder->start())
1338 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
1340 eDVBServicePMTHandler::program program;
1341 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1343 if (h.getProgramInfo(program))
1346 if (i >= program.audioStreams.size())
1349 if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
1350 info.m_description = "MPEG";
1351 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
1352 info.m_description = "AC3";
1353 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
1354 info.m_description = "AAC";
1355 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
1356 info.m_description = "DTS";
1358 info.m_description = "???";
1360 if (program.audioStreams[i].component_tag != -1)
1362 ePtr<eServiceEvent> evt;
1363 if (!m_event_handler.getEvent(evt, 0))
1365 ePtr<eComponentData> data;
1366 if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
1367 info.m_language = data->getText();
1371 if (info.m_language.empty())
1372 info.m_language = program.audioStreams[i].language_code;
1377 int eDVBServicePlay::selectAudioStream(int i)
1379 eDVBServicePMTHandler::program program;
1380 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1382 if (h.getProgramInfo(program))
1385 if ((unsigned int)i >= program.audioStreams.size())
1391 if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
1394 if (m_radiotext_parser)
1395 m_radiotext_parser->start(program.audioStreams[i].pid);
1397 if (m_dvb_service && !m_is_pvr)
1399 if (program.audioStreams[i].type == eDVBAudio::aMPEG)
1401 m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[i].pid);
1402 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1406 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1407 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[i].pid);
1411 h.resetCachedProgram();
1416 int eDVBServicePlay::getCurrentChannel()
1418 return m_decoder ? m_decoder->getAudioChannel() : STEREO;
1421 RESULT eDVBServicePlay::selectChannel(int i)
1423 if (i < LEFT || i > RIGHT || i == STEREO)
1426 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
1428 m_decoder->setAudioChannel(i);
1432 std::string eDVBServicePlay::getRadioText(int x)
1434 if (m_radiotext_parser)
1438 return convertLatin1UTF8(m_radiotext_parser->getCurrentText());
1443 void eDVBServicePlay::radioTextUpdated()
1445 m_event((iPlayableService*)this, evUpdatedRadioText);
1448 int eDVBServiceBase::getFrontendInfo(int w)
1450 eUsePtr<iDVBChannel> channel;
1451 if(m_service_handler.getChannel(channel))
1453 ePtr<iDVBFrontend> fe;
1454 if(channel->getFrontend(fe))
1456 return fe->readFrontendData(w);
1459 PyObject *eDVBServiceBase::getFrontendData(bool original)
1463 eUsePtr<iDVBChannel> channel;
1464 if(!m_service_handler.getChannel(channel))
1466 ePtr<iDVBFrontend> fe;
1467 if(!channel->getFrontend(fe))
1469 ret = fe->readTransponderData(original);
1472 ePtr<iDVBFrontendParameters> feparm;
1473 channel->getCurrentFrontendParameters(feparm);
1476 eDVBFrontendParametersSatellite osat;
1477 if (!feparm->getDVBS(osat))
1479 void PutToDict(ePyObject &, const char*, long);
1480 void PutToDict(ePyObject &, const char*, const char*);
1481 PutToDict(ret, "orbital_position", osat.orbital_position);
1482 const char *tmp = "UNKNOWN";
1483 switch(osat.polarisation)
1485 case eDVBFrontendParametersSatellite::Polarisation::Horizontal: tmp="HORIZONTAL"; break;
1486 case eDVBFrontendParametersSatellite::Polarisation::Vertical: tmp="VERTICAL"; break;
1487 case eDVBFrontendParametersSatellite::Polarisation::CircularLeft: tmp="CIRCULAR_LEFT"; break;
1488 case eDVBFrontendParametersSatellite::Polarisation::CircularRight: tmp="CIRCULAR_RIGHT"; break;
1491 PutToDict(ret, "polarization", tmp);
1505 int eDVBServicePlay::getNumberOfSubservices()
1507 ePtr<eServiceEvent> evt;
1508 if (!m_event_handler.getEvent(evt, 0))
1509 return evt->getNumOfLinkageServices();
1513 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
1515 ePtr<eServiceEvent> evt;
1516 if (!m_event_handler.getEvent(evt, 0))
1518 if (!evt->getLinkageService(sub, m_reference, n))
1521 sub.type=eServiceReference::idInvalid;
1525 RESULT eDVBServicePlay::startTimeshift()
1527 ePtr<iDVBDemux> demux;
1529 eDebug("Start timeshift!");
1531 if (m_timeshift_enabled)
1534 /* start recording with the data demux. */
1535 if (m_service_handler.getDataDemux(demux))
1538 demux->createTSRecorder(m_record);
1542 char templ[]=TSPATH "/timeshift.XXXXXX";
1543 m_timeshift_fd = mkstemp(templ);
1544 m_timeshift_file = templ;
1546 eDebug("recording to %s", templ);
1548 if (m_timeshift_fd < 0)
1554 m_record->setTargetFD(m_timeshift_fd);
1556 m_timeshift_enabled = 1;
1558 updateTimeshiftPids();
1564 RESULT eDVBServicePlay::stopTimeshift()
1566 if (!m_timeshift_enabled)
1571 m_timeshift_enabled = 0;
1576 close(m_timeshift_fd);
1577 eDebug("remove timeshift file");
1578 remove(m_timeshift_file.c_str());
1583 int eDVBServicePlay::isTimeshiftActive()
1585 return m_timeshift_enabled && m_timeshift_active;
1588 RESULT eDVBServicePlay::activateTimeshift()
1590 if (!m_timeshift_enabled)
1593 if (!m_timeshift_active)
1595 switchToTimeshift();
1602 PyObject *eDVBServicePlay::getCutList()
1604 ePyObject list = PyList_New(0);
1606 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
1608 ePyObject tuple = PyTuple_New(2);
1609 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(i->where));
1610 PyTuple_SetItem(tuple, 1, PyInt_FromLong(i->what));
1611 PyList_Append(list, tuple);
1618 void eDVBServicePlay::setCutList(ePyObject list)
1620 if (!PyList_Check(list))
1622 int size = PyList_Size(list);
1625 m_cue_entries.clear();
1627 for (i=0; i<size; ++i)
1629 ePyObject tuple = PyList_GET_ITEM(list, i);
1630 if (!PyTuple_Check(tuple))
1632 eDebug("non-tuple in cutlist");
1635 if (PyTuple_Size(tuple) != 2)
1637 eDebug("cutlist entries need to be a 2-tuple");
1640 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
1641 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
1643 eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
1646 pts_t pts = PyLong_AsLongLong(ppts);
1647 int type = PyInt_AsLong(ptype);
1648 m_cue_entries.insert(cueEntry(pts, type));
1649 eDebug("adding %08llx, %d", pts, type);
1651 m_cuesheet_changed = 1;
1653 cutlistToCuesheet();
1654 m_event((iPlayableService*)this, evCuesheetChanged);
1657 void eDVBServicePlay::setCutListEnable(int enable)
1659 m_cutlist_enabled = enable;
1660 cutlistToCuesheet();
1663 void eDVBServicePlay::updateTimeshiftPids()
1668 eDVBServicePMTHandler::program program;
1669 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1671 if (h.getProgramInfo(program))
1675 std::set<int> pids_to_record;
1676 pids_to_record.insert(0); // PAT
1677 if (program.pmtPid != -1)
1678 pids_to_record.insert(program.pmtPid); // PMT
1680 if (program.textPid != -1)
1681 pids_to_record.insert(program.textPid); // Videotext
1683 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1684 i(program.videoStreams.begin());
1685 i != program.videoStreams.end(); ++i)
1686 pids_to_record.insert(i->pid);
1688 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1689 i(program.audioStreams.begin());
1690 i != program.audioStreams.end(); ++i)
1691 pids_to_record.insert(i->pid);
1693 std::set<int> new_pids, obsolete_pids;
1695 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
1696 m_pids_active.begin(), m_pids_active.end(),
1697 std::inserter(new_pids, new_pids.begin()));
1699 std::set_difference(
1700 m_pids_active.begin(), m_pids_active.end(),
1701 pids_to_record.begin(), pids_to_record.end(),
1702 std::inserter(new_pids, new_pids.begin())
1705 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
1706 m_record->addPID(*i);
1708 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
1709 m_record->removePID(*i);
1713 void eDVBServicePlay::switchToLive()
1715 if (!m_timeshift_active)
1721 m_teletext_parser = 0;
1722 m_radiotext_parser = 0;
1723 m_subtitle_parser = 0;
1724 m_new_dvb_subtitle_page_connection = 0;
1725 m_new_subtitle_page_connection = 0;
1726 m_radiotext_updated_connection = 0;
1728 /* free the timeshift service handler, we need the resources */
1729 m_service_handler_timeshift.free();
1730 m_timeshift_active = 0;
1732 m_event((iPlayableService*)this, evSeekableStatusChanged);
1737 void eDVBServicePlay::switchToTimeshift()
1739 if (m_timeshift_active)
1744 m_teletext_parser = 0;
1745 m_radiotext_parser = 0;
1746 m_subtitle_parser = 0;
1747 m_new_subtitle_page_connection = 0;
1748 m_new_dvb_subtitle_page_connection = 0;
1749 m_radiotext_updated_connection = 0;
1751 m_timeshift_active = 1;
1753 m_event((iPlayableService*)this, evSeekableStatusChanged);
1755 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1756 r.path = m_timeshift_file;
1758 m_cue = new eCueSheet();
1759 m_service_handler_timeshift.tune(r, 1, m_cue); /* use the decoder demux for everything */
1760 updateDecoder(); /* mainly to switch off PCR */
1763 void eDVBServicePlay::updateDecoder()
1765 int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
1767 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1769 bool defaultac3=false;
1770 std::string default_ac3;
1772 if (!ePythonConfigQuery::getConfigValue("config.av.defaultac3", default_ac3))
1773 defaultac3 = default_ac3 == "True";
1775 eDVBServicePMTHandler::program program;
1776 if (h.getProgramInfo(program))
1777 eDebug("getting program info failed.");
1780 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
1781 if (!program.videoStreams.empty())
1783 eDebugNoNewLine(" (");
1784 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1785 i(program.videoStreams.begin());
1786 i != program.videoStreams.end(); ++i)
1793 if (i != program.videoStreams.begin())
1794 eDebugNoNewLine(", ");
1795 eDebugNoNewLine("%04x", i->pid);
1797 eDebugNoNewLine(")");
1799 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
1800 if (!program.audioStreams.empty())
1802 eDebugNoNewLine(" (");
1803 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1804 i(program.audioStreams.begin());
1805 i != program.audioStreams.end(); ++i)
1807 if (apid == -1 || (apidtype == eDVBAudio::aMPEG && defaultac3))
1809 if ( apid == -1 || (i->type != eDVBAudio::aMPEG) )
1815 if (i != program.audioStreams.begin())
1816 eDebugNoNewLine(", ");
1817 eDebugNoNewLine("%04x", i->pid);
1819 eDebugNoNewLine(")");
1821 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
1822 pcrpid = program.pcrPid;
1823 eDebug(", and the text pid is %04x", program.textPid);
1824 tpid = program.textPid;
1829 h.getDecodeDemux(m_decode_demux);
1831 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
1833 m_cue->setDecodingDemux(m_decode_demux, m_decoder);
1834 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
1835 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
1836 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
1837 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
1844 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
1845 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
1846 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
1848 else // subservice or recording
1850 eServiceReferenceDVB ref;
1851 m_service_handler.getServiceReference(ref);
1852 eServiceReferenceDVB parent = ref.getParentServiceReference();
1857 ePtr<eDVBResourceManager> res_mgr;
1858 if (!eDVBResourceManager::getInstance(res_mgr))
1860 ePtr<iDVBChannelList> db;
1861 if (!res_mgr->getChannelList(db))
1863 ePtr<eDVBService> origService;
1864 if (!db->getService(parent, origService))
1866 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
1867 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
1873 m_decoder->setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
1874 m_decoder->setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
1876 m_decoder->setVideoPID(vpid, vpidtype);
1877 m_decoder->setAudioPID(apid, apidtype);
1878 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
1880 m_decoder->setSyncPCR(pcrpid);
1883 ePtr<iDVBDemux> data_demux;
1884 if (!h.getDataDemux(data_demux))
1886 m_radiotext_parser = new eDVBRadioTextParser(data_demux);
1887 m_radiotext_parser->connectUpdatedRadiotext(slot(*this, &eDVBServicePlay::radioTextUpdated), m_radiotext_updated_connection);
1888 m_radiotext_parser->start(apid);
1893 m_decoder->setSyncPCR(-1);
1895 m_decoder->setTextPID(tpid);
1897 m_teletext_parser->start(program.textPid);
1900 m_decoder->setTrickmode(1);
1904 if (vpid > 0 && vpid < 0x2000)
1908 std::string radio_pic;
1909 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
1910 m_decoder->setRadioPic(radio_pic);
1913 m_decoder->setAudioChannel(achannel);
1915 // how we can do this better?
1916 // update cache pid when the user changed the audio track or video track
1917 // TODO handling of difference audio types.. default audio types..
1919 /* don't worry about non-existing services, nor pvr services */
1920 if (m_dvb_service && !m_is_pvr)
1922 if (apidtype == eDVBAudio::aMPEG)
1924 m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
1925 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1929 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1930 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
1932 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
1933 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
1934 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
1935 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
1938 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
1941 void eDVBServicePlay::loadCuesheet()
1943 std::string filename = m_reference.path + ".cuts";
1945 m_cue_entries.clear();
1947 FILE *f = fopen(filename.c_str(), "rb");
1951 eDebug("loading cuts..");
1954 unsigned long long where;
1957 if (!fread(&where, sizeof(where), 1, f))
1959 if (!fread(&what, sizeof(what), 1, f))
1962 #if BYTE_ORDER == LITTLE_ENDIAN
1963 where = bswap_64(where);
1970 m_cue_entries.insert(cueEntry(where, what));
1973 eDebug("%d entries", m_cue_entries.size());
1975 eDebug("cutfile not found!");
1977 m_cuesheet_changed = 0;
1978 cutlistToCuesheet();
1979 m_event((iPlayableService*)this, evCuesheetChanged);
1982 void eDVBServicePlay::saveCuesheet()
1984 std::string filename = m_reference.path + ".cuts";
1986 FILE *f = fopen(filename.c_str(), "wb");
1990 unsigned long long where;
1993 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
1995 #if BYTE_ORDER == BIG_ENDIAN
1998 where = bswap_64(i->where);
2000 what = htonl(i->what);
2001 fwrite(&where, sizeof(where), 1, f);
2002 fwrite(&what, sizeof(what), 1, f);
2008 m_cuesheet_changed = 0;
2011 void eDVBServicePlay::cutlistToCuesheet()
2015 eDebug("no cue sheet");
2020 if (!m_cutlist_enabled)
2022 m_cue->commitSpans();
2023 eDebug("cutlists were disabled");
2027 pts_t in = 0, out = 0, length = 0;
2031 std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
2035 if (i == m_cue_entries.end())
2038 if (i->what == 0) /* in */
2042 } else if (i->what == 1) /* out */
2044 else /* mark (2) or last play position (3) */
2052 m_cue->addSourceSpan(in, out);
2056 if (i == m_cue_entries.end())
2059 m_cue->commitSpans();
2062 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
2064 if (m_subtitle_widget)
2065 disableSubtitles(parent);
2068 int tuplesize = PyTuple_Size(tuple);
2071 if (!PyTuple_Check(tuple))
2077 entry = PyTuple_GET_ITEM(tuple, 0);
2079 if (!PyInt_Check(entry))
2082 type = PyInt_AsLong(entry);
2084 if (type == 1) // teletext subtitles
2086 int page, magazine, pid;
2090 if (!m_teletext_parser)
2092 eDebug("enable teletext subtitles.. no parser !!!");
2096 entry = PyTuple_GET_ITEM(tuple, 1);
2097 if (!PyInt_Check(entry))
2099 pid = PyInt_AsLong(entry);
2101 entry = PyTuple_GET_ITEM(tuple, 2);
2102 if (!PyInt_Check(entry))
2104 page = PyInt_AsLong(entry);
2106 entry = PyTuple_GET_ITEM(tuple, 3);
2107 if (!PyInt_Check(entry))
2109 magazine = PyInt_AsLong(entry);
2111 m_subtitle_widget = new eSubtitleWidget(parent);
2112 m_subtitle_widget->resize(parent->size()); /* full size */
2113 m_teletext_parser->setPageAndMagazine(page, magazine);
2115 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
2119 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
2120 if (!m_subtitle_parser)
2122 eDebug("enable dvb subtitles.. no parser !!!");
2128 entry = PyTuple_GET_ITEM(tuple, 1);
2129 if (!PyInt_Check(entry))
2131 pid = PyInt_AsLong(entry);
2133 entry = PyTuple_GET_ITEM(tuple, 2);
2134 if (!PyInt_Check(entry))
2136 composition_page_id = PyInt_AsLong(entry);
2138 entry = PyTuple_GET_ITEM(tuple, 3);
2139 if (!PyInt_Check(entry))
2141 ancillary_page_id = PyInt_AsLong(entry);
2143 m_subtitle_widget = new eSubtitleWidget(parent);
2144 m_subtitle_widget->resize(parent->size()); /* full size */
2145 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
2147 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
2153 eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
2154 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
2155 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
2159 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
2161 delete m_subtitle_widget;
2162 m_subtitle_widget = 0;
2163 if (m_subtitle_parser)
2165 m_subtitle_parser->stop();
2166 m_dvb_subtitle_pages.clear();
2168 if (m_teletext_parser)
2170 m_teletext_parser->setPageAndMagazine(-1, -1);
2171 m_subtitle_pages.clear();
2174 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
2178 PyObject *eDVBServicePlay::getCachedSubtitle()
2182 int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
2185 unsigned int data = (unsigned int)tmp;
2186 int pid = (data&0xFFFF0000)>>16;
2187 ePyObject tuple = PyTuple_New(4);
2188 eDVBServicePMTHandler::program program;
2189 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2190 if (!h.getProgramInfo(program))
2192 if (program.textPid==pid) // teletext
2193 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
2195 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
2196 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
2197 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
2198 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
2207 PyObject *eDVBServicePlay::getSubtitleList()
2209 if (!m_teletext_parser)
2215 ePyObject l = PyList_New(0);
2216 std::set<int> added_ttx_pages;
2218 std::set<eDVBServicePMTHandler::subtitleStream> &subs =
2219 m_teletext_parser->m_found_subtitle_pages;
2221 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2222 eDVBServicePMTHandler::program program;
2223 if (h.getProgramInfo(program))
2224 eDebug("getting program info failed.");
2227 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
2228 it != program.subtitleStreams.end(); ++it)
2230 switch(it->subtitling_type)
2232 case 0x01: // ebu teletext subtitles
2234 int page_number = it->teletext_page_number & 0xFF;
2235 int magazine_number = it->teletext_magazine_number & 7;
2236 int hash = magazine_number << 8 | page_number;
2237 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2239 ePyObject tuple = PyTuple_New(5);
2240 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2241 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2242 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2243 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2244 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2245 PyList_Append(l, tuple);
2247 added_ttx_pages.insert(hash);
2252 case 0x20 ... 0x23: // dvb subtitles
2254 ePyObject tuple = PyTuple_New(5);
2255 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
2256 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2257 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
2258 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
2259 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2260 PyList_Insert(l, 0, tuple);
2268 for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
2269 it != subs.end(); ++it)
2271 int page_number = it->teletext_page_number & 0xFF;
2272 int magazine_number = it->teletext_magazine_number & 7;
2273 int hash = magazine_number << 8 | page_number;
2274 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2276 ePyObject tuple = PyTuple_New(5);
2277 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2278 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2279 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2280 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2281 PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
2282 PyList_Append(l, tuple);
2290 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
2292 if (m_subtitle_widget)
2294 m_subtitle_pages.push_back(page);
2295 checkSubtitleTiming();
2299 void eDVBServicePlay::checkSubtitleTiming()
2301 // eDebug("checkSubtitleTiming");
2302 if (!m_subtitle_widget)
2306 enum { TELETEXT, DVB } type;
2307 eDVBTeletextSubtitlePage page;
2308 eDVBSubtitlePage dvb_page;
2310 if (!m_subtitle_pages.empty())
2312 page = m_subtitle_pages.front();
2314 show_time = page.m_pts;
2316 else if (!m_dvb_subtitle_pages.empty())
2318 dvb_page = m_dvb_subtitle_pages.front();
2320 show_time = dvb_page.m_show_time;
2328 m_decoder->getPTS(0, pos);
2330 // eDebug("%lld %lld", pos, show_time);
2331 int diff = show_time - pos;
2334 eDebug("[late (%d ms)]", -diff / 90);
2339 eDebug("[invalid]");
2345 if (type == TELETEXT)
2347 eDebug("display teletext subtitle page");
2348 m_subtitle_widget->setPage(page);
2349 m_subtitle_pages.pop_front();
2353 eDebug("display dvb subtitle Page");
2354 m_subtitle_widget->setPage(dvb_page);
2355 m_dvb_subtitle_pages.pop_front();
2359 // eDebug("start subtitle delay %d", diff / 90);
2360 m_subtitle_sync_timer.start(diff / 90, 1);
2366 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
2368 if (m_subtitle_widget)
2370 m_dvb_subtitle_pages.push_back(p);
2371 checkSubtitleTiming();
2375 int eDVBServicePlay::getAC3Delay()
2378 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2380 return m_decoder->getAC3Delay();
2385 int eDVBServicePlay::getPCMDelay()
2388 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2390 return m_decoder->getPCMDelay();
2395 void eDVBServicePlay::setAC3Delay(int delay)
2398 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2400 m_decoder->setAC3Delay(delay);
2403 void eDVBServicePlay::setPCMDelay(int delay)
2406 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2408 m_decoder->setPCMDelay(delay);
2411 DEFINE_REF(eDVBServicePlay)
2413 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");