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 eDebug("service %p: error %d", this, event);
761 m_tune_state = event;
765 case eDVBServicePMTHandler::eventTuned:
767 ePtr<iDVBDemux> m_demux;
768 if (!m_service_handler.getDataDemux(m_demux))
770 eServiceReferenceDVB &ref = (eServiceReferenceDVB&) m_reference;
771 int sid = ref.getParentServiceID().get();
773 sid = ref.getServiceID().get();
774 if ( ref.getParentTransportStreamID().get() &&
775 ref.getParentTransportStreamID() != ref.getTransportStreamID() )
776 m_event_handler.startOther(m_demux, sid);
778 m_event_handler.start(m_demux, sid);
782 case eDVBServicePMTHandler::eventNoPAT:
783 case eDVBServicePMTHandler::eventNoPATEntry:
784 case eDVBServicePMTHandler::eventNoPMT:
785 case eDVBServicePMTHandler::eventTuneFailed:
787 eDebug("DVB service failed to tune - error %d", event);
788 m_event((iPlayableService*)this, evTuneFailed);
791 case eDVBServicePMTHandler::eventNewProgramInfo:
793 eDebug("eventNewProgramInfo %d %d", m_timeshift_enabled, m_timeshift_active);
794 if (m_timeshift_enabled)
795 updateTimeshiftPids();
796 if (!m_timeshift_active)
798 if (m_first_program_info && m_is_pvr)
800 m_first_program_info = 0;
803 m_event((iPlayableService*)this, evUpdatedInfo);
806 case eDVBServicePMTHandler::eventEOF:
807 m_event((iPlayableService*)this, evEOF);
809 case eDVBServicePMTHandler::eventSOF:
810 m_event((iPlayableService*)this, evSOF);
815 void eDVBServicePlay::serviceEventTimeshift(int event)
819 case eDVBServicePMTHandler::eventNewProgramInfo:
820 if (m_timeshift_active)
823 case eDVBServicePMTHandler::eventSOF:
824 m_event((iPlayableService*)this, evSOF);
826 case eDVBServicePMTHandler::eventEOF:
832 RESULT eDVBServicePlay::start()
835 /* in pvr mode, we only want to use one demux. in tv mode, we're using
836 two (one for decoding, one for data source), as we must be prepared
837 to start recording from the data demux. */
839 m_cue = new eCueSheet();
841 m_first_program_info = 1;
842 eServiceReferenceDVB &service = (eServiceReferenceDVB&)m_reference;
843 r = m_service_handler.tune(service, m_is_pvr, m_cue);
845 /* inject EIT if there is a stored one */
848 std::string filename = service.path;
849 filename.erase(filename.length()-2, 2);
851 ePtr<eServiceEvent> event = new eServiceEvent;
852 if (!event->parseFrom(filename, (service.getTransportStreamID().get()<<16)|service.getOriginalNetworkID().get()))
854 ePtr<eServiceEvent> empty;
855 m_event_handler.inject(event, 0);
856 m_event_handler.inject(empty, 1);
863 m_event(this, evStart);
864 m_event((iPlayableService*)this, evSeekableStatusChanged);
868 RESULT eDVBServicePlay::stop()
870 /* add bookmark for last play position */
874 if (!getPlayPosition(play_position))
876 /* remove last position */
877 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end();)
879 if (i->what == 3) /* current play position */
881 m_cue_entries.erase(i);
882 i = m_cue_entries.begin();
888 m_cue_entries.insert(cueEntry(play_position, 3)); /* last play position */
889 m_cuesheet_changed = 1;
893 stopTimeshift(); /* in case timeshift was enabled, remove buffer etc. */
895 m_service_handler_timeshift.free();
896 m_service_handler.free();
898 if (m_is_pvr && m_cuesheet_changed)
901 /* save cuesheet only when main file is accessible. */
902 if (!::stat(m_reference.path.c_str(), &s))
909 RESULT eDVBServicePlay::setTarget(int target)
911 m_is_primary = !target;
915 RESULT eDVBServicePlay::connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)
917 connection = new eConnection((iPlayableService*)this, m_event.connect(event));
921 RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
923 /* note: we check for timeshift to be enabled,
924 not neccessary active. if you pause when timeshift
925 is not active, you should activate it when unpausing */
926 if ((!m_is_pvr) && (!m_timeshift_enabled))
936 RESULT eDVBServicePlay::setSlowMotion(int ratio)
939 return m_decoder->setSlowMotion(ratio);
944 RESULT eDVBServicePlay::setFastForward(int ratio)
946 int skipmode, ffratio;
952 } else if (ratio > 0)
960 } else // if (ratio < 0)
966 if (m_skipmode != skipmode)
968 eDebug("setting cue skipmode to %d", skipmode);
970 m_cue->setSkipmode(skipmode * 90000); /* convert to 90000 per second */
973 m_skipmode = skipmode;
978 return m_decoder->setFastForward(ffratio);
981 RESULT eDVBServicePlay::seek(ePtr<iSeekableService> &ptr)
983 if (m_is_pvr || m_timeshift_enabled)
993 /* TODO: when timeshift is enabled but not active, this doesn't work. */
994 RESULT eDVBServicePlay::getLength(pts_t &len)
996 ePtr<iDVBPVRChannel> pvr_channel;
998 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1001 return pvr_channel->getLength(len);
1004 RESULT eDVBServicePlay::pause()
1006 if (!m_is_paused && m_decoder)
1009 return m_decoder->freeze(0);
1014 RESULT eDVBServicePlay::unpause()
1016 if (m_is_paused && m_decoder)
1019 return m_decoder->unfreeze();
1024 RESULT eDVBServicePlay::seekTo(pts_t to)
1026 eDebug("eDVBServicePlay::seekTo: jump %lld", to);
1028 if (!m_decode_demux)
1031 ePtr<iDVBPVRChannel> pvr_channel;
1033 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1039 m_cue->seekTo(0, to);
1043 RESULT eDVBServicePlay::seekRelative(int direction, pts_t to)
1045 eDebug("eDVBServicePlay::seekRelative: jump %d, %lld", direction, to);
1047 if (!m_decode_demux)
1050 ePtr<iDVBPVRChannel> pvr_channel;
1052 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1057 /* HACK until we have skip-AP api */
1058 if ((to > 0) && (to < 100))
1066 m_cue->seekTo(mode, to);
1070 RESULT eDVBServicePlay::getPlayPosition(pts_t &pos)
1072 ePtr<iDVBPVRChannel> pvr_channel;
1074 if (!m_decode_demux)
1077 if ((m_timeshift_enabled ? m_service_handler_timeshift : m_service_handler).getPVRChannel(pvr_channel))
1082 /* if there is a decoder, use audio or video PTS */
1085 r = m_decoder->getPTS(0, pos);
1091 return pvr_channel->getCurrentPosition(m_decode_demux, pos, m_decoder ? 1 : 0);
1094 RESULT eDVBServicePlay::setTrickmode(int trick)
1097 m_decoder->setTrickmode(trick);
1101 RESULT eDVBServicePlay::isCurrentlySeekable()
1103 return m_is_pvr || m_timeshift_active;
1106 RESULT eDVBServicePlay::frontendInfo(ePtr<iFrontendInformation> &ptr)
1112 RESULT eDVBServicePlay::info(ePtr<iServiceInformation> &ptr)
1118 RESULT eDVBServicePlay::audioChannel(ePtr<iAudioChannelSelection> &ptr)
1124 RESULT eDVBServicePlay::audioTracks(ePtr<iAudioTrackSelection> &ptr)
1130 RESULT eDVBServicePlay::subServices(ePtr<iSubserviceList> &ptr)
1136 RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
1139 if (m_have_video_pid && // HACK !!! FIXMEE !! temporary no timeshift on radio services !!
1140 (m_timeshift_enabled || !m_is_pvr))
1142 if (!m_timeshift_enabled)
1144 /* we need enough diskspace */
1146 if (statfs(TSPATH "/.", &fs) < 0)
1148 eDebug("statfs failed!");
1152 if (((off_t)fs.f_bavail) * ((off_t)fs.f_bsize) < 1024*1024*1024LL)
1154 eDebug("not enough diskspace for timeshift! (less than 1GB)");
1164 RESULT eDVBServicePlay::cueSheet(ePtr<iCueSheet> &ptr)
1175 RESULT eDVBServicePlay::subtitle(ePtr<iSubtitleOutput> &ptr)
1181 RESULT eDVBServicePlay::audioDelay(ePtr<iAudioDelay> &ptr)
1187 RESULT eDVBServicePlay::radioText(ePtr<iRadioText> &ptr)
1193 RESULT eDVBServicePlay::getName(std::string &name)
1197 ePtr<iStaticServiceInformation> i = new eStaticServiceDVBPVRInformation(m_reference);
1198 return i->getName(m_reference, name);
1202 m_dvb_service->getName(m_reference, name);
1206 else if (!m_reference.name.empty())
1207 eStaticServiceDVBInformation().getName(m_reference, name);
1209 name = "DVB service";
1213 RESULT eDVBServicePlay::getEvent(ePtr<eServiceEvent> &evt, int nownext)
1215 return m_event_handler.getEvent(evt, nownext);
1218 int eDVBServicePlay::getInfo(int w)
1220 eDVBServicePMTHandler::program program;
1222 eDebug("get info in %p", this);
1225 return resIsPyObject;
1227 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1229 int no_program_info = 0;
1231 if (h.getProgramInfo(program))
1232 no_program_info = 1;
1238 if (!no_program_info) return -1;
1239 if (!program.videoStreams.empty() && program.videoStreams[0].component_tag != -1)
1241 ePtr<eServiceEvent> evt;
1242 if (!m_event_handler.getEvent(evt, 0))
1244 ePtr<eComponentData> data;
1245 if (!evt->getComponentData(data, program.videoStreams[0].component_tag))
1247 if ( data->getStreamContent() == 1 )
1249 switch(data->getComponentType())
1252 case 1: // 4:3 SD PAL
1254 case 3: // 16:9 SD PAL
1255 case 4: // > 16:9 PAL
1256 case 5: // 4:3 SD NTSC
1258 case 7: // 16:9 SD NTSC
1259 case 8: // > 16:9 NTSC
1262 case 9: // 4:3 HD PAL
1264 case 0xB: // 16:9 HD PAL
1265 case 0xC: // > 16:9 HD PAL
1266 case 0xD: // 4:3 HD NTSC
1268 case 0xF: // 16:9 HD NTSC
1269 case 0x10: // > 16:9 HD PAL
1270 return data->getComponentType();
1277 case sIsCrypted: if (!no_program_info) return -1; return program.isCrypted();
1278 case sVideoPID: if (!no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].pid;
1279 case sVideoType: if (!no_program_info) return -1; if (program.videoStreams.empty()) return -1; return program.videoStreams[0].type;
1280 case sAudioPID: if (!no_program_info) return -1; if (program.audioStreams.empty()) return -1; return program.audioStreams[0].pid;
1281 case sPCRPID: if (!no_program_info) return -1; return program.pcrPid;
1282 case sPMTPID: if (!no_program_info) return -1; return program.pmtPid;
1283 case sTXTPID: if (!no_program_info) return -1; return program.textPid;
1284 case sSID: return ((const eServiceReferenceDVB&)m_reference).getServiceID().get();
1285 case sONID: return ((const eServiceReferenceDVB&)m_reference).getOriginalNetworkID().get();
1286 case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get();
1287 case sNamespace: return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get();
1288 case sProvider: if (!m_dvb_service) return -1; return -2;
1289 case sServiceref: return resIsString;
1290 case sDVBState: return m_tune_state;
1296 std::string eDVBServicePlay::getInfoString(int w)
1301 if (!m_dvb_service) return "";
1302 return m_dvb_service->m_provider_name;
1304 return m_reference.toString();
1308 return iServiceInformation::getInfoString(w);
1311 PyObject *eDVBServicePlay::getInfoObject(int w)
1316 return m_service_handler.getCaIds();
1320 return iServiceInformation::getInfoObject(w);
1323 int eDVBServicePlay::getNumberOfTracks()
1325 eDVBServicePMTHandler::program program;
1326 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1327 if (h.getProgramInfo(program))
1329 return program.audioStreams.size();
1332 RESULT eDVBServicePlay::selectTrack(unsigned int i)
1334 int ret = selectAudioStream(i);
1336 if (m_decoder->start())
1342 RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int i)
1344 eDVBServicePMTHandler::program program;
1345 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1347 if (h.getProgramInfo(program))
1350 if (i >= program.audioStreams.size())
1353 if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atMPEG)
1354 info.m_description = "MPEG";
1355 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAC3)
1356 info.m_description = "AC3";
1357 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC)
1358 info.m_description = "AAC";
1359 else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS)
1360 info.m_description = "DTS";
1362 info.m_description = "???";
1364 if (program.audioStreams[i].component_tag != -1)
1366 ePtr<eServiceEvent> evt;
1367 if (!m_event_handler.getEvent(evt, 0))
1369 ePtr<eComponentData> data;
1370 if (!evt->getComponentData(data, program.audioStreams[i].component_tag))
1371 info.m_language = data->getText();
1375 if (info.m_language.empty())
1376 info.m_language = program.audioStreams[i].language_code;
1381 int eDVBServicePlay::selectAudioStream(int i)
1383 eDVBServicePMTHandler::program program;
1384 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1386 if (h.getProgramInfo(program))
1389 if ((unsigned int)i >= program.audioStreams.size())
1395 if (m_decoder->setAudioPID(program.audioStreams[i].pid, program.audioStreams[i].type))
1398 if (m_radiotext_parser)
1399 m_radiotext_parser->start(program.audioStreams[i].pid);
1401 if (m_dvb_service && !m_is_pvr)
1403 if (program.audioStreams[i].type == eDVBAudio::aMPEG)
1405 m_dvb_service->setCacheEntry(eDVBService::cAPID, program.audioStreams[i].pid);
1406 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1410 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1411 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, program.audioStreams[i].pid);
1415 h.resetCachedProgram();
1420 int eDVBServicePlay::getCurrentChannel()
1422 return m_decoder ? m_decoder->getAudioChannel() : STEREO;
1425 RESULT eDVBServicePlay::selectChannel(int i)
1427 if (i < LEFT || i > RIGHT || i == STEREO)
1430 m_dvb_service->setCacheEntry(eDVBService::cACHANNEL, i);
1432 m_decoder->setAudioChannel(i);
1436 std::string eDVBServicePlay::getRadioText(int x)
1438 if (m_radiotext_parser)
1442 return convertLatin1UTF8(m_radiotext_parser->getCurrentText());
1447 void eDVBServicePlay::radioTextUpdated()
1449 m_event((iPlayableService*)this, evUpdatedRadioText);
1452 int eDVBServiceBase::getFrontendInfo(int w)
1454 eUsePtr<iDVBChannel> channel;
1455 if(m_service_handler.getChannel(channel))
1457 ePtr<iDVBFrontend> fe;
1458 if(channel->getFrontend(fe))
1460 return fe->readFrontendData(w);
1463 PyObject *eDVBServiceBase::getFrontendData(bool original)
1467 eUsePtr<iDVBChannel> channel;
1468 if(!m_service_handler.getChannel(channel))
1470 ePtr<iDVBFrontend> fe;
1471 if(!channel->getFrontend(fe))
1473 ret = fe->readTransponderData(original);
1476 ePtr<iDVBFrontendParameters> feparm;
1477 channel->getCurrentFrontendParameters(feparm);
1480 eDVBFrontendParametersSatellite osat;
1481 if (!feparm->getDVBS(osat))
1483 void PutToDict(ePyObject &, const char*, long);
1484 void PutToDict(ePyObject &, const char*, const char*);
1485 PutToDict(ret, "orbital_position", osat.orbital_position);
1486 const char *tmp = "UNKNOWN";
1487 switch(osat.polarisation)
1489 case eDVBFrontendParametersSatellite::Polarisation::Horizontal: tmp="HORIZONTAL"; break;
1490 case eDVBFrontendParametersSatellite::Polarisation::Vertical: tmp="VERTICAL"; break;
1491 case eDVBFrontendParametersSatellite::Polarisation::CircularLeft: tmp="CIRCULAR_LEFT"; break;
1492 case eDVBFrontendParametersSatellite::Polarisation::CircularRight: tmp="CIRCULAR_RIGHT"; break;
1495 PutToDict(ret, "polarization", tmp);
1509 int eDVBServicePlay::getNumberOfSubservices()
1511 ePtr<eServiceEvent> evt;
1512 if (!m_event_handler.getEvent(evt, 0))
1513 return evt->getNumOfLinkageServices();
1517 RESULT eDVBServicePlay::getSubservice(eServiceReference &sub, unsigned int n)
1519 ePtr<eServiceEvent> evt;
1520 if (!m_event_handler.getEvent(evt, 0))
1522 if (!evt->getLinkageService(sub, m_reference, n))
1525 sub.type=eServiceReference::idInvalid;
1529 RESULT eDVBServicePlay::startTimeshift()
1531 ePtr<iDVBDemux> demux;
1533 eDebug("Start timeshift!");
1535 if (m_timeshift_enabled)
1538 /* start recording with the data demux. */
1539 if (m_service_handler.getDataDemux(demux))
1542 demux->createTSRecorder(m_record);
1546 char templ[]=TSPATH "/timeshift.XXXXXX";
1547 m_timeshift_fd = mkstemp(templ);
1548 m_timeshift_file = templ;
1550 eDebug("recording to %s", templ);
1552 if (m_timeshift_fd < 0)
1558 m_record->setTargetFD(m_timeshift_fd);
1560 m_timeshift_enabled = 1;
1562 updateTimeshiftPids();
1568 RESULT eDVBServicePlay::stopTimeshift()
1570 if (!m_timeshift_enabled)
1575 m_timeshift_enabled = 0;
1580 close(m_timeshift_fd);
1581 eDebug("remove timeshift file");
1582 remove(m_timeshift_file.c_str());
1587 int eDVBServicePlay::isTimeshiftActive()
1589 return m_timeshift_enabled && m_timeshift_active;
1592 RESULT eDVBServicePlay::activateTimeshift()
1594 if (!m_timeshift_enabled)
1597 if (!m_timeshift_active)
1599 switchToTimeshift();
1606 PyObject *eDVBServicePlay::getCutList()
1608 ePyObject list = PyList_New(0);
1610 for (std::multiset<struct cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
1612 ePyObject tuple = PyTuple_New(2);
1613 PyTuple_SetItem(tuple, 0, PyLong_FromLongLong(i->where));
1614 PyTuple_SetItem(tuple, 1, PyInt_FromLong(i->what));
1615 PyList_Append(list, tuple);
1622 void eDVBServicePlay::setCutList(ePyObject list)
1624 if (!PyList_Check(list))
1626 int size = PyList_Size(list);
1629 m_cue_entries.clear();
1631 for (i=0; i<size; ++i)
1633 ePyObject tuple = PyList_GET_ITEM(list, i);
1634 if (!PyTuple_Check(tuple))
1636 eDebug("non-tuple in cutlist");
1639 if (PyTuple_Size(tuple) != 2)
1641 eDebug("cutlist entries need to be a 2-tuple");
1644 ePyObject ppts = PyTuple_GET_ITEM(tuple, 0), ptype = PyTuple_GET_ITEM(tuple, 1);
1645 if (!(PyLong_Check(ppts) && PyInt_Check(ptype)))
1647 eDebug("cutlist entries need to be (pts, type)-tuples (%d %d)", PyLong_Check(ppts), PyInt_Check(ptype));
1650 pts_t pts = PyLong_AsLongLong(ppts);
1651 int type = PyInt_AsLong(ptype);
1652 m_cue_entries.insert(cueEntry(pts, type));
1653 eDebug("adding %08llx, %d", pts, type);
1655 m_cuesheet_changed = 1;
1657 cutlistToCuesheet();
1658 m_event((iPlayableService*)this, evCuesheetChanged);
1661 void eDVBServicePlay::setCutListEnable(int enable)
1663 m_cutlist_enabled = enable;
1664 cutlistToCuesheet();
1667 void eDVBServicePlay::updateTimeshiftPids()
1672 eDVBServicePMTHandler::program program;
1673 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1675 if (h.getProgramInfo(program))
1679 std::set<int> pids_to_record;
1680 pids_to_record.insert(0); // PAT
1681 if (program.pmtPid != -1)
1682 pids_to_record.insert(program.pmtPid); // PMT
1684 if (program.textPid != -1)
1685 pids_to_record.insert(program.textPid); // Videotext
1687 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1688 i(program.videoStreams.begin());
1689 i != program.videoStreams.end(); ++i)
1690 pids_to_record.insert(i->pid);
1692 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1693 i(program.audioStreams.begin());
1694 i != program.audioStreams.end(); ++i)
1695 pids_to_record.insert(i->pid);
1697 std::set<int> new_pids, obsolete_pids;
1699 std::set_difference(pids_to_record.begin(), pids_to_record.end(),
1700 m_pids_active.begin(), m_pids_active.end(),
1701 std::inserter(new_pids, new_pids.begin()));
1703 std::set_difference(
1704 m_pids_active.begin(), m_pids_active.end(),
1705 pids_to_record.begin(), pids_to_record.end(),
1706 std::inserter(new_pids, new_pids.begin())
1709 for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
1710 m_record->addPID(*i);
1712 for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
1713 m_record->removePID(*i);
1717 void eDVBServicePlay::switchToLive()
1719 if (!m_timeshift_active)
1725 m_teletext_parser = 0;
1726 m_radiotext_parser = 0;
1727 m_subtitle_parser = 0;
1728 m_new_dvb_subtitle_page_connection = 0;
1729 m_new_subtitle_page_connection = 0;
1730 m_radiotext_updated_connection = 0;
1732 /* free the timeshift service handler, we need the resources */
1733 m_service_handler_timeshift.free();
1734 m_timeshift_active = 0;
1736 m_event((iPlayableService*)this, evSeekableStatusChanged);
1741 void eDVBServicePlay::switchToTimeshift()
1743 if (m_timeshift_active)
1748 m_teletext_parser = 0;
1749 m_radiotext_parser = 0;
1750 m_subtitle_parser = 0;
1751 m_new_subtitle_page_connection = 0;
1752 m_new_dvb_subtitle_page_connection = 0;
1753 m_radiotext_updated_connection = 0;
1755 m_timeshift_active = 1;
1757 m_event((iPlayableService*)this, evSeekableStatusChanged);
1759 eServiceReferenceDVB r = (eServiceReferenceDVB&)m_reference;
1760 r.path = m_timeshift_file;
1762 m_cue = new eCueSheet();
1763 m_service_handler_timeshift.tune(r, 1, m_cue); /* use the decoder demux for everything */
1764 updateDecoder(); /* mainly to switch off PCR */
1767 void eDVBServicePlay::updateDecoder()
1769 int vpid = -1, vpidtype = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1, achannel = -1, ac3_delay=-1, pcm_delay=-1;
1771 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
1773 bool defaultac3=false;
1774 std::string default_ac3;
1776 if (!ePythonConfigQuery::getConfigValue("config.av.defaultac3", default_ac3))
1777 defaultac3 = default_ac3 == "True";
1779 eDVBServicePMTHandler::program program;
1780 if (h.getProgramInfo(program))
1781 eDebug("getting program info failed.");
1784 eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size());
1785 if (!program.videoStreams.empty())
1787 eDebugNoNewLine(" (");
1788 for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
1789 i(program.videoStreams.begin());
1790 i != program.videoStreams.end(); ++i)
1797 if (i != program.videoStreams.begin())
1798 eDebugNoNewLine(", ");
1799 eDebugNoNewLine("%04x", i->pid);
1801 eDebugNoNewLine(")");
1803 eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
1804 if (!program.audioStreams.empty())
1806 eDebugNoNewLine(" (");
1807 for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
1808 i(program.audioStreams.begin());
1809 i != program.audioStreams.end(); ++i)
1811 if (apid == -1 || (apidtype == eDVBAudio::aMPEG && defaultac3))
1813 if ( apid == -1 || (i->type != eDVBAudio::aMPEG) )
1819 if (i != program.audioStreams.begin())
1820 eDebugNoNewLine(", ");
1821 eDebugNoNewLine("%04x", i->pid);
1823 eDebugNoNewLine(")");
1825 eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
1826 pcrpid = program.pcrPid;
1827 eDebug(", and the text pid is %04x", program.textPid);
1828 tpid = program.textPid;
1833 h.getDecodeDemux(m_decode_demux);
1835 m_decode_demux->getMPEGDecoder(m_decoder, m_is_primary);
1837 m_cue->setDecodingDemux(m_decode_demux, m_decoder);
1838 m_teletext_parser = new eDVBTeletextParser(m_decode_demux);
1839 m_teletext_parser->connectNewPage(slot(*this, &eDVBServicePlay::newSubtitlePage), m_new_subtitle_page_connection);
1840 m_subtitle_parser = new eDVBSubtitleParser(m_decode_demux);
1841 m_subtitle_parser->connectNewPage(slot(*this, &eDVBServicePlay::newDVBSubtitlePage), m_new_dvb_subtitle_page_connection);
1848 achannel = m_dvb_service->getCacheEntry(eDVBService::cACHANNEL);
1849 ac3_delay = m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
1850 pcm_delay = m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
1852 else // subservice or recording
1854 eServiceReferenceDVB ref;
1855 m_service_handler.getServiceReference(ref);
1856 eServiceReferenceDVB parent = ref.getParentServiceReference();
1861 ePtr<eDVBResourceManager> res_mgr;
1862 if (!eDVBResourceManager::getInstance(res_mgr))
1864 ePtr<iDVBChannelList> db;
1865 if (!res_mgr->getChannelList(db))
1867 ePtr<eDVBService> origService;
1868 if (!db->getService(parent, origService))
1870 ac3_delay = origService->getCacheEntry(eDVBService::cAC3DELAY);
1871 pcm_delay = origService->getCacheEntry(eDVBService::cPCMDELAY);
1877 m_decoder->setAC3Delay(ac3_delay == -1 ? 0 : ac3_delay);
1878 m_decoder->setPCMDelay(pcm_delay == -1 ? 0 : pcm_delay);
1880 m_decoder->setVideoPID(vpid, vpidtype);
1881 m_decoder->setAudioPID(apid, apidtype);
1882 if (!(m_is_pvr || m_timeshift_active || !m_is_primary))
1884 m_decoder->setSyncPCR(pcrpid);
1887 ePtr<iDVBDemux> data_demux;
1888 if (!h.getDataDemux(data_demux))
1890 m_radiotext_parser = new eDVBRadioTextParser(data_demux);
1891 m_radiotext_parser->connectUpdatedRadiotext(slot(*this, &eDVBServicePlay::radioTextUpdated), m_radiotext_updated_connection);
1892 m_radiotext_parser->start(apid);
1897 m_decoder->setSyncPCR(-1);
1899 m_decoder->setTextPID(tpid);
1901 m_teletext_parser->start(program.textPid);
1904 m_decoder->setTrickmode(1);
1908 if (vpid > 0 && vpid < 0x2000)
1912 std::string radio_pic;
1913 if (!ePythonConfigQuery::getConfigValue("config.misc.radiopic", radio_pic))
1914 m_decoder->setRadioPic(radio_pic);
1917 m_decoder->setAudioChannel(achannel);
1919 // how we can do this better?
1920 // update cache pid when the user changed the audio track or video track
1921 // TODO handling of difference audio types.. default audio types..
1923 /* don't worry about non-existing services, nor pvr services */
1924 if (m_dvb_service && !m_is_pvr)
1926 if (apidtype == eDVBAudio::aMPEG)
1928 m_dvb_service->setCacheEntry(eDVBService::cAPID, apid);
1929 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, -1);
1933 m_dvb_service->setCacheEntry(eDVBService::cAPID, -1);
1934 m_dvb_service->setCacheEntry(eDVBService::cAC3PID, apid);
1936 m_dvb_service->setCacheEntry(eDVBService::cVPID, vpid);
1937 m_dvb_service->setCacheEntry(eDVBService::cVTYPE, vpidtype == eDVBVideo::MPEG2 ? -1 : vpidtype);
1938 m_dvb_service->setCacheEntry(eDVBService::cPCRPID, pcrpid);
1939 m_dvb_service->setCacheEntry(eDVBService::cTPID, tpid);
1942 m_have_video_pid = (vpid > 0 && vpid < 0x2000);
1945 void eDVBServicePlay::loadCuesheet()
1947 std::string filename = m_reference.path + ".cuts";
1949 m_cue_entries.clear();
1951 FILE *f = fopen(filename.c_str(), "rb");
1955 eDebug("loading cuts..");
1958 unsigned long long where;
1961 if (!fread(&where, sizeof(where), 1, f))
1963 if (!fread(&what, sizeof(what), 1, f))
1966 #if BYTE_ORDER == LITTLE_ENDIAN
1967 where = bswap_64(where);
1974 m_cue_entries.insert(cueEntry(where, what));
1977 eDebug("%d entries", m_cue_entries.size());
1979 eDebug("cutfile not found!");
1981 m_cuesheet_changed = 0;
1982 cutlistToCuesheet();
1983 m_event((iPlayableService*)this, evCuesheetChanged);
1986 void eDVBServicePlay::saveCuesheet()
1988 std::string filename = m_reference.path + ".cuts";
1990 FILE *f = fopen(filename.c_str(), "wb");
1994 unsigned long long where;
1997 for (std::multiset<cueEntry>::iterator i(m_cue_entries.begin()); i != m_cue_entries.end(); ++i)
1999 #if BYTE_ORDER == BIG_ENDIAN
2002 where = bswap_64(i->where);
2004 what = htonl(i->what);
2005 fwrite(&where, sizeof(where), 1, f);
2006 fwrite(&what, sizeof(what), 1, f);
2012 m_cuesheet_changed = 0;
2015 void eDVBServicePlay::cutlistToCuesheet()
2019 eDebug("no cue sheet");
2024 if (!m_cutlist_enabled)
2026 m_cue->commitSpans();
2027 eDebug("cutlists were disabled");
2031 pts_t in = 0, out = 0, length = 0;
2035 std::multiset<cueEntry>::iterator i(m_cue_entries.begin());
2039 if (i == m_cue_entries.end())
2042 if (i->what == 0) /* in */
2046 } else if (i->what == 1) /* out */
2048 else /* mark (2) or last play position (3) */
2056 m_cue->addSourceSpan(in, out);
2060 if (i == m_cue_entries.end())
2063 m_cue->commitSpans();
2066 RESULT eDVBServicePlay::enableSubtitles(eWidget *parent, ePyObject tuple)
2068 if (m_subtitle_widget)
2069 disableSubtitles(parent);
2072 int tuplesize = PyTuple_Size(tuple);
2075 if (!PyTuple_Check(tuple))
2081 entry = PyTuple_GET_ITEM(tuple, 0);
2083 if (!PyInt_Check(entry))
2086 type = PyInt_AsLong(entry);
2088 if (type == 1) // teletext subtitles
2090 int page, magazine, pid;
2094 if (!m_teletext_parser)
2096 eDebug("enable teletext subtitles.. no parser !!!");
2100 entry = PyTuple_GET_ITEM(tuple, 1);
2101 if (!PyInt_Check(entry))
2103 pid = PyInt_AsLong(entry);
2105 entry = PyTuple_GET_ITEM(tuple, 2);
2106 if (!PyInt_Check(entry))
2108 page = PyInt_AsLong(entry);
2110 entry = PyTuple_GET_ITEM(tuple, 3);
2111 if (!PyInt_Check(entry))
2113 magazine = PyInt_AsLong(entry);
2115 m_subtitle_widget = new eSubtitleWidget(parent);
2116 m_subtitle_widget->resize(parent->size()); /* full size */
2117 m_teletext_parser->setPageAndMagazine(page, magazine);
2119 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE,((pid&0xFFFF)<<16)|((page&0xFF)<<8)|(magazine&0xFF));
2123 int pid = 0, composition_page_id = 0, ancillary_page_id = 0;
2124 if (!m_subtitle_parser)
2126 eDebug("enable dvb subtitles.. no parser !!!");
2132 entry = PyTuple_GET_ITEM(tuple, 1);
2133 if (!PyInt_Check(entry))
2135 pid = PyInt_AsLong(entry);
2137 entry = PyTuple_GET_ITEM(tuple, 2);
2138 if (!PyInt_Check(entry))
2140 composition_page_id = PyInt_AsLong(entry);
2142 entry = PyTuple_GET_ITEM(tuple, 3);
2143 if (!PyInt_Check(entry))
2145 ancillary_page_id = PyInt_AsLong(entry);
2147 m_subtitle_widget = new eSubtitleWidget(parent);
2148 m_subtitle_widget->resize(parent->size()); /* full size */
2149 m_subtitle_parser->start(pid, composition_page_id, ancillary_page_id);
2151 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, ((pid&0xFFFF)<<16)|((composition_page_id&0xFF)<<8)|(ancillary_page_id&0xFF));
2157 eDebug("enableSubtitles needs a tuple as 2nd argument!\n"
2158 "for teletext subtitles (0, pid, teletext_page, teletext_magazine)\n"
2159 "for dvb subtitles (1, pid, composition_page_id, ancillary_page_id)");
2163 RESULT eDVBServicePlay::disableSubtitles(eWidget *parent)
2165 delete m_subtitle_widget;
2166 m_subtitle_widget = 0;
2167 if (m_subtitle_parser)
2169 m_subtitle_parser->stop();
2170 m_dvb_subtitle_pages.clear();
2172 if (m_teletext_parser)
2174 m_teletext_parser->setPageAndMagazine(-1, -1);
2175 m_subtitle_pages.clear();
2178 m_dvb_service->setCacheEntry(eDVBService::cSUBTITLE, -1);
2182 PyObject *eDVBServicePlay::getCachedSubtitle()
2186 int tmp = m_dvb_service->getCacheEntry(eDVBService::cSUBTITLE);
2189 unsigned int data = (unsigned int)tmp;
2190 int pid = (data&0xFFFF0000)>>16;
2191 ePyObject tuple = PyTuple_New(4);
2192 eDVBServicePMTHandler::program program;
2193 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2194 if (!h.getProgramInfo(program))
2196 if (program.textPid==pid) // teletext
2197 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1)); // type teletext
2199 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0)); // type dvb
2200 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((data&0xFFFF0000)>>16)); // pid
2201 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong((data&0xFF00)>>8)); // composition_page / page
2202 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(data&0xFF)); // ancillary_page / magazine
2211 PyObject *eDVBServicePlay::getSubtitleList()
2213 if (!m_teletext_parser)
2219 ePyObject l = PyList_New(0);
2220 std::set<int> added_ttx_pages;
2222 std::set<eDVBServicePMTHandler::subtitleStream> &subs =
2223 m_teletext_parser->m_found_subtitle_pages;
2225 eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler;
2226 eDVBServicePMTHandler::program program;
2227 if (h.getProgramInfo(program))
2228 eDebug("getting program info failed.");
2231 for (std::vector<eDVBServicePMTHandler::subtitleStream>::iterator it(program.subtitleStreams.begin());
2232 it != program.subtitleStreams.end(); ++it)
2234 switch(it->subtitling_type)
2236 case 0x01: // ebu teletext subtitles
2238 int page_number = it->teletext_page_number & 0xFF;
2239 int magazine_number = it->teletext_magazine_number & 7;
2240 int hash = magazine_number << 8 | page_number;
2241 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2243 ePyObject tuple = PyTuple_New(5);
2244 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2245 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2246 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2247 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2248 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2249 PyList_Append(l, tuple);
2251 added_ttx_pages.insert(hash);
2256 case 0x20 ... 0x23: // dvb subtitles
2258 ePyObject tuple = PyTuple_New(5);
2259 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
2260 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2261 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(it->composition_page_id));
2262 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(it->ancillary_page_id));
2263 PyTuple_SET_ITEM(tuple, 4, PyString_FromString(it->language_code.c_str()));
2264 PyList_Insert(l, 0, tuple);
2272 for (std::set<eDVBServicePMTHandler::subtitleStream>::iterator it(subs.begin());
2273 it != subs.end(); ++it)
2275 int page_number = it->teletext_page_number & 0xFF;
2276 int magazine_number = it->teletext_magazine_number & 7;
2277 int hash = magazine_number << 8 | page_number;
2278 if (added_ttx_pages.find(hash) == added_ttx_pages.end())
2280 ePyObject tuple = PyTuple_New(5);
2281 PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(1));
2282 PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(it->pid));
2283 PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(page_number));
2284 PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(magazine_number));
2285 PyTuple_SET_ITEM(tuple, 4, PyString_FromString("und")); // undetermined
2286 PyList_Append(l, tuple);
2294 void eDVBServicePlay::newSubtitlePage(const eDVBTeletextSubtitlePage &page)
2296 if (m_subtitle_widget)
2298 m_subtitle_pages.push_back(page);
2299 checkSubtitleTiming();
2303 void eDVBServicePlay::checkSubtitleTiming()
2305 // eDebug("checkSubtitleTiming");
2306 if (!m_subtitle_widget)
2310 enum { TELETEXT, DVB } type;
2311 eDVBTeletextSubtitlePage page;
2312 eDVBSubtitlePage dvb_page;
2314 if (!m_subtitle_pages.empty())
2316 page = m_subtitle_pages.front();
2318 show_time = page.m_pts;
2320 else if (!m_dvb_subtitle_pages.empty())
2322 dvb_page = m_dvb_subtitle_pages.front();
2324 show_time = dvb_page.m_show_time;
2332 m_decoder->getPTS(0, pos);
2334 // eDebug("%lld %lld", pos, show_time);
2335 int diff = show_time - pos;
2338 eDebug("[late (%d ms)]", -diff / 90);
2343 eDebug("[invalid]");
2349 if (type == TELETEXT)
2351 eDebug("display teletext subtitle page");
2352 m_subtitle_widget->setPage(page);
2353 m_subtitle_pages.pop_front();
2357 eDebug("display dvb subtitle Page");
2358 m_subtitle_widget->setPage(dvb_page);
2359 m_dvb_subtitle_pages.pop_front();
2363 // eDebug("start subtitle delay %d", diff / 90);
2364 m_subtitle_sync_timer.start(diff / 90, 1);
2370 void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p)
2372 if (m_subtitle_widget)
2374 m_dvb_subtitle_pages.push_back(p);
2375 checkSubtitleTiming();
2379 int eDVBServicePlay::getAC3Delay()
2382 return m_dvb_service->getCacheEntry(eDVBService::cAC3DELAY);
2384 return m_decoder->getAC3Delay();
2389 int eDVBServicePlay::getPCMDelay()
2392 return m_dvb_service->getCacheEntry(eDVBService::cPCMDELAY);
2394 return m_decoder->getPCMDelay();
2399 void eDVBServicePlay::setAC3Delay(int delay)
2402 m_dvb_service->setCacheEntry(eDVBService::cAC3DELAY, delay ? delay : -1);
2404 m_decoder->setAC3Delay(delay);
2407 void eDVBServicePlay::setPCMDelay(int delay)
2410 m_dvb_service->setCacheEntry(eDVBService::cPCMDELAY, delay ? delay : -1);
2412 m_decoder->setPCMDelay(delay);
2415 DEFINE_REF(eDVBServicePlay)
2417 eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");