ePtr<eTable<ProgramAssociationSection> > ptr;
if (!m_PAT.getCurrent(ptr))
{
+ int service_id_single = -1;
+ int pmtpid_single = -1;
int pmtpid = -1;
std::vector<ProgramAssociationSection*>::const_iterator i;
for (i = ptr->getSections().begin(); pmtpid == -1 && i != ptr->getSections().end(); ++i)
const ProgramAssociationSection &pat = **i;
ProgramAssociationConstIterator program;
for (program = pat.getPrograms()->begin(); pmtpid == -1 && program != pat.getPrograms()->end(); ++program)
+ {
if (eServiceID((*program)->getProgramNumber()) == m_reference.getServiceID())
pmtpid = (*program)->getProgramMapPid();
+ if (pmtpid_single == -1 && pmtpid == -1)
+ {
+ pmtpid_single = (*program)->getProgramMapPid();
+ service_id_single = (*program)->getProgramNumber();
+ }
+ else
+ pmtpid_single = service_id_single = -1;
+ }
+ }
+ if (pmtpid_single != -1) // only one PAT entry .. so we use this one
+ {
+ m_reference.setServiceID(eServiceID(service_id_single));
+ pmtpid = pmtpid_single;
}
if (pmtpid == -1)
serviceEvent(eventNoPATEntry);
serviceEvent(eventNoPAT);
}
-PyObject *eDVBServicePMTHandler::getCaIds()
+PyObject *eDVBServicePMTHandler::getCaIds(bool pair)
{
ePyObject ret;
if (cnt)
{
ret=PyList_New(cnt);
- std::set<uint16_t>::iterator it(prog.caids.begin());
- while(cnt--)
- PyList_SET_ITEM(ret, cnt, PyInt_FromLong(*it++));
+ std::set<program::capid_pair>::iterator it(prog.caids.begin());
+ if (pair)
+ {
+ while(cnt--)
+ {
+ ePyObject tuple = PyTuple_New(2);
+ PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(it->caid));
+ PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong((it++)->capid));
+ PyList_SET_ITEM(ret, cnt, tuple);
+ }
+ }
+ else
+ {
+ while(cnt--)
+ PyList_SET_ITEM(ret, cnt, PyInt_FromLong((it++)->caid));
+ }
}
}
return ret ? (PyObject*)ret : (PyObject*)PyList_New(0);
}
-int eDVBServicePMTHandler::getProgramInfo(struct program &program)
+int eDVBServicePMTHandler::getProgramInfo(program &program)
{
ePtr<eTable<ProgramMapSection> > ptr;
int cached_apid_ac3 = -1;
for (i = ptr->getSections().begin(); i != ptr->getSections().end(); ++i)
{
const ProgramMapSection &pmt = **i;
+ int is_hdmv = 0;
+
program.pcrPid = pmt.getPcrPid();
- program.caids.insert(descr->getCaSystemId());
+ for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
+ desc != pmt.getDescriptors()->end(); ++desc)
+ {
+ if ((*desc)->getTag() == CA_DESCRIPTOR)
+ {
+ CaDescriptor *descr = (CaDescriptor*)(*desc);
++ program::capid_pair pair;
++ pair.caid = descr->getCaSystemId();
++ pair.capid = descr->getCaPid();
++ program.caids.insert(pair);
+ }
+ else if ((*desc)->getTag() == REGISTRATION_DESCRIPTOR)
+ {
+ RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc);
+ if (d->getFormatIdentifier() == 0x48444d56) // HDMV
+ is_hdmv = 1;
+ }
+ }
+
ElementaryStreamInfoConstIterator es;
for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
{
audio.type = audioStream::atAACHE;
forced_audio = 1;
}
- case 0x80: // user private ... but blueray LPCM
- if (!isvideo && !isaudio)
+ case 0x80: // user private ... but bluray LPCM
+ case 0xA0: // bluray secondary LPCM
+ if (!isvideo && !isaudio && is_hdmv)
{
isaudio = 1;
audio.type = audioStream::atLPCM;
}
- case 0x81: // user private ... but blueray AC3
- if (!isvideo && !isaudio)
+ case 0x81: // user private ... but bluray AC3
+ case 0xA1: // bluray secondary AC3
+ if (!isvideo && !isaudio && is_hdmv)
{
isaudio = 1;
audio.type = audioStream::atAC3;
}
- case 0x82: // Blueray DTS (dvb user private...)
- case 0xA2: // Blueray secondary DTS
- if (!isvideo && !isaudio)
+ case 0x82: // bluray DTS (dvb user private...)
+ case 0xA2: // bluray secondary DTS
+ if (!isvideo && !isaudio && is_hdmv)
{
isaudio = 1;
audio.type = audioStream::atDTS;
}
+ case 0x86: // bluray DTS-HD (dvb user private...)
+ case 0xA6: // bluray secondary DTS-HD
+ if (!isvideo && !isaudio && is_hdmv)
+ {
+ isaudio = 1;
+ audio.type = audioStream::atDTSHD;
+ }
case 0x06: // PES Private
case 0xEA: // TS_PSI_ST_SMPTE_VC1
{
case CA_DESCRIPTOR:
{
CaDescriptor *descr = (CaDescriptor*)(*desc);
- program.caids.insert(descr->getCaSystemId());
+ program::capid_pair pair;
+ pair.caid = descr->getCaSystemId();
+ pair.capid = descr->getCaPid();
+ program.caids.insert(pair);
break;
}
default:
default:
break;
}
- if (isteletext && (isaudio || isvideo))
+ if (isteletext && (isaudio || isvideo))
{
- eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());
+ eDebug("ambiguous streamtype for PID %04x detected.. forced as teletext!", (*es)->getPid());
continue; // continue with next PID
}
else if (issubtitle && (isaudio || isvideo))
else
continue;
}
- for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
- desc != pmt.getDescriptors()->end(); ++desc)
- {
- if ((*desc)->getTag() == CA_DESCRIPTOR)
- {
- CaDescriptor *descr = (CaDescriptor*)(*desc);
- program::capid_pair pair;
- pair.caid = descr->getCaSystemId();
- pair.capid = descr->getCaPid();
- program.caids.insert(pair);
- }
- }
}
ret = 0;
program.textPid = cached_tpid;
}
CAID_LIST &caids = m_service->m_ca;
- for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it)
- program.caids.insert(*it);
+ for (CAID_LIST::iterator it(caids.begin()); it != caids.end(); ++it) {
+ program::capid_pair pair;
+ pair.caid = *it;
+ pair.capid = -1; // not known yet
+ program.caids.insert(pair);
+ }
if ( cnt )
ret = 0;
}
{
int pid,
rdsPid; // hack for some radio services which transmit radiotext on different pid (i.e. harmony fm, HIT RADIO FFH, ...)
- enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM };
+ enum { atMPEG, atAC3, atDTS, atAAC, atAACHE, atLPCM, atDTSHD };
int type; // mpeg2, ac3, dts, ...
int component_tag;
struct program
{
+ struct capid_pair
+ {
+ uint16_t caid;
+ int capid;
+ bool operator< (const struct capid_pair &t) { return t.caid < caid; }
+ };
std::vector<videoStream> videoStreams;
std::vector<audioStream> audioStreams;
int defaultAudioStream;
std::vector<subtitleStream> subtitleStreams;
- std::set<uint16_t> caids;
+ std::set<capid_pair> caids;
int pcrPid;
int pmtPid;
int textPid;
PyObject *createPythonObject();
};
- int getProgramInfo(struct program &program);
+ int getProgramInfo(program &program);
int getDataDemux(ePtr<iDVBDemux> &demux);
int getDecodeDemux(ePtr<iDVBDemux> &demux);
- PyObject *getCaIds();
+ PyObject *getCaIds(bool pair=false); // caid / ecmpid pair
int getPVRChannel(ePtr<iDVBPVRChannel> &pvr_channel);
int getServiceReference(eServiceReferenceDVB &service) { service = m_reference; return 0; }