X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/d63d2c3c6cbbd574dda4f8b00ebe6c661735edd5..defa1a765f48ec880b36b14a247b89649553c2ec:/lib/service/servicedvb.cpp diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index fc48fa66..5618477c 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -6,9 +6,39 @@ #include #include +#include +#include + +#include +#include + +class eStaticServiceDVBPVRInformation: public iStaticServiceInformation +{ + DECLARE_REF(eStaticServiceDVBPVRInformation); + eServiceReference m_ref; + eDVBMetaParser m_parser; +public: + eStaticServiceDVBPVRInformation(const eServiceReference &ref); + RESULT getName(const eServiceReference &ref, std::string &name); +}; + +DEFINE_REF(eStaticServiceDVBPVRInformation); + +eStaticServiceDVBPVRInformation::eStaticServiceDVBPVRInformation(const eServiceReference &ref) +{ + m_ref = ref; + m_parser.parseFile(ref.path); +} + +RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, std::string &name) +{ + ASSERT(ref == m_ref); + name = m_parser.m_name.size() ? m_parser.m_name : ref.path; +} + DEFINE_REF(eServiceFactoryDVB) -eServiceFactoryDVB::eServiceFactoryDVB(): ref(0) +eServiceFactoryDVB::eServiceFactoryDVB() { ePtr sc; @@ -26,36 +56,137 @@ eServiceFactoryDVB::~eServiceFactoryDVB() sc->removeServiceFactory(eServiceFactoryDVB::id); } -RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr &ptr) +DEFINE_REF(eDVBServiceList); + +eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent) { - RESULT res; - // check resources... - ptr = new eDVBServicePlay(ref); - res = ptr->start(); - if (res) +} + +eDVBServiceList::~eDVBServiceList() +{ +} + +RESULT eDVBServiceList::getContent(std::list &list) +{ + ePtr db; + ePtr res; + + int err; + if ((err = eDVBResourceManager::getInstance(res)) != 0) + { + eDebug("no resource manager"); + return err; + } + if ((err = res->getChannelList(db)) != 0) { - ptr = 0; - return res; + eDebug("no channel list"); + return err; } + + ePtr query; + + ePtr q; + + if (m_parent.path.size()) + eDVBChannelQuery::compile(q, m_parent.path); + + if ((err = db->startQuery(query, q)) != 0) + { + eDebug("startQuery failed"); + return err; + } + + eServiceReferenceDVB ref; + + while (!query->getNextResult(ref)) + list.push_back(ref); return 0; } -RESULT eServiceFactoryDVB::record(const eServiceReference &, ePtr &ptr) +RESULT eDVBServiceList::getNext(eServiceReference &) { - ptr = 0; + /* implement me */ return -1; } -RESULT eServiceFactoryDVB::list(const eServiceReference &, ePtr &ptr) +RESULT eServiceFactoryDVB::play(const eServiceReference &ref, ePtr &ptr) { - ptr = 0; - return -1; + ePtr service; + int r = lookupService(service, ref); + if (r) + service = 0; + // check resources... + ptr = new eDVBServicePlay(ref, service); + return 0; +} + +RESULT eServiceFactoryDVB::record(const eServiceReference &ref, ePtr &ptr) +{ + ptr = new eDVBServiceRecord((eServiceReferenceDVB&)ref); + return 0; } -eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref): - ref(0), m_reference(ref) +RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr &ptr) { - CONNECT(m_serviceHandler.serviceEvent, eDVBServicePlay::serviceEvent); + ptr = new eDVBServiceList(ref); + return 0; +} + +RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr &ptr) +{ + /* do we have a PVR service? */ + if (ref.path.size()) + { + ptr = new eStaticServiceDVBPVRInformation(ref); + return 0; + } else + { + ePtr service; + int r = lookupService(service, ref); + if (r) + return r; + /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */ + ptr = service; + return 0; + } +} + +RESULT eServiceFactoryDVB::lookupService(ePtr &service, const eServiceReference &ref) +{ + // TODO: handle the listing itself + // if (ref.... == -1) .. return "... bouquets ..."; + // could be also done in another serviceFactory (with seperate ID) to seperate actual services and lists + // TODO: cache + ePtr db; + ePtr res; + + int err; + if ((err = eDVBResourceManager::getInstance(res)) != 0) + { + eDebug("no resource manager"); + return err; + } + if ((err = res->getChannelList(db)) != 0) + { + eDebug("no channel list"); + return err; + } + + /* we are sure to have a ..DVB reference as the info() call was forwarded here according to it's ID. */ + if ((err = db->getService((eServiceReferenceDVB&)ref, service)) != 0) + { + eDebug("getService failed!"); + return err; + } + + return 0; +} + +eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref, eDVBService *service): + m_reference(ref), m_dvb_service(service) +{ + CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent); + CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent); eDebug("DVB start (play)"); } @@ -64,16 +195,44 @@ eDVBServicePlay::~eDVBServicePlay() eDebug("DVB stop (play)"); } +void eDVBServicePlay::gotNewEvent() +{ +#if 0 + // debug only + ePtr m_event_now, m_event_next; + getEvent(m_event_now, 0); + getEvent(m_event_next, 1); + + if (m_event_now) + eDebug("now running: %s (%d seconds :)", m_event_now->m_event_name.c_str(), m_event_now->m_duration); + if (m_event_next) + eDebug("next running: %s (%d seconds :)", m_event_next->m_event_name.c_str(), m_event_next->m_duration); +#endif + m_event((iPlayableService*)this, evUpdatedEventInfo); +} + void eDVBServicePlay::serviceEvent(int event) { eDebug("service event %d", event); switch (event) { + case eDVBServicePMTHandler::eventTuned: + { + ePtr m_demux; + if (!m_service_handler.getDemux(m_demux)) + { +// eventStartedEventAcquisition + m_event_handler.start(m_demux, ((eServiceReferenceDVB&)m_reference).getServiceID().get()); + } else + eDebug("no event data available :( "); +// eventNoEvent + break; + } case eDVBServicePMTHandler::eventNewProgramInfo: { int vpid = -1, apid = -1, pcrpid = -1; eDVBServicePMTHandler::program program; - if (m_serviceHandler.getProgramInfo(program)) + if (m_service_handler.getProgramInfo(program)) eDebug("getting program info failed."); else { @@ -117,7 +276,7 @@ void eDVBServicePlay::serviceEvent(int event) if (!m_decoder) { ePtr demux; - m_serviceHandler.getDemux(demux); + m_service_handler.getDemux(demux); if (demux) demux->getMPEGDecoder(m_decoder); } @@ -128,8 +287,14 @@ void eDVBServicePlay::serviceEvent(int event) m_decoder->setAudioPID(apid, 0); m_decoder->setSyncPCR(pcrpid); m_decoder->start(); +// how we can do this better? +// update cache pid when the user changed the audio track or video track +// TODO handling of difference audio types.. default audio types.. + m_dvb_service->setCachePID(eDVBService::cVPID, vpid); + m_dvb_service->setCachePID(eDVBService::cAPID, apid); + m_dvb_service->setCachePID(eDVBService::cPCRPID, pcrpid); } - + break; } } @@ -138,17 +303,49 @@ void eDVBServicePlay::serviceEvent(int event) RESULT eDVBServicePlay::start() { eDebug("starting DVB service"); - m_serviceHandler.tune((eServiceReferenceDVB&)m_reference); + m_event(this, evStart); + return m_service_handler.tune((eServiceReferenceDVB&)m_reference); +} + +RESULT eDVBServicePlay::stop() +{ + eDebug("stopping.."); + return 0; +} + +RESULT eDVBServicePlay::connectEvent(const Slot2 &event, ePtr &connection) +{ + connection = new eConnection((iPlayableService*)this, m_event.connect(event)); return 0; } -RESULT eDVBServicePlay::getIPausableService(ePtr &ptr) +RESULT eDVBServicePlay::pause(ePtr &ptr) { // not yet possible, maybe later... ptr = 0; return -1; } +RESULT eDVBServicePlay::info(ePtr &ptr) +{ + ptr = this; + return 0; +} + +RESULT eDVBServicePlay::getName(std::string &name) +{ + if (m_dvb_service) + m_dvb_service->getName(m_reference, name); + else + name = "DVB service"; + return 0; +} + +RESULT eDVBServicePlay::getEvent(ePtr &evt, int nownext) +{ + return m_event_handler.getEvent(evt, nownext); +} + DEFINE_REF(eDVBServicePlay) -eAutoInitP0 init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB"); +eAutoInitPtr init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");