37#include <QMutexLocker>
44#include "libmythbase/mythconfig.h"
86 return "ChannelScanSM(u)";
89#define LOC (ChannelScanSM::loc(this) + ": ")
150 int sourceID, std::chrono::milliseconds signal_timeout,
151 std::chrono::milliseconds channel_timeout, QString inputname,
152 bool test_decryption)
154 m_scanMonitor(scan_monitor),
156 m_signalMonitor(
SignalMonitor::Init(cardtype, m_channel->GetInputID(),
158 m_sourceID(sourceID),
159 m_signalTimeout(signal_timeout),
160 m_channelTimeout(channel_timeout),
161 m_inputName(std::move(inputname)),
162 m_testDecryption(test_decryption),
173 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Connecting up DTVSignalMonitor");
178 "SELECT dvb_nit_id, bouquet_id, region_id, lcnoffset "
180 "WHERE videosource.sourceid = :SOURCEID");
186 else if (query.
next())
188 int nitid = query.
value(0).toInt();
189 data->SetRealNetworkID(nitid);
190 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
191 QString(
"Setting NIT-ID to %1").arg(nitid));
196 m_nitId = nitid > 0 ? nitid : 0;
199 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
200 QString(
"Freesat/Sky bouquet_id:%1 region_id:%2")
211 if (dvbchannel && dvbchannel->GetRotor())
215 data->AddMPEGListener(
this);
216 data->AddATSCMainListener(
this);
217 data->AddDVBMainListener(
this);
218 data->AddDVBOtherListener(
this);
225 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ChannelScanSM Stopped");
261 QMutexLocker locker(&
m_lock);
263 QString cur_chan = (*m_current).m_friendlyName;
264 QStringList list = cur_chan.split(
" ", Qt::SkipEmptyParts);
265 QString freqid = (list.size() >= 2) ? list[1] : cur_chan;
267 QString msg = QObject::tr(
"Updated Channel %1").arg(cur_chan);
273 QString callsign = QString(
"%1-%2")
291 QObject::tr(
"Added Channel %1").arg(cur_chan) :
292 QObject::tr(
"Failed to add channel %1").arg(cur_chan);
332 if (multiplexes.empty())
334 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
"Unable to find any transports for " +
335 QString(
"sourceid %1").arg(sourceid));
340 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
341 QString(
"Found %1 transports for ").arg(multiplexes.size()) +
342 QString(
"sourceid %1").arg(sourceid));
344 for (
uint multiplex : multiplexes)
357 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
358 "Unable to find add any transports for " +
359 QString(
"sourceid %1").arg(sourceid));
371 QStringList lines =
string.split(
'\n');
372 for (
const QString& line : std::as_const(lines))
373 LOG(VB_CHANSCAN, LOG_DEBUG, line);
379 QMutexLocker locker(&
m_lock);
381 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
382 QString(
"Got a Program Association Table for %1")
383 .arg((*m_current).m_friendlyName));
388 if (
nullptr == monitor)
399 QMutexLocker locker(&
m_lock);
401 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
402 QString(
"Got a Conditional Access Table for %1")
403 .arg((*m_current).m_friendlyName));
409 QMutexLocker locker(&
m_lock);
411 LOG(VB_CHANSCAN, LOG_INFO,
LOC + QString(
"Got a Program Map Table for %1 program %2 (0x%3)")
425 QMutexLocker locker(&
m_lock);
427 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
428 QString(
"Got a Virtual Channel Table for %1")
429 .arg((*m_current).m_friendlyName));
445 QMutexLocker locker(&
m_lock);
447 LOG(VB_CHANSCAN, LOG_INFO,
LOC + QString(
"Got the Master Guide for %1")
448 .arg((*m_current).m_friendlyName));
463 QMutexLocker locker(&
m_lock);
465 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
466 QString(
"Got a Service Description Table for %1 section %2/%3")
467 .arg((*m_current).m_friendlyName)
477 if (
nullptr != monitor)
480 if (
nullptr != stream)
489 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
490 QString(
"SDT has OriginalNetworkID %1, look for "
500 if (
nullptr != monitor)
503 SetVersionSDT(sdt->
TSID(), -1, 0);
523 QMutexLocker locker(&
m_lock);
525 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
526 QString(
"Got a Network Information Table id %1 for %2 section %3/%4")
527 .arg(nit->
NetworkID()).arg((*m_current).m_friendlyName)
536 QMutexLocker locker(&
m_lock);
538 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
539 QString(
"Got a Bouquet Association Table id %1 for %2 section %3/%4")
540 .arg(bat->
BouquetID()).arg((*m_current).m_friendlyName)
554 const unsigned char *def_auth =
556 const unsigned char *serv_list =
559 if (def_auth && serv_list)
570 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
571 QString(
"Found default authority '%1' in BAT for service nid %2 tid %3 sid %4")
573 .arg(netid).arg(tsid).arg(services.
ServiceID(j)));
574 uint64_t index = ((uint64_t)netid << 32) | (tsid << 16) |
586 QMutexLocker locker(&
m_lock);
588 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
589 QString(
"Got a Service Description Table (other) for Transport ID %1 section %2/%3")
604 const unsigned char *def_auth =
612 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
613 QString(
"Found default authority '%1' in SDTo for service nid %2 tid %3 sid %4")
615 .arg(netid).arg(tsid).arg(serviceId));
625 QMutexLocker locker(&
m_lock);
639 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't monitor decryption -- no pmts");
649 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"%1/%2 checked")
650 .arg(currentEncryptionStatusChecked.size())
651 .arg(currentEncryptionStatus.size()));
688 QObject::tr(
"Program %1 Testing Decryption")
691 QString(
"%1 -- Testing decryption of program %2")
692 .arg(cur_chan).arg(pnum);
695 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
703 if (
nullptr != monitor)
714 LOG(VB_GENERAL, LOG_INFO,
LOC +
715 QString(
"Can't monitor decryption of program %1 -- no pmt")
736 for (
auto & tt : tts)
750 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC + QString(
"%1 NIT nid:%2 fr:%3 section:%4/%5 ts count:%6 ")
756 uint32_t tsid = nit->
TSID(i);
758 uint32_t
id = netid << 16 | tsid;
767 for (
const auto *
const item : list)
769 uint64_t frequency = 0;
828 LOG(VB_CHANSCAN, LOG_DEBUG, QString(
"NIT onid:%1 add ts(%2):%3 %4")
829 .arg(netid).arg(i).arg(tsid).arg(tuning.
toString()));
834 LOG(VB_CHANSCAN, LOG_DEBUG, QString(
"NIT onid:%1 cannot add ts(%2):%3 fr:%4")
835 .arg(netid).arg(i).arg(tsid).arg(frequency));
866 bool transport_tune_complete =
true;
872 QMap<uint,bool> tsid_checked;
873 for (
auto & pat : pattmp)
875 uint tsid = pat->TransportStreamID();
876 if (tsid_checked[tsid])
878 tsid_checked[tsid] =
true;
893 transport_tune_complete =
false;
896 transport_tune_complete &= !pattmp.empty();
929 tsid_checked.clear();
930 for (
auto & sdt : sdttmp)
932 uint tsid = sdt->TSID();
933 if (tsid_checked[tsid])
935 tsid_checked[tsid] =
true;
952 if (transport_tune_complete)
958 transport_tune_complete =
false;
964 transport_tune_complete &=
976 if (transport_tune_complete)
979 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
980 QString(
"\nTable status after transport tune complete:") +
986 QString(
"\nsd->HasCachedAllSDT(%1): %2").arg(tsid,5).arg(sd->
HasCachedAllSDT(tsid)) +
988 QString(
"\nsd->HasCachedMGT(): %1").arg(sd->
HasCachedMGT()) +
1000 if (!wait_until_complete)
1001 transport_tune_complete =
true;
1002 if (transport_tune_complete)
1004 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1005 QString(
"transport_tune_complete: wait_until_complete %1").arg(wait_until_complete));
1023 QString msg_tr1 = QObject::tr(
"Program %1").arg(it.key());
1024 QString msg_tr2 = QObject::tr(
"Unknown decryption status");
1026 msg_tr2 = QObject::tr(
"Encrypted");
1028 msg_tr2 = QObject::tr(
"Decrypted");
1029 QString msg_tr =QString(
"%1 %2").arg(msg_tr1, msg_tr2);
1033 QString msg = QString(
"Program %1").arg(it.key());
1035 msg = msg +
" -- Encrypted";
1037 msg = msg +
" -- Decrypted";
1039 msg = msg +
" -- Unknown decryption status";
1041 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
1059 if (transport_tune_complete)
1065 QString chan_tr = QObject::tr(
"%1 -- Timed out").arg(cchan_tr);
1066 QString chan = QString(
"%1 -- Timed out").arg(cchan);
1067 QString msg_tr =
"";
1097 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1098 QString(
"Adding %1 offset:%2 ss:%3")
1102 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
1103 QString(
"%1(%2) m_inputName: %3 ").arg(__FUNCTION__).arg(__LINE__).arg(
m_inputName) +
1120 msg_tr = cchan_cnt ?
1121 QObject::tr(
"%1 possible channels").arg(cchan_cnt) :
1122 QObject::tr(
"no channels");
1123 msg_tr = QString(
"%1, %2").arg(chan_tr, msg_tr);
1125 QString(
"%1 possible channels").arg(cchan_cnt) :
1126 QString(
"no channels");
1127 msg = QString(
"%1, %2").arg(chan_tr, msg);
1130 m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
1133 msg_tr = QObject::tr(
"%1, no signal").arg(chan_tr);
1134 msg = QString(
"%1, no signal").arg(chan);
1138 msg_tr = QObject::tr(
"%1 -- Found %2 probable channels")
1139 .arg(cchan_tr).arg(cchan_cnt);
1141 msg = QString(
"%1 -- Found %2 probable channels")
1142 .arg(cchan).arg(cchan_cnt);
1146 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
1175#define PCM_INFO_INIT(SISTD) \
1176 ChannelInsertInfo &info = pnum_to_dbchan[pnum]; \
1177 info.m_dbMplexId = mplexid; info.m_sourceId = m_sourceID; \
1178 info.m_serviceId = pnum; info.m_freqId = freqidStr; \
1179 info.m_siStandard = SISTD;
1187 info.m_siStandard =
"ntsc";
1188 info.m_format =
"ntsc";
1194 if (
info.m_serviceName.isEmpty())
1197 info.m_chanNum.clear();
1214 info.m_inVct =
true;
1219 const QMap<uint64_t, QString> &defAuthorities)
1224 bool force_guide_present = (
1241 QString service_name;
1245 if (callsign.trimmed().isEmpty())
1247 callsign = QString(
"%1-%2-%3")
1253 if (service_name.trimmed().isEmpty())
1254 service_name.clear();
1257 info.m_isDataService =
1264 LOG(VB_CHANSCAN, LOG_INFO,
"ChannelScanSM: " +
1265 QString(
"No ServiceDescriptor for onid %1 tid %2 sid %3")
1269 if (
info.m_callSign.isEmpty())
1270 info.m_callSign = callsign;
1271 if (
info.m_serviceName.isEmpty())
1272 info.m_serviceName = service_name;
1274 info.m_useOnAirGuide =
1277 force_guide_present;
1279 info.m_hidden =
false;
1280 info.m_hiddenInGuide =
false;
1284 info.m_inSdt =
true;
1290 const unsigned char *def_auth =
1298 LOG(VB_CHANSCAN, LOG_DEBUG,
1299 QString(
"ChannelScanSM: Found default authority '%1' in SDT for service onid %2 tid %3 sid %4")
1301 .arg(
info.m_origNetId).arg(
info.m_sdtTsId).arg(
info.m_serviceId));
1309 uint64_t index = (uint64_t)
info.m_origNetId << 32 |
1310 info.m_sdtTsId << 16 |
info.m_serviceId;
1311 if (defAuthorities.contains(index))
1312 info.m_defaultAuthority = defAuthorities[index];
1318 info.m_oldOrigNetId = srdesc->OldOriginalNetworkID();
1319 info.m_oldTsId = srdesc->OldTransportID();
1320 info.m_oldServiceId = srdesc->OldServiceID();
1322 LOG(VB_CHANSCAN, LOG_DEBUG,
"ChannelScanSM: " +
1323 QString(
"Service '%1' onid:%2 tid:%3 sid:%4 ")
1324 .arg(
info.m_serviceName)
1325 .arg(
info.m_origNetId)
1326 .arg(
info.m_sdtTsId)
1327 .arg(
info.m_serviceId) +
1328 QString(
" relocated from onid:%1 tid:%2 sid:%3")
1329 .arg(
info.m_oldOrigNetId)
1330 .arg(
info.m_oldTsId)
1331 .arg(
info.m_oldServiceId));
1339 QString &cur_chan, QString &cur_chan_tr)
const
1344 cur_chan_tr.clear();
1348 uint max_chan_cnt = 0;
1352 for (
const auto &
info : std::as_const(list))
1356 info.m_inSdt ||
info.m_inVct) ? 1 : 0;
1362 cur_chan_tr = QString(
"%1%2")
1363 .arg((*m_current).m_friendlyName, offset_str_tr);
1367 cur_chan = QString(
"%1%2")
1368 .arg((*m_current).m_friendlyName, offset_str);
1370 return max_chan_cnt;
1373QMap<uint,ChannelInsertInfo>
1377 QMap<uint,ChannelInsertInfo> pnum_to_dbchan;
1379 uint mplexid = (*trans_info).m_mplexid;
1380 int freqid = (*trans_info).m_friendlyNum;
1381 QString freqidStr = freqid ? QString::number(freqid) : QString(
"");
1382 QString iptv_channel = (*trans_info).m_iptvChannel;
1386 for (
const auto & chan : echan)
1388 uint pnum = chan.m_serviceid;
1390 info.m_serviceName = chan.m_name;
1391 info.m_inChannelsConf =
true;
1395 for (
const auto& pat_list : std::as_const(scan_info->
m_pats))
1397 for (
const auto *pat : pat_list)
1399 bool could_be_opencable =
false;
1400 for (
uint i = 0; i < pat->ProgramCount(); ++i)
1402 if ((pat->ProgramNumber(i) == 0) &&
1405 could_be_opencable =
true;
1409 for (
uint i = 0; i < pat->ProgramCount(); ++i)
1411 uint pnum = pat->ProgramNumber(i);
1415 info.m_patTsId = pat->TransportStreamID();
1416 info.m_couldBeOpencable = could_be_opencable;
1417 info.m_inPat =
true;
1424 for (
const auto *pmt : scan_info->
m_pmts)
1426 uint pnum = pmt->ProgramNumber();
1428 for (
uint i = 0; i < pmt->StreamCount(); ++i)
1430 info.m_couldBeOpencable |=
1435 pmt->ProgramInfo(), pmt->ProgramInfoLength(),
1438 for (
auto & desc : descs)
1445 info.m_couldBeOpencable =
true;
1449 info.m_inPmt =
true;
1453 for (
const auto *cvct : scan_info->
m_cvcts)
1455 for (
uint i = 0; i < cvct->ChannelCount(); ++i)
1457 uint pnum = cvct->ProgramNumber(i);
1464 if ((
info.m_atscMajorChannel & 0x3F0) == 0x3F0)
1466 info.m_chanNum = QString::number(((
info.m_atscMajorChannel & 0x00F) << 10) +
info.m_atscMinorChannel);
1476 for (
const auto *tvct : scan_info->
m_tvcts)
1478 for (
uint i = 0; i < tvct->ChannelCount(); ++i)
1480 uint pnum = tvct->ProgramNumber(i);
1488 QString siStandard = (scan_info->
m_mgt ==
nullptr) ?
"dvb" :
"atsc";
1489 for (
const auto& sdt_list : std::as_const(scan_info->
m_sdts))
1491 for (
const auto *sdt_it : sdt_list)
1493 for (
uint i = 0; i < sdt_it->ServiceCount(); ++i)
1495 uint pnum = sdt_it->ServiceID(i);
1503 QMap<qlonglong, uint> ukChanNums;
1504 QMap<qlonglong, uint> scnChanNums;
1505 QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1506 for (dbchan_it = pnum_to_dbchan.begin();
1507 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1512 for (
const auto *item : scan_info->
m_nits)
1514 for (
uint i = 0; i < item->TransportStreamCount(); ++i)
1517 if ((nit->
TSID(i) ==
info.m_sdtTsId) &&
1521 info.m_inNit =
true;
1536 const unsigned char *desc =
1552 const unsigned char *desc =
1563 ukChanNums[((qlonglong)
info.m_origNetId<<32) |
1572 const unsigned char *desc =
1583 scnChanNums[((qlonglong)
info.m_origNetId<<32) |
1614 QMap<uint,qlonglong> lcn_sid;
1616 for (
const auto *bat : scan_info->
m_bats)
1622 for (
uint t = 0;
t < bat->TransportStreamCount(); ++
t)
1624 uint netid = bat->OriginalNetworkID(
t);
1635 bat->TransportDescriptorsLength(
t));
1638 for (
const auto *item : parsed)
1663 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1667 if (lcn_sid.value(lcn,0) == 0)
1668 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1689 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1693 if (lcn_sid.value(lcn,0) == 0)
1694 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1697 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1698 QString(
"LCN bid:%1 tid:%2 rid:%3 sid:%4 lcn:%5")
1699 .arg(bat->BouquetID()).arg(bat->TSID(
t)).arg(region_id).arg(service_id).arg(lcn));
1711 QMap<qlonglong, uint> sid_lcn;
1712 QMap<uint, qlonglong>::const_iterator r = lcn_sid.constEnd();
1713 while (r != lcn_sid.constBegin())
1716 qlonglong sid = r.value();
1724 for (dbchan_it = pnum_to_dbchan.begin();
1725 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1728 qlonglong key = ((qlonglong)
info.m_origNetId<<32) |
info.m_serviceId;
1729 QMap<qlonglong, uint>::const_iterator it;
1738 it = scnChanNums.constFind(key);
1739 if (it != scnChanNums.constEnd())
1741 info.m_simulcastChannel = *it;
1745 it = ukChanNums.constFind(key);
1746 if (it != ukChanNums.constEnd())
1748 info.m_logicalChannel = *it;
1752 it = sid_lcn.constFind(key);
1753 if (it != sid_lcn.constEnd())
1755 info.m_logicalChannel = *it;
1758 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1759 QString(
"service %1 (0x%2) lcn:%3 scn:%4 callsign '%5'")
1760 .arg(
info.m_serviceId).arg(
info.m_serviceId,4,16,QChar(
'0'))
1761 .arg(
info.m_logicalChannel).arg(
info.m_simulcastChannel).arg(
info.m_callSign));
1765 for (dbchan_it = pnum_to_dbchan.begin();
1766 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1770 if (!
info.m_chanNum.isEmpty())
1773 if ((
info.m_siStandard ==
"mpeg") ||
1774 (
info.m_siStandard ==
"scte") ||
1775 (
info.m_siStandard ==
"opencable"))
1777 if (
info.m_freqId.isEmpty())
1779 info.m_chanNum = QString(
"%1-%2")
1780 .arg(
info.m_sourceId)
1781 .arg(
info.m_serviceId);
1785 info.m_chanNum = QString(
"%1-%2")
1787 .arg(
info.m_serviceId);
1793 for (dbchan_it = pnum_to_dbchan.begin();
1794 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1798 if (!
info.m_chanNum.isEmpty())
1801 if (!iptv_channel.isEmpty())
1803 info.m_chanNum = iptv_channel;
1804 if (
info.m_serviceId)
1805 info.m_chanNum +=
"-" + QString::number(
info.m_serviceId);
1810 for (dbchan_it = pnum_to_dbchan.begin();
1811 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1813 uint pnum = dbchan_it.key();
1818 return pnum_to_dbchan;
1832 QMap<uint,ChannelInsertInfo> pnum_to_dbchan =
1841 QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1842 for (dbchan_it = pnum_to_dbchan.begin();
1843 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1857 for (
auto & channel : pnum_to_dbchan)
1859 if (channel.m_inPat && channel.m_inPmt)
1868 if (
info.m_serviceId == 0)
1870 dbchan_it = pnum_to_dbchan.begin();
1877 info.m_chanNum = QString(
"%1").arg(
info.m_serviceId);
1878 info.m_logicalChannel =
info.m_serviceId;
1882 info.m_callSign = QString(
"MPTS_%1")
1885 else if (
info.m_siStandard ==
"mpeg" ||
1886 info.m_siStandard ==
"scte" ||
1887 info.m_siStandard ==
"opencable")
1889 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_freqId);
1891 else if (
info.m_atscMajorChannel > 0)
1893 if (
info.m_atscMajorChannel < 0x3F0)
1895 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_atscMajorChannel);
1899 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_freqId);
1902 else if (
info.m_serviceId > 0)
1904 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_serviceId);
1906 else if (!
info.m_chanNum.isEmpty())
1908 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_chanNum);
1912 info.m_callSign =
"MPTS_UNKNOWN";
1915 info.m_serviceName =
info.m_callSign;
1916 info.m_atscMinorChannel = 0;
1917 info.m_format =
"MPTS";
1918 info.m_useOnAirGuide =
false;
1919 info.m_isEncrypted =
false;
1923 list.push_back(item);
2019 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"run -- begin");
2026 std::this_thread::sleep_for(10ms);
2029 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"run -- end");
2054 bool was_moving =
false;
2055 bool is_moving =
false;
2057 if (was_moving && !is_moving)
2089 if (
m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
2117 QMutexLocker locker(&
m_lock);
2170 QString name = QString(
"TransportID %1").arg(it.key() & 0xffff);
2216 return channel->
Tune(tuning,
true);
2235 return channel->
Tune(tuning);
2240 QString offset_str = (transport.
offset()) ?
2241 QObject::tr(
" offset %2").arg(transport.
offset()) :
"";
2242 QString cur_chan = QString(
"%1%2")
2243 .arg((*m_current).m_friendlyName, offset_str);
2244 QString tune_msg_str =
2245 QObject::tr(
"ScanTransport Tuning to %1 mplexid(%2)")
2246 .arg(cur_chan).arg((*m_current).m_mplexid);
2250 if (transport.
offset() &&
2264 LOG(VB_CHANSCAN, LOG_INFO,
LOC + tune_msg_str);
2266 if (!
Tune(transport))
2269 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
2270 QString(
"Failed to tune %1 mplexid(%2) at offset %3")
2272 .arg(transport.
offset()));
2298 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"StopScanner");
2321 const QString &modulation,
2322 const QString &country,
2323 const QString &table_start,
2324 const QString &table_end)
2326 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
2327 QString(
"%1:%2 ").arg(__FUNCTION__).arg(__LINE__) +
2328 QString(
"SourceID:%1 ").arg(
SourceID) +
2329 QString(
"std:%1 ").arg(std) +
2330 QString(
"modulation:%1 ").arg(modulation) +
2331 QString(
"country:%1 ").arg(country) +
2332 QString(
"table_start:%1 ").arg(table_start) +
2333 QString(
"table_end:%1 ").arg(table_end));
2347 QString msg = QString(
"No freq table for (%1, %2, %3) found")
2348 .arg(std, modulation, country);
2351 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
2352 QString(
"Looked up freq table (%1, %2, %3) w/%4 entries")
2353 .arg(std, modulation, country, QString::number(tables.size())));
2355 QString start = table_start;
2356 const QString& end = table_end;
2358 for (
auto it = tables.begin(); it != tables.end(); ++it)
2366 name = strNameFormat;
2367 if (strNameFormat.indexOf(
"%") >= 0)
2368 name = strNameFormat.arg(name_num);
2370 if (start.isEmpty() || name == start)
2378 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanTransports " +
2385 if (!end.isEmpty() && name == end)
2388 if (!end.isEmpty() && name == end)
2392 while (!tables.empty())
2394 delete tables.back();
2411 const QString &cardtype,
2418 tunertype.
Parse(cardtype);
2420 auto it = channels.cbegin();
2421 for (
uint i = 0; it != channels.cend(); ++it, ++i)
2430 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanForChannels " + item.
toString());
2435 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ScanForChannels() no transports");
2455 fbox_chan_map_t::const_iterator Ichan = iptv_channels.begin();
2456 for (
uint idx = 0; Ichan != iptv_channels.end(); ++Ichan, ++idx)
2459 Ichan.value().m_tuning, Ichan.key(),
2464 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanIPTVChannels " + item.
toString());
2469 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ScanIPTVChannels() no transports");
2489 int sourceid,
const QMap<QString,QString> &startChan)
2491 auto iter = startChan.find(
"type");
2492 if (iter == startChan.end())
2494 iter = startChan.find(
"std");
2495 if (iter == startChan.end())
2498 QString si_std = ((*iter).toLower() !=
"atsc") ?
"dvb" :
"atsc";
2510 ok =
type.Parse(startChan[
"type"]);
2516 startChan[
"frequency"], startChan[
"inversion"],
2517 startChan[
"symbolrate"], startChan[
"fec"],
2518 startChan[
"polarity"],
2519 startChan[
"coderate_hp"], startChan[
"coderate_lp"],
2520 startChan[
"constellation"], startChan[
"trans_mode"],
2521 startChan[
"guard_interval"], startChan[
"hierarchy"],
2522 startChan[
"modulation"], startChan[
"bandwidth"],
2523 startChan[
"mod_sys"], startChan[
"rolloff"]);
2530 sourceid, QObject::tr(
"Frequency %1").arg(startChan[
"frequency"]),
2554 "SELECT sourceid, sistandard, transportid, frequency, modulation, mod_sys "
2555 "FROM dtv_multiplex "
2556 "WHERE mplexid = :MPLEXID");
2566 LOG(VB_GENERAL, LOG_ERR,
LOC +
"AddToList() " +
2567 QString(
"Failed to locate mplexid(%1) in DB").arg(mplexid));
2571 uint sourceid = query.
value(0).toUInt();
2572 QString sistandard = query.
value(1).toString();
2574 uint frequency = query.
value(3).toUInt();
2575 QString modulation = query.
value(4).toString();
2576 QString mod_sys = query.
value(5).toString();
2578 delsys.
Parse(mod_sys);
2580 QString fn = tsid ? QString(
"Transport ID %1").arg(tsid) :
2581 QString(
"Multiplex #%1").arg(mplexid);
2583 if (modulation ==
"8vsb")
2585 QString chan = QString(
"%1 Hz").arg(frequency);
2586 int findFrequency = (query.
value(3).toInt() / 1000) - 1750;
2589 if ((list.freq <= findFrequency + 200) &&
2590 (list.freq >= findFrequency - 200))
2592 chan = QString(
"%1").arg(list.name);
2595 fn = QObject::tr(
"ATSC Channel %1").arg(chan);
2603 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
2604 QString(
"tunertype:%1 %2 sourceid:%3 sistandard:%4 fn:'%5' mplexid:%6")
2605 .arg(tt.
toInt()).arg(tt.
toString()).arg(sourceid).arg(sistandard, fn).arg(mplexid));
2609 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Adding " + fn);
2614 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Not adding incomplete transport " + fn);
2664 uint mpeg_program_num,
2665 QString &service_name,
2667 QString &common_status_info)
2669 if (channels.empty())
2673 for (
const auto & channel : channels)
2675 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
2676 QString(
"comparing %1 %2 against %3 %4")
2677 .arg(channel.m_serviceid).arg(channel.m_name)
2678 .arg(mpeg_program_num).arg(common_status_info));
2680 if (channel.m_serviceid == mpeg_program_num)
2683 if (!channel.m_name.isEmpty())
2685 service_name = channel.m_name;
2686 callsign = channel.m_name;
2693 common_status_info += QString(
" %1 %2")
2694 .arg(QObject::tr(
"as"), service_name);
2699 QObject::tr(
"Skipping %1, not in imported channel map")
2700 .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