#include #include #include #include #include #include #include #include #include DEFINE_REF(eServiceFactoryDVB) eServiceFactoryDVB::eServiceFactoryDVB() { ePtr sc; eServiceCenter::getInstance(sc); if (sc) sc->addServiceFactory(eServiceFactoryDVB::id, this); } eServiceFactoryDVB::~eServiceFactoryDVB() { ePtr sc; eServiceCenter::getInstance(sc); if (sc) sc->removeServiceFactory(eServiceFactoryDVB::id); } DEFINE_REF(eDVBServiceList); eDVBServiceList::eDVBServiceList(const eServiceReference &parent): m_parent(parent) { } 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) { 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::play(const eServiceReference &ref, ePtr &ptr) { // check resources... ptr = new eDVBServicePlay(ref); return 0; } RESULT eServiceFactoryDVB::record(const eServiceReference &, ePtr &ptr) { ptr = 0; return -1; } RESULT eServiceFactoryDVB::list(const eServiceReference &ref, ePtr &ptr) { ptr = new eDVBServiceList(ref); return 0; } RESULT eServiceFactoryDVB::info(const eServiceReference &ref, ePtr &ptr) { ptr = 0; // 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; } ePtr service; /* 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; } /* eDVBService has the iStaticServiceInformation interface, so we pass it here. */ ptr = service; return 0; } eDVBServicePlay::eDVBServicePlay(const eServiceReference &ref): m_reference(ref) { CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent); CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent); eDebug("DVB start (play)"); } 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_service_handler.getProgramInfo(program)) eDebug("getting program info failed."); else { eDebugNoNewLine("have %d video stream(s)", program.videoStreams.size()); if (!program.videoStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector::const_iterator i(program.videoStreams.begin()); i != program.videoStreams.end(); ++i) { if (vpid == -1) vpid = i->pid; if (i != program.videoStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size()); if (!program.audioStreams.empty()) { eDebugNoNewLine(" ("); for (std::vector::const_iterator i(program.audioStreams.begin()); i != program.audioStreams.end(); ++i) { if (apid == -1) apid = i->pid; if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); eDebugNoNewLine("%04x", i->pid); } eDebugNoNewLine(")"); } eDebug(", and the pcr pid is %04x", program.pcrPid); if (program.pcrPid != 0x1fff) pcrpid = program.pcrPid; } if (!m_decoder) { ePtr demux; m_service_handler.getDemux(demux); if (demux) demux->getMPEGDecoder(m_decoder); } if (m_decoder) { m_decoder->setVideoPID(vpid); m_decoder->setAudioPID(apid, 0); m_decoder->setSyncPCR(pcrpid); m_decoder->start(); } break; } } } RESULT eDVBServicePlay::start() { eDebug("starting DVB service"); 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::pause(ePtr &ptr) { // not yet possible, maybe later... ptr = 0; return -1; } RESULT eDVBServicePlay::info(ePtr &ptr) { ptr = this; return 0; } RESULT eDVBServicePlay::getName(const eServiceReference &ref, std::string &name) { name = "DVB service"; return 0; } RESULT eDVBServicePlay::getEvent(ePtr &evt, int nownext) { return m_event_handler.getEvent(evt, nownext); } DEFINE_REF(eDVBServicePlay) eAutoInitPtr init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");