36#include <QMutexLocker>
43#include "libmythbase/mythconfig.h"
85 return "ChannelScanSM(u)";
88#define LOC (ChannelScanSM::loc(this) + ": ")
149 int sourceID, std::chrono::milliseconds signal_timeout,
150 std::chrono::milliseconds channel_timeout, QString inputname,
151 bool test_decryption)
153 m_scanMonitor(scan_monitor),
155 m_signalMonitor(
SignalMonitor::Init(cardtype, m_channel->GetInputID(),
157 m_sourceID(sourceID),
158 m_signalTimeout(signal_timeout),
159 m_channelTimeout(channel_timeout),
160 m_inputName(
std::move(inputname)),
161 m_testDecryption(test_decryption),
172 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Connecting up DTVSignalMonitor");
177 "SELECT dvb_nit_id, bouquet_id, region_id, lcnoffset "
179 "WHERE videosource.sourceid = :SOURCEID");
185 else if (query.
next())
187 int nitid = query.
value(0).toInt();
188 data->SetRealNetworkID(nitid);
189 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
190 QString(
"Setting NIT-ID to %1").arg(nitid));
195 m_nitId = nitid > 0 ? nitid : 0;
198 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
199 QString(
"Freesat/Sky bouquet_id:%1 region_id:%2")
210 if (dvbchannel && dvbchannel->GetRotor())
214 data->AddMPEGListener(
this);
215 data->AddATSCMainListener(
this);
216 data->AddDVBMainListener(
this);
217 data->AddDVBOtherListener(
this);
224 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ChannelScanSM Stopped");
260 QMutexLocker locker(&
m_lock);
262 QString cur_chan = (*m_current).m_friendlyName;
263 QStringList list = cur_chan.split(
" ", Qt::SkipEmptyParts);
264 QString freqid = (list.size() >= 2) ? list[1] : cur_chan;
266 QString msg = QObject::tr(
"Updated Channel %1").arg(cur_chan);
272 QString callsign = QString(
"%1-%2")
290 QObject::tr(
"Added Channel %1").arg(cur_chan) :
291 QObject::tr(
"Failed to add channel %1").arg(cur_chan);
331 if (multiplexes.empty())
333 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
"Unable to find any transports for " +
334 QString(
"sourceid %1").arg(sourceid));
339 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
340 QString(
"Found %1 transports for ").arg(multiplexes.size()) +
341 QString(
"sourceid %1").arg(sourceid));
343 for (
uint multiplex : multiplexes)
356 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
357 "Unable to find add any transports for " +
358 QString(
"sourceid %1").arg(sourceid));
370 QStringList lines =
string.split(
'\n');
371 for (
const QString& line : std::as_const(lines))
372 LOG(VB_CHANSCAN, LOG_DEBUG, line);
378 QMutexLocker locker(&
m_lock);
380 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
381 QString(
"Got a Program Association Table for %1")
382 .arg((*m_current).m_friendlyName));
387 if (
nullptr == monitor)
398 QMutexLocker locker(&
m_lock);
400 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
401 QString(
"Got a Conditional Access Table for %1")
402 .arg((*m_current).m_friendlyName));
408 QMutexLocker locker(&
m_lock);
410 LOG(VB_CHANSCAN, LOG_INFO,
LOC + QString(
"Got a Program Map Table for %1 program %2 (0x%3)")
424 QMutexLocker locker(&
m_lock);
426 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
427 QString(
"Got a Virtual Channel Table for %1")
428 .arg((*m_current).m_friendlyName));
444 QMutexLocker locker(&
m_lock);
446 LOG(VB_CHANSCAN, LOG_INFO,
LOC + QString(
"Got the Master Guide for %1")
447 .arg((*m_current).m_friendlyName));
462 QMutexLocker locker(&
m_lock);
464 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
465 QString(
"Got a Service Description Table for %1 section %2/%3")
466 .arg((*m_current).m_friendlyName)
476 if (
nullptr != monitor)
479 if (
nullptr != stream)
488 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
489 QString(
"SDT has OriginalNetworkID %1, look for "
499 if (
nullptr != monitor)
502 SetVersionSDT(sdt->
TSID(), -1, 0);
522 QMutexLocker locker(&
m_lock);
524 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
525 QString(
"Got a Network Information Table id %1 for %2 section %3/%4")
526 .arg(nit->
NetworkID()).arg((*m_current).m_friendlyName)
535 QMutexLocker locker(&
m_lock);
537 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
538 QString(
"Got a Bouquet Association Table id %1 for %2 section %3/%4")
539 .arg(bat->
BouquetID()).arg((*m_current).m_friendlyName)
553 const unsigned char *def_auth =
555 const unsigned char *serv_list =
558 if (def_auth && serv_list)
569 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
570 QString(
"Found default authority '%1' in BAT for service nid %2 tid %3 sid %4")
572 .arg(netid).arg(tsid).arg(services.
ServiceID(j)));
573 uint64_t index = ((uint64_t)netid << 32) | (tsid << 16) |
585 QMutexLocker locker(&
m_lock);
587 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
588 QString(
"Got a Service Description Table (other) for Transport ID %1 section %2/%3")
603 const unsigned char *def_auth =
611 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
612 QString(
"Found default authority '%1' in SDTo for service nid %2 tid %3 sid %4")
614 .arg(netid).arg(tsid).arg(serviceId));
624 QMutexLocker locker(&
m_lock);
638 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't monitor decryption -- no pmts");
648 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"%1/%2 checked")
649 .arg(currentEncryptionStatusChecked.size())
650 .arg(currentEncryptionStatus.size()));
687 QObject::tr(
"Program %1 Testing Decryption")
690 QString(
"%1 -- Testing decryption of program %2")
691 .arg(cur_chan).arg(pnum);
694 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
702 if (
nullptr != monitor)
713 LOG(VB_GENERAL, LOG_INFO,
LOC +
714 QString(
"Can't monitor decryption of program %1 -- no pmt")
735 for (
auto & tt : tts)
749 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC + QString(
"%1 NIT nid:%2 fr:%3 section:%4/%5 ts count:%6 ")
755 uint32_t tsid = nit->
TSID(i);
757 uint32_t
id = netid << 16 | tsid;
766 for (
const auto *
const item : list)
768 uint64_t frequency = 0;
827 LOG(VB_CHANSCAN, LOG_DEBUG, QString(
"NIT onid:%1 add ts(%2):%3 %4")
828 .arg(netid).arg(i).arg(tsid).arg(tuning.
toString()));
833 LOG(VB_CHANSCAN, LOG_DEBUG, QString(
"NIT onid:%1 cannot add ts(%2):%3 fr:%4")
834 .arg(netid).arg(i).arg(tsid).arg(frequency));
865 bool transport_tune_complete =
true;
871 QMap<uint,bool> tsid_checked;
872 for (
auto & pat : pattmp)
874 uint tsid = pat->TransportStreamID();
875 if (tsid_checked[tsid])
877 tsid_checked[tsid] =
true;
892 transport_tune_complete =
false;
895 transport_tune_complete &= !pattmp.empty();
928 tsid_checked.clear();
929 for (
auto & sdt : sdttmp)
931 uint tsid = sdt->TSID();
932 if (tsid_checked[tsid])
934 tsid_checked[tsid] =
true;
951 if (transport_tune_complete)
957 transport_tune_complete =
false;
963 transport_tune_complete &=
975 if (transport_tune_complete)
978 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
979 QString(
"\nTable status after transport tune complete:") +
985 QString(
"\nsd->HasCachedAllSDT(%1): %2").arg(tsid,5).arg(sd->
HasCachedAllSDT(tsid)) +
987 QString(
"\nsd->HasCachedMGT(): %1").arg(sd->
HasCachedMGT()) +
999 if (!wait_until_complete)
1000 transport_tune_complete =
true;
1001 if (transport_tune_complete)
1003 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1004 QString(
"transport_tune_complete: wait_until_complete %1").arg(wait_until_complete));
1022 QString msg_tr1 = QObject::tr(
"Program %1").arg(it.key());
1023 QString msg_tr2 = QObject::tr(
"Unknown decryption status");
1025 msg_tr2 = QObject::tr(
"Encrypted");
1027 msg_tr2 = QObject::tr(
"Decrypted");
1028 QString msg_tr =QString(
"%1 %2").arg(msg_tr1, msg_tr2);
1032 QString msg = QString(
"Program %1").arg(it.key());
1034 msg = msg +
" -- Encrypted";
1036 msg = msg +
" -- Decrypted";
1038 msg = msg +
" -- Unknown decryption status";
1040 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
1058 if (transport_tune_complete)
1064 QString chan_tr = QObject::tr(
"%1 -- Timed out").arg(cchan_tr);
1065 QString chan = QString(
"%1 -- Timed out").arg(cchan);
1066 QString msg_tr =
"";
1096 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1097 QString(
"Adding %1 offset:%2 ss:%3")
1101 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
1102 QString(
"%1(%2) m_inputName: %3 ").arg(__FUNCTION__).arg(__LINE__).arg(
m_inputName) +
1119 msg_tr = (cchan_cnt) ?
1120 QObject::tr(
"%1 possible channels").arg(cchan_cnt) :
1121 QObject::tr(
"no channels");
1122 msg_tr = QString(
"%1, %2").arg(chan_tr, msg_tr);
1124 QString(
"%1 possible channels").arg(cchan_cnt) :
1125 QString(
"no channels");
1126 msg = QString(
"%1, %2").arg(chan_tr, msg);
1129 m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
1132 msg_tr = QObject::tr(
"%1, no signal").arg(chan_tr);
1133 msg = QString(
"%1, no signal").arg(chan);
1137 msg_tr = QObject::tr(
"%1 -- Found %2 probable channels")
1138 .arg(cchan_tr).arg(cchan_cnt);
1140 msg = QString(
"%1 -- Found %2 probable channels")
1141 .arg(cchan).arg(cchan_cnt);
1145 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
1174#define PCM_INFO_INIT(SISTD) \
1175 ChannelInsertInfo &info = pnum_to_dbchan[pnum]; \
1176 info.m_dbMplexId = mplexid; info.m_sourceId = m_sourceID; \
1177 info.m_serviceId = pnum; info.m_freqId = freqidStr; \
1178 info.m_siStandard = SISTD;
1186 info.m_siStandard =
"ntsc";
1187 info.m_format =
"ntsc";
1193 if (
info.m_serviceName.isEmpty())
1196 info.m_chanNum.clear();
1213 info.m_inVct =
true;
1218 const QMap<uint64_t, QString> &defAuthorities)
1223 bool force_guide_present = (
1240 QString service_name;
1244 if (callsign.trimmed().isEmpty())
1246 callsign = QString(
"%1-%2-%3")
1252 if (service_name.trimmed().isEmpty())
1253 service_name.clear();
1256 info.m_isDataService =
1263 LOG(VB_CHANSCAN, LOG_INFO,
"ChannelScanSM: " +
1264 QString(
"No ServiceDescriptor for onid %1 tid %2 sid %3")
1268 if (
info.m_callSign.isEmpty())
1269 info.m_callSign = callsign;
1270 if (
info.m_serviceName.isEmpty())
1271 info.m_serviceName = service_name;
1273 info.m_useOnAirGuide =
1276 force_guide_present;
1278 info.m_hidden =
false;
1279 info.m_hiddenInGuide =
false;
1283 info.m_inSdt =
true;
1289 const unsigned char *def_auth =
1297 LOG(VB_CHANSCAN, LOG_DEBUG,
1298 QString(
"ChannelScanSM: Found default authority '%1' in SDT for service onid %2 tid %3 sid %4")
1300 .arg(
info.m_origNetId).arg(
info.m_sdtTsId).arg(
info.m_serviceId));
1308 uint64_t index = (uint64_t)
info.m_origNetId << 32 |
1309 info.m_sdtTsId << 16 |
info.m_serviceId;
1310 if (defAuthorities.contains(index))
1311 info.m_defaultAuthority = defAuthorities[index];
1317 info.m_oldOrigNetId = srdesc->OldOriginalNetworkID();
1318 info.m_oldTsId = srdesc->OldTransportID();
1319 info.m_oldServiceId = srdesc->OldServiceID();
1321 LOG(VB_CHANSCAN, LOG_DEBUG,
"ChannelScanSM: " +
1322 QString(
"Service '%1' onid:%2 tid:%3 sid:%4 ")
1323 .arg(
info.m_serviceName)
1324 .arg(
info.m_origNetId)
1325 .arg(
info.m_sdtTsId)
1326 .arg(
info.m_serviceId) +
1327 QString(
" relocated from onid:%1 tid:%2 sid:%3")
1328 .arg(
info.m_oldOrigNetId)
1329 .arg(
info.m_oldTsId)
1330 .arg(
info.m_oldServiceId));
1338 QString &cur_chan, QString &cur_chan_tr)
const
1343 cur_chan_tr.clear();
1347 uint max_chan_cnt = 0;
1351 for (
const auto &
info : std::as_const(list))
1355 info.m_inSdt ||
info.m_inVct) ? 1 : 0;
1361 cur_chan_tr = QString(
"%1%2")
1362 .arg((*m_current).m_friendlyName, offset_str_tr);
1366 cur_chan = QString(
"%1%2")
1367 .arg((*m_current).m_friendlyName, offset_str);
1369 return max_chan_cnt;
1372QMap<uint,ChannelInsertInfo>
1376 QMap<uint,ChannelInsertInfo> pnum_to_dbchan;
1378 uint mplexid = (*trans_info).m_mplexid;
1379 int freqid = (*trans_info).m_friendlyNum;
1380 QString freqidStr = (freqid) ? QString::number(freqid) : QString(
"");
1381 QString iptv_channel = (*trans_info).m_iptvChannel;
1385 for (
const auto & chan : echan)
1387 uint pnum = chan.m_serviceid;
1389 info.m_serviceName = chan.m_name;
1390 info.m_inChannelsConf =
true;
1394 for (
const auto& pat_list : std::as_const(scan_info->
m_pats))
1396 for (
const auto *pat : pat_list)
1398 bool could_be_opencable =
false;
1399 for (
uint i = 0; i < pat->ProgramCount(); ++i)
1401 if ((pat->ProgramNumber(i) == 0) &&
1404 could_be_opencable =
true;
1408 for (
uint i = 0; i < pat->ProgramCount(); ++i)
1410 uint pnum = pat->ProgramNumber(i);
1414 info.m_patTsId = pat->TransportStreamID();
1415 info.m_couldBeOpencable = could_be_opencable;
1416 info.m_inPat =
true;
1423 for (
const auto *pmt : scan_info->
m_pmts)
1425 uint pnum = pmt->ProgramNumber();
1427 for (
uint i = 0; i < pmt->StreamCount(); ++i)
1429 info.m_couldBeOpencable |=
1434 pmt->ProgramInfo(), pmt->ProgramInfoLength(),
1437 for (
auto & desc : descs)
1444 info.m_couldBeOpencable =
true;
1448 info.m_inPmt =
true;
1452 for (
const auto *cvct : scan_info->
m_cvcts)
1454 for (
uint i = 0; i < cvct->ChannelCount(); ++i)
1456 uint pnum = cvct->ProgramNumber(i);
1463 if ((
info.m_atscMajorChannel & 0x3F0) == 0x3F0)
1465 info.m_chanNum = QString::number(((
info.m_atscMajorChannel & 0x00F) << 10) +
info.m_atscMinorChannel);
1475 for (
const auto *tvct : scan_info->
m_tvcts)
1477 for (
uint i = 0; i < tvct->ChannelCount(); ++i)
1479 uint pnum = tvct->ProgramNumber(i);
1487 QString siStandard = (scan_info->
m_mgt ==
nullptr) ?
"dvb" :
"atsc";
1488 for (
const auto& sdt_list : std::as_const(scan_info->
m_sdts))
1490 for (
const auto *sdt_it : sdt_list)
1492 for (
uint i = 0; i < sdt_it->ServiceCount(); ++i)
1494 uint pnum = sdt_it->ServiceID(i);
1502 QMap<qlonglong, uint> ukChanNums;
1503 QMap<qlonglong, uint> scnChanNums;
1504 QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1505 for (dbchan_it = pnum_to_dbchan.begin();
1506 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1511 for (
const auto *item : scan_info->
m_nits)
1513 for (
uint i = 0; i < item->TransportStreamCount(); ++i)
1516 if ((nit->
TSID(i) ==
info.m_sdtTsId) &&
1520 info.m_inNit =
true;
1535 const unsigned char *desc =
1551 const unsigned char *desc =
1562 ukChanNums[((qlonglong)
info.m_origNetId<<32) |
1571 const unsigned char *desc =
1582 scnChanNums[((qlonglong)
info.m_origNetId<<32) |
1613 QMap<uint,qlonglong> lcn_sid;
1615 for (
const auto *bat : scan_info->
m_bats)
1621 for (
uint t = 0;
t < bat->TransportStreamCount(); ++
t)
1623 uint netid = bat->OriginalNetworkID(
t);
1634 bat->TransportDescriptorsLength(
t));
1637 for (
const auto *item : parsed)
1662 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1666 if (lcn_sid.value(lcn,0) == 0)
1667 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1688 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1692 if (lcn_sid.value(lcn,0) == 0)
1693 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1696 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1697 QString(
"LCN bid:%1 tid:%2 rid:%3 sid:%4 lcn:%5")
1698 .arg(bat->BouquetID()).arg(bat->TSID(
t)).arg(region_id).arg(service_id).arg(lcn));
1710 QMap<qlonglong, uint> sid_lcn;
1711 QMap<uint, qlonglong>::const_iterator r = lcn_sid.constEnd();
1712 while (r != lcn_sid.constBegin())
1715 qlonglong sid = r.value();
1723 for (dbchan_it = pnum_to_dbchan.begin();
1724 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1727 qlonglong key = ((qlonglong)
info.m_origNetId<<32) |
info.m_serviceId;
1728 QMap<qlonglong, uint>::const_iterator it;
1737 it = scnChanNums.constFind(key);
1738 if (it != scnChanNums.constEnd())
1740 info.m_simulcastChannel = *it;
1744 it = ukChanNums.constFind(key);
1745 if (it != ukChanNums.constEnd())
1747 info.m_logicalChannel = *it;
1751 it = sid_lcn.constFind(key);
1752 if (it != sid_lcn.constEnd())
1754 info.m_logicalChannel = *it;
1757 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1758 QString(
"service %1 (0x%2) lcn:%3 scn:%4 callsign '%5'")
1759 .arg(
info.m_serviceId).arg(
info.m_serviceId,4,16,QChar(
'0'))
1760 .arg(
info.m_logicalChannel).arg(
info.m_simulcastChannel).arg(
info.m_callSign));
1764 for (dbchan_it = pnum_to_dbchan.begin();
1765 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1769 if (!
info.m_chanNum.isEmpty())
1772 if ((
info.m_siStandard ==
"mpeg") ||
1773 (
info.m_siStandard ==
"scte") ||
1774 (
info.m_siStandard ==
"opencable"))
1776 if (
info.m_freqId.isEmpty())
1778 info.m_chanNum = QString(
"%1-%2")
1779 .arg(
info.m_sourceId)
1780 .arg(
info.m_serviceId);
1784 info.m_chanNum = QString(
"%1-%2")
1786 .arg(
info.m_serviceId);
1792 for (dbchan_it = pnum_to_dbchan.begin();
1793 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1797 if (!
info.m_chanNum.isEmpty())
1800 if (!iptv_channel.isEmpty())
1802 info.m_chanNum = iptv_channel;
1803 if (
info.m_serviceId)
1804 info.m_chanNum +=
"-" + QString::number(
info.m_serviceId);
1809 for (dbchan_it = pnum_to_dbchan.begin();
1810 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1812 uint pnum = dbchan_it.key();
1817 return pnum_to_dbchan;
1831 QMap<uint,ChannelInsertInfo> pnum_to_dbchan =
1840 QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1841 for (dbchan_it = pnum_to_dbchan.begin();
1842 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1856 for (
auto & channel : pnum_to_dbchan)
1858 if (channel.m_inPat && channel.m_inPmt)
1867 if (
info.m_serviceId == 0)
1869 dbchan_it = pnum_to_dbchan.begin();
1876 info.m_chanNum = QString(
"%1").arg(
info.m_serviceId);
1877 info.m_logicalChannel =
info.m_serviceId;
1881 info.m_callSign = QString(
"MPTS_%1")
1884 else if (
info.m_siStandard ==
"mpeg" ||
1885 info.m_siStandard ==
"scte" ||
1886 info.m_siStandard ==
"opencable")
1888 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_freqId);
1890 else if (
info.m_atscMajorChannel > 0)
1892 if (
info.m_atscMajorChannel < 0x3F0)
1894 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_atscMajorChannel);
1898 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_freqId);
1901 else if (
info.m_serviceId > 0)
1903 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_serviceId);
1905 else if (!
info.m_chanNum.isEmpty())
1907 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_chanNum);
1911 info.m_callSign =
"MPTS_UNKNOWN";
1914 info.m_serviceName =
info.m_callSign;
1915 info.m_atscMinorChannel = 0;
1916 info.m_format =
"MPTS";
1917 info.m_useOnAirGuide =
false;
1918 info.m_isEncrypted =
false;
1922 list.push_back(item);
2013 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"run -- begin");
2020 std::this_thread::sleep_for(10ms);
2023 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"run -- end");
2048 bool was_moving =
false;
2049 bool is_moving =
false;
2051 if (was_moving && !is_moving)
2083 if (
m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
2111 QMutexLocker locker(&
m_lock);
2164 QString name = QString(
"TransportID %1").arg(it.key() & 0xffff);
2210 return channel->
Tune(tuning,
true);
2229 return channel->
Tune(tuning);
2234 QString offset_str = (transport.
offset()) ?
2235 QObject::tr(
" offset %2").arg(transport.
offset()) :
"";
2236 QString cur_chan = QString(
"%1%2")
2237 .arg((*m_current).m_friendlyName, offset_str);
2238 QString tune_msg_str =
2239 QObject::tr(
"ScanTransport Tuning to %1 mplexid(%2)")
2240 .arg(cur_chan).arg((*m_current).m_mplexid);
2244 if (transport.
offset() &&
2258 LOG(VB_CHANSCAN, LOG_INFO,
LOC + tune_msg_str);
2260 if (!
Tune(transport))
2263 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
2264 QString(
"Failed to tune %1 mplexid(%2) at offset %3")
2266 .arg(transport.
offset()));
2292 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"StopScanner");
2315 const QString &modulation,
2316 const QString &country,
2317 const QString &table_start,
2318 const QString &table_end)
2320 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
2321 QString(
"%1:%2 ").arg(__FUNCTION__).arg(__LINE__) +
2322 QString(
"SourceID:%1 ").arg(
SourceID) +
2323 QString(
"std:%1 ").arg(
std) +
2324 QString(
"modulation:%1 ").arg(modulation) +
2325 QString(
"country:%1 ").arg(country) +
2326 QString(
"table_start:%1 ").arg(table_start) +
2327 QString(
"table_end:%1 ").arg(table_end));
2341 QString msg = QString(
"No freq table for (%1, %2, %3) found")
2342 .arg(
std, modulation, country);
2345 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
2346 QString(
"Looked up freq table (%1, %2, %3) w/%4 entries")
2347 .arg(
std, modulation, country, QString::number(tables.size())));
2349 QString start = table_start;
2350 const QString& end = table_end;
2352 for (
auto it = tables.begin(); it != tables.end(); ++it)
2360 name = strNameFormat;
2361 if (strNameFormat.indexOf(
"%") >= 0)
2362 name = strNameFormat.arg(name_num);
2364 if (start.isEmpty() || name == start)
2372 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanTransports " +
2379 if (!end.isEmpty() && name == end)
2382 if (!end.isEmpty() && name == end)
2386 while (!tables.empty())
2388 delete tables.back();
2405 const QString &cardtype,
2412 tunertype.
Parse(cardtype);
2414 auto it = channels.cbegin();
2415 for (
uint i = 0; it != channels.cend(); ++it, ++i)
2424 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanForChannels " + item.
toString());
2429 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ScanForChannels() no transports");
2449 fbox_chan_map_t::const_iterator Ichan = iptv_channels.begin();
2450 for (
uint idx = 0; Ichan != iptv_channels.end(); ++Ichan, ++idx)
2453 Ichan.value().m_tuning, Ichan.key(),
2458 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanIPTVChannels " + item.
toString());
2463 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ScanIPTVChannels() no transports");
2483 int sourceid,
const QMap<QString,QString> &startChan)
2485 auto iter = startChan.find(
"type");
2486 if (iter == startChan.end())
2488 iter = startChan.find(
"std");
2489 if (iter == startChan.end())
2492 QString si_std = ((*iter).toLower() !=
"atsc") ?
"dvb" :
"atsc";
2504 ok =
type.Parse(startChan[
"type"]);
2510 startChan[
"frequency"], startChan[
"inversion"],
2511 startChan[
"symbolrate"], startChan[
"fec"],
2512 startChan[
"polarity"],
2513 startChan[
"coderate_hp"], startChan[
"coderate_lp"],
2514 startChan[
"constellation"], startChan[
"trans_mode"],
2515 startChan[
"guard_interval"], startChan[
"hierarchy"],
2516 startChan[
"modulation"], startChan[
"bandwidth"],
2517 startChan[
"mod_sys"], startChan[
"rolloff"]);
2524 sourceid, QObject::tr(
"Frequency %1").arg(startChan[
"frequency"]),
2548 "SELECT sourceid, sistandard, transportid, frequency, modulation, mod_sys "
2549 "FROM dtv_multiplex "
2550 "WHERE mplexid = :MPLEXID");
2560 LOG(VB_GENERAL, LOG_ERR,
LOC +
"AddToList() " +
2561 QString(
"Failed to locate mplexid(%1) in DB").arg(mplexid));
2565 uint sourceid = query.
value(0).toUInt();
2566 QString sistandard = query.
value(1).toString();
2568 uint frequency = query.
value(3).toUInt();
2569 QString modulation = query.
value(4).toString();
2570 QString mod_sys = query.
value(5).toString();
2572 delsys.
Parse(mod_sys);
2574 QString fn = (tsid) ? QString(
"Transport ID %1").arg(tsid) :
2575 QString(
"Multiplex #%1").arg(mplexid);
2577 if (modulation ==
"8vsb")
2579 QString chan = QString(
"%1 Hz").arg(frequency);
2580 int findFrequency = (query.
value(3).toInt() / 1000) - 1750;
2583 if ((list.freq <= findFrequency + 200) &&
2584 (list.freq >= findFrequency - 200))
2586 chan = QString(
"%1").arg(list.name);
2589 fn = QObject::tr(
"ATSC Channel %1").arg(chan);
2597 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
2598 QString(
"tunertype:%1 %2 sourceid:%3 sistandard:%4 fn:'%5' mplexid:%6")
2599 .arg(tt.
toInt()).arg(tt.
toString()).arg(sourceid).arg(sistandard, fn).arg(mplexid));
2603 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Adding " + fn);
2608 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Not adding incomplete transport " + fn);
2658 uint mpeg_program_num,
2659 QString &service_name,
2661 QString &common_status_info)
2663 if (channels.empty())
2667 for (
const auto & channel : channels)
2669 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
2670 QString(
"comparing %1 %2 against %3 %4")
2671 .arg(channel.m_serviceid).arg(channel.m_name)
2672 .arg(mpeg_program_num).arg(common_status_info));
2674 if (channel.m_serviceid == mpeg_program_num)
2677 if (!channel.m_name.isEmpty())
2679 service_name = channel.m_name;
2680 callsign = channel.m_name;
2687 common_status_info += QString(
" %1 %2")
2688 .arg(QObject::tr(
"as"), service_name);
2693 QObject::tr(
"Skipping %1, not in imported channel map")
2694 .arg(common_status_info));
std::vector< const TerrestrialVirtualChannelTable * > tvct_vec_t
std::vector< const CableVirtualChannelTable * > cvct_vec_t
static void update_info(ChannelInsertInfo &info, const VirtualChannelTable *vct, uint i)
#define PCM_INFO_INIT(SISTD)
static const QString kATSCChannelFormat
static constexpr qint64 kDecryptionTimeout
static const uint kRegionUndefined
std::vector< const ProgramMapTable * > pmt_vec_t
QPair< transport_scan_items_it_t, ScannedChannelInfo * > ChannelListItem
cvct_vec_t GetCachedCVCTs(bool current=true) const
const MasterGuideTable * GetCachedMGT(bool current=true) const
bool HasCachedAllTVCTs(bool current=true) const
bool HasCachedAnyVCTs(bool current=true) const
tvct_vec_t GetCachedTVCTs(bool current=true) const
bool HasCachedMGT(bool current=true) const
bool HasCachedAllCVCTs(bool current=true) const
Tells what channels can be found on each transponder for one bouquet (a bunch of channels from one pr...
uint TransportDescriptorsLength(uint i) const
const unsigned char * TransportDescriptors(uint i) const
for(j=0;j<N;j++) x 6.0+p { descriptor() }
QString toString(void) const override
uint OriginalNetworkID(uint i) const
uint TransportStreamCount(void) const
unsigned long long FrequencyHz(void) const
static QString GetDisplayName(uint inputid)
static DTVTunerType ConvertToTunerType(DTVModulationSystem delsys)
Abstract class providing a generic interface to tuning hardware.
virtual int GetInputID(void) const
Scanning class for cards that support a SignalMonitor class.
bool ScanTransportsStartingOn(int sourceid, const QMap< QString, QString > &startChan)
Generates a list of frequencies to scan and adds it to the scanTransport list, and then sets the scan...
QMutex m_lock
The big lock.
DTVTunerType GuessDTVTunerType(DTVTunerType type) const
void UpdateScanPercentCompleted(void)
void run(void) override
This runs the event loop for ChannelScanSM until 'm_threadExit' is true.
void UpdateScanTransports(uint frequency, const NetworkInformationTable *nit)
QSet< uint32_t > m_tsScanned
std::chrono::milliseconds m_otherTableTimeout
void HandleMGT(const MasterGuideTable *mgt) override
QMap< uint32_t, DTVMultiplex > m_extendTransports
std::chrono::milliseconds m_otherTableTime
DTVTunerType m_scanDTVTunerType
ChannelList m_channelList
Found Channel Info.
DTVChannel * GetDTVChannel(void)
void HandleActiveScan(void)
Handles the TRANSPORT_LIST ChannelScanSM mode.
bool ScanForChannels(uint sourceid, const QString &std, const QString &cardtype, const DTVChannelList &channels)
void HandleEncryptionStatus(uint pnum, bool encrypted) override
transport_scan_items_t m_scanTransports
static const std::chrono::milliseconds kMPEGTableTimeout
No logic here, lets just wait at least 15 seconds.
bool ScanTransport(uint mplexid, bool follow_nit)
void HandleSDTo(uint tsid, const ServiceDescriptionTable *sdt) override
static const std::chrono::milliseconds kATSCTableTimeout
No logic here, lets just wait at least 10 seconds.
void SetAnalog(bool is_analog)
void HandleVCT(uint tsid, const VirtualChannelTable *vct) override
void HandleNIT(const NetworkInformationTable *nit) override
std::chrono::milliseconds m_signalTimeout
static QString loc(const ChannelScanSM *siscan)
void HandleSDT(uint tsid, const ServiceDescriptionTable *sdt) override
uint GetCurrentTransportInfo(QString &chan, QString &chan_tr) const
DVBSignalMonitor * GetDVBSignalMonitor(void)
QMap< uint64_t, QString > m_defAuthorities
DTVSignalMonitor * GetDTVSignalMonitor(void)
MThread * m_scannerThread
static const std::chrono::milliseconds kDVBTableTimeout
SDT's should be sent every 2 seconds and NIT's every 10 seconds, so lets wait at least 30 seconds,...
QMap< uint, bool > m_currentEncryptionStatusChecked
SignalMonitor * GetSignalMonitor(void)
bool UpdateChannelInfo(bool wait_until_complete)
bool ScanTransports(int SourceID, const QString &std, const QString &mod, const QString &country, const QString &table_start=QString(), const QString &table_end=QString())
Generates a list of frequencies to scan and adds it to the scanTransport list, and then sets the scan...
bool Tune(transport_scan_items_it_t transport)
AnalogSignalHandler * m_analogSignalHandler
V4LChannel * GetV4LChannel(void)
chan_info_map_t GetChannelList(transport_scan_items_it_t trans_info, ScannedChannelInfo *scan_info) const
void HandlePMT(uint program_num, const ProgramMapTable *pmt) override
void HandlePAT(const ProgramAssociationTable *pat) override
HDHRChannel * GetHDHRChannel(void)
~ChannelScanSM() override
bool m_currentTestingDecryption
ChannelScanSM(ScanMonitor *scan_monitor, const QString &cardtype, ChannelBase *channel, int sourceID, std::chrono::milliseconds signal_timeout, std::chrono::milliseconds channel_timeout, QString inputname, bool test_decryption)
static void LogLines(const QString &string)
void HandleCAT(const ConditionalAccessTable *cat) override
QMap< uint, uint > m_currentEncryptionStatus
bool ScanExistingTransports(uint sourceid, bool follow_nit)
If we are not already scanning a frequency table, this creates a new frequency table from database an...
ScannedChannelInfo * m_currentInfo
transport_scan_items_it_t m_current
std::chrono::milliseconds m_channelTimeout
SignalMonitor * m_signalMonitor
void StopScanner(void)
Stops the ChannelScanSM event loop and the signal monitor, blocking until both exit.
bool ScanCurrentTransport(const QString &sistandard)
void HandleBAT(const BouquetAssociationTable *bat) override
void StartScanner(void)
Starts the ChannelScanSM event loop.
transport_scan_items_it_t m_nextIt
DVBChannel * GetDVBChannel(void)
ScanMonitor * m_scanMonitor
bool CheckImportedList(const DTVChannelInfoList &channels, uint mpeg_program_num, QString &service_name, QString &callsign, QString &common_status_info)
If we are scanning a dvb-utils import verify channel is in list.
bool TestNextProgramEncryption(void)
bool AddToList(uint mplexid)
bool ScanIPTVChannels(uint sourceid, const fbox_chan_map_t &iptv_channels)
volatile bool m_threadExit
static int CreateChanID(uint sourceid, const QString &chan_num)
Creates a unique channel ID for database use.
static bool CreateChannel(uint db_mplexid, uint db_sourceid, uint new_channel_id, const QString &callsign, const QString &service_name, const QString &chan_num, uint service_id, uint atsc_major_channel, uint atsc_minor_channel, bool use_on_air_guide, ChannelVisibleType visible, const QString &freqid, const QString &icon=QString(), QString format="Default", const QString &xmltvid=QString(), const QString &default_authority=QString(), uint service_type=0, int recpriority=0, int tmOffset=0, int commMethod=-1)
static QString GetUnknownCallsign(void)
static uint FindChannel(uint sourceid, const QString &freqid)
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Class providing a generic interface to digital tuning hardware.
virtual bool Tune(const DTVMultiplex &tuning)=0
This performs the actual frequency tuning and in some cases input switching.
virtual std::vector< DTVTunerType > GetTunerTypes(void) const
Returns a vector of supported tuning types.
virtual bool TuneMultiplex(uint mplexid, const QString &inputname)
To be used by the channel scanner and possibly the EIT scanner.
@ kModulationSystem_DVBT2
@ kModulationSystem_DVBC_ANNEX_A
@ kModulationSystem_UNDEFINED
bool Parse(const QString &_value)
bool FillFromDeliverySystemDesc(DTVTunerType type, const MPEGDescriptor &desc)
bool ParseTuningParams(DTVTunerType type, const QString &frequency, const QString &inversion, const QString &symbolrate, const QString &fec, const QString &polarity, const QString &hp_code_rate, const QString &lp_code_rate, const QString &ofdm_modulation, const QString &trans_mode, const QString &guard_interval, const QString &hierarchy, const QString &modulation, const QString &bandwidth, const QString &mod_sys, const QString &rolloff)
IPTVTuningData m_iptvTuning
DTVModulationSystem m_modSys
virtual bool FillFromDB(DTVTunerType type, uint mplexid)
This class is intended to detect the presence of needed tables.
void SetDVBService(uint network_id, uint transport_id, int service_id)
uint GetNetworkID(void) const
void AddFlags(uint64_t _flags) override
uint GetTransportID(void) const
void SetChannel(int major, int minor)
MPEGStreamData * GetStreamData()
Returns the MPEG stream data if it exists.
ScanStreamData * GetScanStreamData()
Returns the scan stream data if it exists.
DVBStreamData * GetDVBStreamData()
Returns the DVB stream data if it exists.
virtual void SetStreamData(MPEGStreamData *data)
Sets the MPEG stream data for DTVSignalMonitor to use, and connects the table signals to the monitor.
bool Parse(const QString &_value)
static const int kTunerTypeASI
static const int kTunerTypeDVBS2
static const int kTunerTypeDVBT
static const int kTunerTypeUnknown
static const int kTunerTypeDVBC
static const int kTunerTypeDVBS1
static const int kTunerTypeDVBT2
static const int kTunerTypeATSC
Provides interface to the tuning hardware when using DVB drivers.
const DiSEqCDevRotor * GetRotor(void) const
Returns rotor object if it exists, nullptr otherwise.
void SetPMT(const ProgramMapTable *pmt)
Tells the Conditional Access Module which streams we wish to decode.
DVB Logical Channel Descriptor.
uint ChannelCount(void) const
uint ChannelNumber(uint i) const
uint ServiceID(uint i) const
void SetRotorTarget(float target) override
Sets rotor target pos from 0.0 to 1.0.
void GetRotorStatus(bool &was_moving, bool &is_moving) override
DVB HD Simulcast Logical Channel Descriptor.
uint ChannelNumber(uint i) const
uint ServiceID(uint i) const
uint ChannelCount(void) const
sdt_vec_t GetCachedSDTSections(uint tsid, bool current=true) const
bool HasCachedAnySDTs(bool current=true) const
sdt_vec_t GetCachedSDTs(bool current=true) const
bool HasCachedAnyBATs(bool current=true) const
bool HasCachedAllBATs(bool current=true) const
bool HasCachedAnyNIT(bool current=true) const
bat_vec_t GetCachedBATs(bool current=true) const
bool HasCachedAllSDT(uint tsid, bool current=true) const
void ReturnCachedSDTTables(sdt_vec_t &sdts) const
nit_const_ptr_t GetCachedNIT(uint section_num, bool current=true) const
bool HasCachedAllNIT(bool current=true) const
QString DefaultAuthority(void) const
@ satellite_delivery_system
@ terrestrial_delivery_system
@ s2_satellite_delivery_system
Freesat Logical Channel Number descriptor.
uint LCNCount(size_t i) const
uint ServiceCount(void) const
uint ServiceID(size_t i) const
uint LogicalChannelNumber(size_t i, size_t j) const
uint RegionID(size_t i, size_t j) const
uint64_t m_frequencyStart
IPTVProtocol GetProtocol(void) const
static const unsigned char * FindExtension(const desc_list_t &parsed, uint desc_tag)
static desc_list_t Parse(const unsigned char *data, uint len)
uint DescriptorTag(void) const
static desc_list_t ParseOnlyInclude(const unsigned char *data, uint len, int excluded_descid)
uint DescriptorTagExtension(void) const
static const unsigned char * Find(const desc_list_t &parsed, uint desc_tag)
pmt_vec_t GetCachedPMTs(void) const
void TestDecryption(const ProgramMapTable *pmt)
virtual void ReturnCachedPATTables(pat_vec_t &pats) const
bool HasCachedAnyPMTs(void) const
bool HasCachedAnyPAT(uint tsid) const
bool HasCachedAllPMTs(void) const
pat_vec_t GetCachedPATs(uint tsid) const
bool HasCachedAllPAT(uint tsid) const
virtual void ReturnCachedPMTTables(pmt_vec_t &pmts) const
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
void ResetDecryptionMonitoringState(void)
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
This is a wrapper around QThread that does several additional things.
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
This table tells the decoder on which PIDs to find other tables, and their sizes and each table's cur...
QString toString(void) const override
static void DBError(const QString &where, const MSqlQuery &query)
uint LastSection(void) const
uint32_t PrivateDataSpecifier(void) const
@ dvb_logical_channel_descriptor
@ dvb_simulcast_channel_descriptor
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
QString toString(void) const override
uint ProgramCount(void) const
uint ProgramPID(uint i) const
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
bool IsEncrypted(const QString &sistandard) const
Returns true iff PMT contains CA descriptor for a vid/aud stream.
QString toString(void) const override
uint ProgramNumber(void) const
QString FormatIdentifierString(void) const
uint64_t FrequencykHz(void) const
ChannelInsertInfoList m_channels
void ScanPercentComplete(int pct)
void ScanAppendTextToLog(const QString &status)
void ScanUpdateStatusTitleText(const QString &status)
void ScanUpdateStatusText(const QString &status)
void Reset(void) override
void SetFreesatAdditionalSI(bool freesat_si)
QMap< uint, uint > m_programEncryptionStatus
ScannedChannelInfo()=default
const MasterGuideTable * m_mgt
This table tells the decoder on which PIDs to find A/V data.
uint TSID() const
transport_stream_id 16 3.0 0x0000
QString toString(void) const override
const unsigned char * ServiceDescriptors(uint i) const
for (j=0;j<N;j++) x 5.0+p { descriptor() }
bool HasEITPresentFollowing(uint i) const
bool HasEITSchedule(uint i) const
ServiceDescriptor * GetServiceDescriptor(uint i) const
uint ServiceID(uint i) const
service_id 16 0.0+p
uint ServiceCount() const
Number of services.
uint ServiceDescriptorsLength(uint i) const
desc_loop_length 12 3.4+p
uint OriginalNetworkID() const
original_network_id 16 8.0
bool IsEncrypted(uint i) const
free_CA_mode 1 3.3+p
ServiceRelocatedDescriptor * GetServiceRelocatedDescriptor(uint i) const
QString ServiceShortName(void) const
uint ServiceType(void) const
QString ServiceName(void) const
bool IsDigitalAudio(void) const
uint ServiceID(uint i) const
uint ServiceCount(void) const
Signal monitoring base class.
static const uint64_t kDTVSigMon_WaitForVCT
void RemoveListener(SignalMonitorListener *listener)
void AddListener(SignalMonitorListener *listener)
static const uint64_t kDTVSigMon_WaitForNIT
static const uint64_t kDVBSigMon_WaitForPos
Wait for rotor to complete turning the antenna.
static const uint64_t kDTVSigMon_WaitForSDT
virtual void Stop()
Stop signal monitoring thread.
int GetSignalStrength(void)
static const uint64_t kDTVSigMon_WaitForMGT
bool HasSignalLock(void) const
Returns true iff scriptStatus.IsGood() and signalLock.IsGood() return true.
virtual void Start()
Start signal monitoring thread.
Sky Logical Channel Number descriptor.
uint RegionID(void) const
uint ServiceCount(void) const
uint LogicalChannelNumber(size_t i) const
uint ServiceID(size_t i) const
static std::vector< uint > GetMplexIDs(uint sourceid)
@ OpenCableVideo
Always MPEG-2??
uint64_t FrequencyHz(void) const
Class used for doing a list of frequencies / transports.
uint64_t freq_offset(uint i) const
IPTVTuningData m_iptvTuning
Implements tuning for TV cards using the V4L driver API, both versions 1 and 2.
This table contains information about the channels transmitted on this multiplex.
QString ShortChannelName(uint i) const
bool IsHiddenInGuide(uint i) const
bool IsHidden(uint i) const
uint MajorChannel(uint i) const
uint ChannelTransportStreamID(uint i) const
uint TransportStreamID() const
QString toString(void) const override
uint MinorChannel(uint i) const
bool IsAccessControlled(uint i) const
uint ProgramNumber(uint i) const
QString GetExtendedChannelName(uint idx) const
uint ServiceType(uint i) const
uint ModulationMode(uint i) const
uint ChannelCount() const
transport_scan_items_it_t nextTransport() const
std::list< TransportScanItem >::iterator iter()
std::vector< DTVChannelInfo > DTVChannelInfoList
std::vector< DTVTransport > DTVChannelList
std::vector< ScanDTVTransport > ScanDTVTransportList
QMap< uint, sdt_vec_t > sdt_map_t
std::vector< const ServiceDescriptionTable * > sdt_vec_t
std::vector< const NetworkInformationTable * > nit_vec_t
std::vector< const BouquetAssociationTable * > bat_vec_t
static const std::array< const uint32_t, 4 > freq
const CHANLISTS_vec gChanLists
bool teardown_frequency_tables(void)
freq_table_list_t get_matching_freq_tables(const QString &format, const QString &modulation, const QString &country)
std::vector< const FrequencyTable * > freq_table_list_t
QMap< QString, IPTVChannelInfo > fbox_chan_map_t
std::vector< const unsigned char * > desc_list_t
QMap< uint, pat_vec_t > pat_map_t
std::vector< const ProgramAssociationTable * > pat_vec_t
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
VERBOSE_PREAMBLE Most true