X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/e4d92d5b785abd120322479ab4f8ff287b06c983..e7e5b70162a6e74d7ee293495635c79660e0f7a8:/lib/dvb/scan.cpp diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp index 0d466f96..19c10868 100644 --- a/lib/dvb/scan.cpp +++ b/lib/dvb/scan.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -13,18 +14,17 @@ #include #include -static bool scan_debug; -#define SCAN_eDebug(x...) do { if (scan_debug) eDebug(x); } while(0) -#define SCAN_eDebugNoNewLine(x...) do { if (scan_debug) eDebugNoNewLine(x); } while(0) +#define SCAN_eDebug(x...) do { if (m_scan_debug) eDebug(x); } while(0) +#define SCAN_eDebugNoNewLine(x...) do { if (m_scan_debug) eDebugNoNewLine(x); } while(0) DEFINE_REF(eDVBScan); eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug) :m_channel(channel), m_channel_state(iDVBChannel::state_idle) ,m_ready(0), m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT) - ,m_pmt_running(false), m_abort_current_pmt(false), m_flags(0), m_usePAT(usePAT) + ,m_pmt_running(false), m_abort_current_pmt(false), m_flags(0) + ,m_usePAT(usePAT), m_scan_debug(debug) { - scan_debug=debug; if (m_channel->getDemux(m_demux)) SCAN_eDebug("scan: failed to allocate demux!"); m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection); @@ -41,10 +41,14 @@ int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTr case 0: case 0x1111: return 0; + case 0x13E: // workaround for 11258H and 11470V on hotbird with same ONID/TSID (0x13E/0x578) + return orbital_position != 130 || tsid != 0x578; case 1: return orbital_position == 192; case 0x00B1: return tsid != 0x00B0; + case 0x00eb: + return tsid != 0x4321; case 0x0002: return abs(orbital_position-282) < 6; default: @@ -136,23 +140,33 @@ RESULT eDVBScan::nextChannel() RESULT eDVBScan::startFilter() { bool startSDT=true; - assert(m_demux); + ASSERT(m_demux); /* only start required filters filter */ if (m_ready_all & readyPAT) startSDT = m_ready & readyPAT; + // m_ch_current is not set, when eDVBScan is just used for a SDT update + if (!m_ch_current) + { + unsigned int channelFlags; + m_channel->getCurrentFrontendParameters(m_ch_current); + m_ch_current->getFlags(channelFlags); + if (channelFlags & iDVBFrontendParameters::flagOnlyFree) + m_flags |= scanOnlyFree; + } + m_SDT = 0; if (startSDT && (m_ready_all & readySDT)) { - m_SDT = new eTable(); + m_SDT = new eTable(m_scan_debug); int tsid=-1; if (m_ready & readyPAT && m_ready & validPAT) { std::vector::const_iterator i = m_PAT->getSections().begin(); - assert(i != m_PAT->getSections().end()); + ASSERT(i != m_PAT->getSections().end()); tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id m_pat_tsid = eTransportStreamID(tsid); for (; i != m_PAT->getSections().end(); ++i) @@ -162,11 +176,11 @@ RESULT eDVBScan::startFilter() for (; program != pat.getPrograms()->end(); ++program) m_pmts_to_read.insert(std::pair((*program)->getProgramNumber(), service((*program)->getProgramMapPid()))); } - m_PMT = new eTable(); + m_PMT = new eTable(m_scan_debug); CONNECT(m_PMT->tableReady, eDVBScan::PMTready); - PMTready(-1); - + PMTready(-2); // KabelBW HACK ... on 618Mhz and 626Mhz the transport stream id in PAT and SDT is different + { int type; m_ch_current->getSystem(type); @@ -195,8 +209,8 @@ RESULT eDVBScan::startFilter() m_PAT = 0; if (m_ready_all & readyPAT) { - m_PAT = new eTable(); - if (m_PAT->start(m_demux, eDVBPATSpec())) + m_PAT = new eTable(m_scan_debug); + if (m_PAT->start(m_demux, eDVBPATSpec(4000))) return -1; CONNECT(m_PAT->tableReady, eDVBScan::PATready); } @@ -204,7 +218,7 @@ RESULT eDVBScan::startFilter() m_NIT = 0; if (m_ready_all & readyNIT) { - m_NIT = new eTable(); + m_NIT = new eTable(m_scan_debug); if (m_NIT->start(m_demux, eDVBNITSpec())) return -1; CONNECT(m_NIT->tableReady, eDVBScan::NITready); @@ -213,13 +227,12 @@ RESULT eDVBScan::startFilter() m_BAT = 0; if (m_ready_all & readyBAT) { - m_BAT = new eTable(); + m_BAT = new eTable(m_scan_debug); if (m_BAT->start(m_demux, eDVBBATSpec())) return -1; CONNECT(m_BAT->tableReady, eDVBScan::BATready); } } - return 0; } @@ -269,6 +282,7 @@ void eDVBScan::PMTready(int err) bool have_video = false; unsigned short pcrpid = 0xFFFF; std::vector::const_iterator i; + for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i) { const ProgramMapSection &pmt = **i; @@ -279,65 +293,82 @@ void eDVBScan::PMTready(int err) ElementaryStreamInfoConstIterator es; for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es) { - int isaudio = 0, isvideo = 0, is_scrambled = 0; + int isaudio = 0, isvideo = 0, is_scrambled = 0, forced_audio = 0, forced_video = 0; switch ((*es)->getType()) { case 0x1b: // AVC Video Stream (MPEG4 H264) + case 0x10: // MPEG 4 Part 2 case 0x01: // MPEG 1 video case 0x02: // MPEG 2 video isvideo = 1; + forced_video = 1; //break; fall through !!! case 0x03: // MPEG 1 audio - case 0x04: // MPEG 2 audio: - if (!isvideo) + case 0x04: // MPEG 2 audio + case 0x0f: // MPEG 2 AAC + case 0x11: // MPEG 4 AAC + if (!isvideo) + { + forced_audio = 1; 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. */ + case 0xEA: // TS_PSI_ST_SMPTE_VC1 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { uint8_t tag = (*desc)->getTag(); - if (!isaudio && !isvideo) + /* PES private can contain AC-3, DTS or lots of other stuff. + check descriptors to get the exakt type. */ + if (!forced_video && !forced_audio) { switch (tag) { - case DTS_DESCRIPTOR: + case 0x1C: // TS_PSI_DT_MPEG4_Audio + case 0x2B: // TS_PSI_DT_MPEG2_AAC case AAC_DESCRIPTOR: - isaudio = 1; case AC3_DESCRIPTOR: + case DTS_DESCRIPTOR: + case AUDIO_STREAM_DESCRIPTOR: isaudio = 1; - break; + break; + case 0x28: // TS_PSI_DT_AVC + case 0x1B: // TS_PSI_DT_MPEG4_Video + case VIDEO_STREAM_DESCRIPTOR: + isvideo = 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) + RegistrationDescriptor *d = (RegistrationDescriptor*)(*desc); + switch (d->getFormatIdentifier()) { - case 0x41432d33: + case 0x44545331 ... 0x44545333: // DTS1/DTS2/DTS3 + case 0x41432d33: // == 'AC-3' + case 0x42535344: // == 'BSSD' (LPCM) isaudio = 1; + break; + case 0x56432d31: // == 'VC-1' + isvideo = 1; + break; default: break; } - break; } + default: + break; } } if (tag == CA_DESCRIPTOR) is_scrambled = 1; } + default: break; } - if (isaudio) - have_audio = true; - else if (isvideo) + if (isvideo) have_video = true; + else if (isaudio) + have_audio = true; else continue; if (is_scrambled) @@ -358,7 +389,7 @@ void eDVBScan::PMTready(int err) else m_pmt_in_progress->second.serviceType = 100; } - if (err == -2) // aborted in sdt progress + 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; @@ -369,9 +400,10 @@ void eDVBScan::PMTready(int err) } 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)); + 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(); } @@ -493,16 +525,6 @@ void eDVBScan::channelDone() { unsigned long hash = 0; - // m_ch_current is not set, when eDVBScan is just used for a SDT update - if (!m_ch_current) - { - unsigned int channelFlags; - m_channel->getCurrentFrontendParameters(m_ch_current); - m_ch_current->getFlags(channelFlags); - if (channelFlags & iDVBFrontendParameters::flagOnlyFree) - m_flags |= scanOnlyFree; - } - m_ch_current->getHash(hash); eDVBNamespace dvbnamespace = buildNamespace( @@ -656,7 +678,7 @@ void eDVBScan::channelDone() if (m_abort_current_pmt) { m_abort_current_pmt = false; - PMTready(-2); + PMTready(-1); } return; } @@ -694,16 +716,6 @@ void eDVBScan::channelDone() { unsigned long hash = 0; - // m_ch_current is not set, when eDVBScan is just used for a SDT update - if (!m_ch_current) - { - unsigned int channelFlags; - m_channel->getCurrentFrontendParameters(m_ch_current); - m_ch_current->getFlags(channelFlags); - if (channelFlags & iDVBFrontendParameters::flagOnlyFree) - m_flags |= scanOnlyFree; - } - m_ch_current->getHash(hash); m_chid_current = eDVBChannelID( @@ -750,11 +762,20 @@ void eDVBScan::channelDone() } case iDVBFrontend::feTerrestrial: { + ePtr fe; eDVBFrontendParametersTerrestrial parm; m_ch_current->getDVBT(parm); snprintf(sname, 255, "%d SID 0x%02x", parm.frequency/1000, m_pmt_in_progress->first); + if (!m_channel->getFrontend(fe)) + { + ePyObject tp_dict = PyDict_New(); + fe->getTransponderData(tp_dict, false); + m_corrected_frequencys[m_chid_current] = + PyInt_AsLong(PyDict_GetItemString(tp_dict, "frequency")); + Py_DECREF(tp_dict); + } break; } case iDVBFrontend::feCable: @@ -770,16 +791,21 @@ void eDVBScan::channelDone() SCAN_eDebug("name '%s', provider_name '%s'", sname, pname); service->m_service_name = convertDVBUTF8(sname); service->genSortName(); - service->m_provider_name = pname; + service->m_provider_name = convertDVBUTF8(pname); } - std::pair >::iterator, bool> i = m_new_services.insert(std::pair >(ref, service)); - - if (i.second) - { - m_last_service = i.first; - m_event(evtNewService); + if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) { + SCAN_eDebug("add not scrambled!"); + std::pair >::iterator, bool> i = + m_new_services.insert(std::pair >(ref, service)); + if (i.second) + { + m_last_service = i.first; + m_event(evtNewService); + } } + else + SCAN_eDebug("dont add... is scrambled!"); m_pmts_to_read.erase(m_pmt_in_progress++); } @@ -928,6 +954,24 @@ void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags) for (std::map >::const_iterator ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch) { + int system; + ch->second->getSystem(system); + if (system == iDVBFrontend::feTerrestrial) + { + std::map::iterator it = m_corrected_frequencys.find(ch->first); + if (it != m_corrected_frequencys.end()) + { + eDVBFrontendParameters *p = (eDVBFrontendParameters*)&(*ch->second); + eDVBFrontendParametersTerrestrial parm; + p->getDVBT(parm); + eDebug("corrected freq for tsid %04x, onid %04x, ns %08x is %d, old was %d", + ch->first.transport_stream_id.get(), ch->first.original_network_id.get(), + ch->first.dvbnamespace.get(), it->second, parm.frequency); + parm.frequency = it->second; + p->setDVBT(parm); + m_corrected_frequencys.erase(it); + } + } if (m_flags & scanOnlyFree) { eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second); @@ -990,9 +1034,13 @@ RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescription SCAN_eDebug("is scrambled!"); add = false; } + else + SCAN_eDebug("is free"); } - else + else { SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!"); + add = false; + } } if (add) @@ -1038,7 +1086,8 @@ RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescription } } - std::pair >::iterator, bool> i = m_new_services.insert(std::pair >(ref, service)); + std::pair >::iterator, bool> i = + m_new_services.insert(std::pair >(ref, service)); if (i.second) {