+void eDVBScan::PMTready(int err)
+{
+ SCAN_eDebug("got pmt %d", err);
+ if (!err)
+ {
+ bool scrambled = false;
+ bool have_audio = false;
+ bool have_video = false;
+ unsigned short pcrpid = 0xFFFF;
+ std::vector<ProgramMapSection*>::const_iterator i;
+ for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
+ {
+ const ProgramMapSection &pmt = **i;
+ if (pcrpid == 0xFFFF)
+ pcrpid = pmt.getPcrPid();
+ else
+ SCAN_eDebug("already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
+ ElementaryStreamInfoConstIterator es;
+ for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
+ {
+ int isaudio = 0, isvideo = 0, is_scrambled = 0;
+ switch ((*es)->getType())
+ {
+ case 0x1b: // AVC Video Stream (MPEG4 H264)
+ case 0x01: // MPEG 1 video
+ case 0x02: // MPEG 2 video
+ isvideo = 1;
+ //break; fall through !!!
+ case 0x03: // MPEG 1 audio
+ case 0x04: // MPEG 2 audio:
+ if (!isvideo)
+ isaudio = 1;
+ //break; fall through !!!
+ case 0x06: // PES Private
+ case 0x81: // user private
+ /* PES private can contain AC-3, DTS or lots of other stuff.
+ check descriptors to get the exact type. */
+ for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
+ desc != (*es)->getDescriptors()->end(); ++desc)
+ {
+ uint8_t tag = (*desc)->getTag();
+ if (!isaudio && !isvideo)
+ {
+ switch (tag)
+ {
+ case DTS_DESCRIPTOR:
+ case AAC_DESCRIPTOR:
+ case AC3_DESCRIPTOR:
+ isaudio = 1;
+ break;
+ case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
+ {
+ /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
+ if ((*desc)->getLength() != 4)
+ break;
+ unsigned char descr[6];
+ (*desc)->writeToBuffer(descr);
+ int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
+ switch (format_identifier)
+ {
+ case 0x41432d33:
+ isaudio = 1;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+ }
+ if (tag == CA_DESCRIPTOR)
+ is_scrambled = 1;
+ }
+ break;
+ }
+ if (isaudio)
+ have_audio = true;
+ else if (isvideo)
+ have_video = true;
+ else
+ continue;
+ if (is_scrambled)
+ scrambled = true;
+ }
+ for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
+ desc != pmt.getDescriptors()->end(); ++desc)
+ {
+ if ((*desc)->getTag() == CA_DESCRIPTOR)
+ scrambled = true;
+ }
+ }
+ m_pmt_in_progress->second.scrambled = scrambled;
+ if ( have_video )
+ m_pmt_in_progress->second.serviceType = 1;
+ else if ( have_audio )
+ m_pmt_in_progress->second.serviceType = 2;
+ else
+ m_pmt_in_progress->second.serviceType = 100;
+ }
+ if (err == -1) // timeout or removed by sdt
+ m_pmts_to_read.erase(m_pmt_in_progress++);
+ else if (m_pmt_running)
+ ++m_pmt_in_progress;
+ else
+ {
+ m_pmt_in_progress = m_pmts_to_read.begin();
+ m_pmt_running = true;
+ }
+
+ if (m_pmt_in_progress != m_pmts_to_read.end())
+ m_PMT->start(m_demux, eDVBPMTSpec(m_pmt_in_progress->second.pmtPid, m_pmt_in_progress->first, 4000));
+ else
+ {
+ m_PMT = 0;
+ m_pmt_running = false;
+ channelDone();
+ }
+}
+
+