X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/ad5b517b4648c91ec34936ac5eba7cde4c34bb31..4eac43bf1c66847feef1711990e4c67043f90d79:/lib/dvb/pmt.cpp diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 2ab6777f..e940e58f 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include // access to python config eDVBServicePMTHandler::eDVBServicePMTHandler() :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF) @@ -86,9 +88,9 @@ void eDVBServicePMTHandler::PMTready(int error) { m_have_cached_program = false; serviceEvent(eventNewProgramInfo); - eEPGCache::getInstance()->PMTready(this); if (!m_pvr_channel) // don't send campmt to camd.socket for playbacked services { + eEPGCache::getInstance()->PMTready(this); if(!m_ca_servicePtr) { int demuxes[2] = {0,0}; @@ -140,7 +142,7 @@ void eDVBServicePMTHandler::PATready(int) PyObject *eDVBServicePMTHandler::getCaIds() { - PyObject *ret=0; + ePyObject ret; program prog; @@ -156,7 +158,7 @@ PyObject *eDVBServicePMTHandler::getCaIds() } } - return ret ? ret : PyList_New(0); + return ret ? (PyObject*)ret : (PyObject*)PyList_New(0); } int eDVBServicePMTHandler::getProgramInfo(struct program &program) @@ -174,11 +176,14 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) program.pmtPid = -1; program.textPid = -1; + int first_ac3 = -1; + program.defaultAudioStream = 0; + if ( m_service && !m_service->cacheEmpty() ) { cached_vpid = m_service->getCacheEntry(eDVBService::cVPID); - cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAC3PID); - cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAPID); + cached_apid_mpeg = m_service->getCacheEntry(eDVBService::cAPID); + cached_apid_ac3 = m_service->getCacheEntry(eDVBService::cAC3PID); cached_tpid = m_service->getCacheEntry(eDVBService::cTPID); } @@ -245,15 +250,36 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) s.composition_page_id = (*it)->getCompositionPageId(); s.ancillary_page_id = (*it)->getAncillaryPageId(); s.language_code = (*it)->getIso639LanguageCode(); - eDebug("add subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d", - s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id); +// eDebug("add dvb subtitle %s PID %04x, type %d, composition page %d, ancillary_page %d", +// s.language_code.c_str(), s.pid, s.subtitling_type, s.composition_page_id, s.ancillary_page_id); program.subtitleStreams.push_back(s); } break; } case TELETEXT_DESCRIPTOR: if ( program.textPid == -1 || (*es)->getPid() == cached_tpid ) - program.textPid = (*es)->getPid(); + { + subtitleStream s; + s.subtitling_type = 0x01; // EBU TELETEXT SUBTITLES + s.pid = program.textPid = (*es)->getPid(); + TeletextDescriptor *d = (TeletextDescriptor*)(*desc); + const VbiTeletextList *list = d->getVbiTeletexts(); + for (VbiTeletextConstIterator it(list->begin()); it != list->end(); ++it) + { + switch((*it)->getTeletextType()) + { + case 0x02: // Teletext subtitle page + case 0x05: // Teletext subtitle page for hearing impaired pepople + s.language_code = (*it)->getIso639LanguageCode(); + s.teletext_page_number = (*it)->getTeletextPageNumber(); + s.teletext_magazine_number = (*it)->getTeletextMagazineNumber(); +// eDebug("add teletext subtitle %s PID %04x, page number %d, magazine number %d", +// s.language_code.c_str(), s.pid, s.teletext_page_number, s.teletext_magazine_number); + program.subtitleStreams.push_back(s); + break; + } + } + } break; case DTS_DESCRIPTOR: isaudio = 1; @@ -294,14 +320,16 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) if (isaudio) { audio.pid = (*es)->getPid(); - if ( !program.audioStreams.empty() && - ( audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg) ) - { - program.audioStreams.push_back(program.audioStreams[0]); - program.audioStreams[0] = audio; - } - else - program.audioStreams.push_back(audio); + + /* if we find the cached pids, this will be our default stream */ + if (audio.pid == cached_apid_ac3 || audio.pid == cached_apid_mpeg) + program.defaultAudioStream = program.audioStreams.size(); + + /* also, we need to know the first non-mpeg (i.e. "ac3"/dts/...) stream */ + if ((audio.type != audioStream::atMPEG) && ((first_ac3 == -1) || (audio.pid == cached_apid_ac3))) + first_ac3 = program.audioStreams.size(); + + program.audioStreams.push_back(audio); } else if (isvideo) { @@ -328,6 +356,21 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) } } ret = 0; + + + /* finally some fixup: if our default audio stream is an MPEG audio stream, + and we have 'defaultac3' set, use the first available ac3 stream instead. + (note: if an ac3 audio stream was selected before, this will be also stored + in 'fisrt_ac3', so we don't need to worry. */ + bool defaultac3 = false; + std::string default_ac3; + + if (!ePythonConfigQuery::getConfigValue("config.av.defaultac3", default_ac3)) + defaultac3 = default_ac3 == "True"; + + if (defaultac3 && (first_ac3 != -1)) + program.defaultAudioStream = first_ac3; + m_cached_program = program; m_have_cached_program = true; } @@ -474,8 +517,9 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, } else { eDVBMetaParser parser; - - if (parser.parseFile(ref.path)) + + int ret=parser.parseFile(ref.path); + if (ret || !parser.m_ref.getServiceID().get() /* incorrect sid in meta file or recordings.epl*/ ) { eWarning("no .meta file found, trying to find PMT pid"); eDVBTSTools tstools; @@ -522,7 +566,7 @@ int eDVBServicePMTHandler::tune(eServiceReferenceDVB &ref, int use_decode_demux, } } else { - serviceEvent(eventTuneFailed); + serviceEvent(eventNoResources); return res; } @@ -834,3 +878,52 @@ void eDVBCAService::sendCAPMT() ++m_sendstate; } } + +static PyObject *createTuple(int pid, const char *type) +{ + PyObject *r = PyTuple_New(2); + PyTuple_SetItem(r, 0, PyInt_FromLong(pid)); + PyTuple_SetItem(r, 1, PyString_FromString(type)); + return r; +} + +static inline void PyList_AppendSteal(PyObject *list, PyObject *item) +{ + PyList_Append(list, item); + Py_DECREF(item); +} + +PyObject *eDVBServicePMTHandler::program::createPythonObject() +{ + PyObject *r = PyDict_New(); + + PyObject *l = PyList_New(0); + + PyList_AppendSteal(l, createTuple(0, "pat")); + + if (pmtPid != -1) + PyList_AppendSteal(l, createTuple(pmtPid, "pmt")); + + for (std::vector::const_iterator + i(videoStreams.begin()); + i != videoStreams.end(); ++i) + PyList_AppendSteal(l, createTuple(i->pid, "video")); + + for (std::vector::const_iterator + i(audioStreams.begin()); + i != audioStreams.end(); ++i) + PyList_AppendSteal(l, createTuple(i->pid, "audio")); + + for (std::vector::const_iterator + i(subtitleStreams.begin()); + i != subtitleStreams.end(); ++i) + PyList_AppendSteal(l, createTuple(i->pid, "subtitle")); + + PyList_AppendSteal(l, createTuple(pcrPid, "pcr")); + + if (textPid != -1) + PyList_AppendSteal(l, createTuple(textPid, "text")); + + PyDict_SetItemString(r, "pids", l); + return r; +}