38#include <QMutexLocker>
45#include "libmythbase/mythconfig.h"
87 return "ChannelScanSM(u)";
90#define LOC (ChannelScanSM::loc(this) + ": ")
151 int sourceID, std::chrono::milliseconds signal_timeout,
152 std::chrono::milliseconds channel_timeout, QString inputname,
153 bool test_decryption)
155 m_scanMonitor(scan_monitor),
157 m_signalMonitor(
SignalMonitor::Init(cardtype, m_channel->GetInputID(),
159 m_sourceID(sourceID),
160 m_signalTimeout(signal_timeout),
161 m_channelTimeout(channel_timeout),
162 m_inputName(
std::move(inputname)),
163 m_testDecryption(test_decryption),
174 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Connecting up DTVSignalMonitor");
179 "SELECT dvb_nit_id, bouquet_id, region_id, lcnoffset "
181 "WHERE videosource.sourceid = :SOURCEID");
187 else if (query.
next())
189 int nitid = query.
value(0).toInt();
190 data->SetRealNetworkID(nitid);
191 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
192 QString(
"Setting NIT-ID to %1").arg(nitid));
197 m_nitId = nitid > 0 ? nitid : 0;
200 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
201 QString(
"Freesat/Sky bouquet_id:%1 region_id:%2")
212 if (dvbchannel && dvbchannel->GetRotor())
216 data->AddMPEGListener(
this);
217 data->AddATSCMainListener(
this);
218 data->AddDVBMainListener(
this);
219 data->AddDVBOtherListener(
this);
226 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ChannelScanSM Stopped");
262 QMutexLocker locker(&
m_lock);
264 QString cur_chan = (*m_current).m_friendlyName;
265 QStringList list = cur_chan.split(
" ", Qt::SkipEmptyParts);
266 QString freqid = (list.size() >= 2) ? list[1] : cur_chan;
268 QString msg = QObject::tr(
"Updated Channel %1").arg(cur_chan);
274 QString callsign = QString(
"%1-%2")
292 QObject::tr(
"Added Channel %1").arg(cur_chan) :
293 QObject::tr(
"Failed to add channel %1").arg(cur_chan);
333 if (multiplexes.empty())
335 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
"Unable to find any transports for " +
336 QString(
"sourceid %1").arg(sourceid));
341 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
342 QString(
"Found %1 transports for ").arg(multiplexes.size()) +
343 QString(
"sourceid %1").arg(sourceid));
345 for (
uint multiplex : multiplexes)
358 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
359 "Unable to find add any transports for " +
360 QString(
"sourceid %1").arg(sourceid));
372 QStringList lines =
string.split(
'\n');
373 for (
const QString& line : std::as_const(lines))
374 LOG(VB_CHANSCAN, LOG_DEBUG, line);
380 QMutexLocker locker(&
m_lock);
382 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
383 QString(
"Got a Program Association Table for %1")
384 .arg((*m_current).m_friendlyName));
389 if (
nullptr == monitor)
400 QMutexLocker locker(&
m_lock);
402 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
403 QString(
"Got a Conditional Access Table for %1")
404 .arg((*m_current).m_friendlyName));
410 QMutexLocker locker(&
m_lock);
412 LOG(VB_CHANSCAN, LOG_INFO,
LOC + QString(
"Got a Program Map Table for %1 program %2 (0x%3)")
426 QMutexLocker locker(&
m_lock);
428 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
429 QString(
"Got a Virtual Channel Table for %1")
430 .arg((*m_current).m_friendlyName));
446 QMutexLocker locker(&
m_lock);
448 LOG(VB_CHANSCAN, LOG_INFO,
LOC + QString(
"Got the Master Guide for %1")
449 .arg((*m_current).m_friendlyName));
464 QMutexLocker locker(&
m_lock);
466 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
467 QString(
"Got a Service Description Table for %1 section %2/%3")
468 .arg((*m_current).m_friendlyName)
478 if (
nullptr != monitor)
481 if (
nullptr != stream)
490 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
491 QString(
"SDT has OriginalNetworkID %1, look for "
501 if (
nullptr != monitor)
504 SetVersionSDT(sdt->
TSID(), -1, 0);
524 QMutexLocker locker(&
m_lock);
526 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
527 QString(
"Got a Network Information Table id %1 for %2 section %3/%4")
528 .arg(nit->
NetworkID()).arg((*m_current).m_friendlyName)
537 QMutexLocker locker(&
m_lock);
539 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
540 QString(
"Got a Bouquet Association Table id %1 for %2 section %3/%4")
541 .arg(bat->
BouquetID()).arg((*m_current).m_friendlyName)
555 const unsigned char *def_auth =
557 const unsigned char *serv_list =
560 if (def_auth && serv_list)
571 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
572 QString(
"Found default authority '%1' in BAT for service nid %2 tid %3 sid %4")
574 .arg(netid).arg(tsid).arg(services.
ServiceID(j)));
575 uint64_t index = ((uint64_t)netid << 32) | (tsid << 16) |
587 QMutexLocker locker(&
m_lock);
589 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
590 QString(
"Got a Service Description Table (other) for Transport ID %1 section %2/%3")
605 const unsigned char *def_auth =
613 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
614 QString(
"Found default authority '%1' in SDTo for service nid %2 tid %3 sid %4")
616 .arg(netid).arg(tsid).arg(serviceId));
626 QMutexLocker locker(&
m_lock);
640 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Can't monitor decryption -- no pmts");
650 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"%1/%2 checked")
651 .arg(currentEncryptionStatusChecked.size())
652 .arg(currentEncryptionStatus.size()));
689 QObject::tr(
"Program %1 Testing Decryption")
692 QString(
"%1 -- Testing decryption of program %2")
693 .arg(cur_chan).arg(pnum);
696 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
704 if (
nullptr != monitor)
715 LOG(VB_GENERAL, LOG_INFO,
LOC +
716 QString(
"Can't monitor decryption of program %1 -- no pmt")
737 for (
auto & tt : tts)
751 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC + QString(
"%1 NIT nid:%2 fr:%3 section:%4/%5 ts count:%6 ")
757 uint32_t tsid = nit->
TSID(i);
759 uint32_t
id = netid << 16 | tsid;
768 for (
const auto *
const item : list)
770 uint64_t frequency = 0;
829 LOG(VB_CHANSCAN, LOG_DEBUG, QString(
"NIT onid:%1 add ts(%2):%3 %4")
830 .arg(netid).arg(i).arg(tsid).arg(tuning.
toString()));
835 LOG(VB_CHANSCAN, LOG_DEBUG, QString(
"NIT onid:%1 cannot add ts(%2):%3 fr:%4")
836 .arg(netid).arg(i).arg(tsid).arg(frequency));
867 bool transport_tune_complete =
true;
873 QMap<uint,bool> tsid_checked;
874 for (
auto & pat : pattmp)
876 uint tsid = pat->TransportStreamID();
877 if (tsid_checked[tsid])
879 tsid_checked[tsid] =
true;
894 transport_tune_complete =
false;
897 transport_tune_complete &= !pattmp.empty();
930 tsid_checked.clear();
931 for (
auto & sdt : sdttmp)
933 uint tsid = sdt->TSID();
934 if (tsid_checked[tsid])
936 tsid_checked[tsid] =
true;
953 if (transport_tune_complete)
959 transport_tune_complete =
false;
965 transport_tune_complete &=
977 if (transport_tune_complete)
980 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
981 QString(
"\nTable status after transport tune complete:") +
987 QString(
"\nsd->HasCachedAllSDT(%1): %2").arg(tsid,5).arg(sd->
HasCachedAllSDT(tsid)) +
989 QString(
"\nsd->HasCachedMGT(): %1").arg(sd->
HasCachedMGT()) +
1001 if (!wait_until_complete)
1002 transport_tune_complete =
true;
1003 if (transport_tune_complete)
1005 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1006 QString(
"transport_tune_complete: wait_until_complete %1").arg(wait_until_complete));
1024 QString msg_tr1 = QObject::tr(
"Program %1").arg(it.key());
1025 QString msg_tr2 = QObject::tr(
"Unknown decryption status");
1027 msg_tr2 = QObject::tr(
"Encrypted");
1029 msg_tr2 = QObject::tr(
"Decrypted");
1030 QString msg_tr =QString(
"%1 %2").arg(msg_tr1, msg_tr2);
1034 QString msg = QString(
"Program %1").arg(it.key());
1036 msg = msg +
" -- Encrypted";
1038 msg = msg +
" -- Decrypted";
1040 msg = msg +
" -- Unknown decryption status";
1042 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
1060 if (transport_tune_complete)
1066 QString chan_tr = QObject::tr(
"%1 -- Timed out").arg(cchan_tr);
1067 QString chan = QString(
"%1 -- Timed out").arg(cchan);
1068 QString msg_tr =
"";
1098 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1099 QString(
"Adding %1 offset:%2 ss:%3")
1103 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
1104 QString(
"%1(%2) m_inputName: %3 ").arg(__FUNCTION__).arg(__LINE__).arg(
m_inputName) +
1121 msg_tr = (cchan_cnt) ?
1122 QObject::tr(
"%1 possible channels").arg(cchan_cnt) :
1123 QObject::tr(
"no channels");
1124 msg_tr = QString(
"%1, %2").arg(chan_tr, msg_tr);
1126 QString(
"%1 possible channels").arg(cchan_cnt) :
1127 QString(
"no channels");
1128 msg = QString(
"%1, %2").arg(chan_tr, msg);
1131 m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
1134 msg_tr = QObject::tr(
"%1, no signal").arg(chan_tr);
1135 msg = QString(
"%1, no signal").arg(chan);
1139 msg_tr = QObject::tr(
"%1 -- Found %2 probable channels")
1140 .arg(cchan_tr).arg(cchan_cnt);
1142 msg = QString(
"%1 -- Found %2 probable channels")
1143 .arg(cchan).arg(cchan_cnt);
1147 LOG(VB_CHANSCAN, LOG_INFO,
LOC + msg);
1176#define PCM_INFO_INIT(SISTD) \
1177 ChannelInsertInfo &info = pnum_to_dbchan[pnum]; \
1178 info.m_dbMplexId = mplexid; info.m_sourceId = m_sourceID; \
1179 info.m_serviceId = pnum; info.m_freqId = freqidStr; \
1180 info.m_siStandard = SISTD;
1188 info.m_siStandard =
"ntsc";
1189 info.m_format =
"ntsc";
1195 if (
info.m_serviceName.isEmpty())
1198 info.m_chanNum.clear();
1215 info.m_inVct =
true;
1220 const QMap<uint64_t, QString> &defAuthorities)
1225 bool force_guide_present = (
1242 QString service_name;
1246 if (callsign.trimmed().isEmpty())
1248 callsign = QString(
"%1-%2-%3")
1254 if (service_name.trimmed().isEmpty())
1255 service_name.clear();
1258 info.m_isDataService =
1265 LOG(VB_CHANSCAN, LOG_INFO,
"ChannelScanSM: " +
1266 QString(
"No ServiceDescriptor for onid %1 tid %2 sid %3")
1270 if (
info.m_callSign.isEmpty())
1271 info.m_callSign = callsign;
1272 if (
info.m_serviceName.isEmpty())
1273 info.m_serviceName = service_name;
1275 info.m_useOnAirGuide =
1278 force_guide_present;
1280 info.m_hidden =
false;
1281 info.m_hiddenInGuide =
false;
1285 info.m_inSdt =
true;
1291 const unsigned char *def_auth =
1299 LOG(VB_CHANSCAN, LOG_DEBUG,
1300 QString(
"ChannelScanSM: Found default authority '%1' in SDT for service onid %2 tid %3 sid %4")
1302 .arg(
info.m_origNetId).arg(
info.m_sdtTsId).arg(
info.m_serviceId));
1310 uint64_t index = (uint64_t)
info.m_origNetId << 32 |
1311 info.m_sdtTsId << 16 |
info.m_serviceId;
1312 if (defAuthorities.contains(index))
1313 info.m_defaultAuthority = defAuthorities[index];
1319 info.m_oldOrigNetId = srdesc->OldOriginalNetworkID();
1320 info.m_oldTsId = srdesc->OldTransportID();
1321 info.m_oldServiceId = srdesc->OldServiceID();
1323 LOG(VB_CHANSCAN, LOG_DEBUG,
"ChannelScanSM: " +
1324 QString(
"Service '%1' onid:%2 tid:%3 sid:%4 ")
1325 .arg(
info.m_serviceName)
1326 .arg(
info.m_origNetId)
1327 .arg(
info.m_sdtTsId)
1328 .arg(
info.m_serviceId) +
1329 QString(
" relocated from onid:%1 tid:%2 sid:%3")
1330 .arg(
info.m_oldOrigNetId)
1331 .arg(
info.m_oldTsId)
1332 .arg(
info.m_oldServiceId));
1340 QString &cur_chan, QString &cur_chan_tr)
const
1345 cur_chan_tr.clear();
1349 uint max_chan_cnt = 0;
1353 for (
const auto &
info : std::as_const(list))
1357 info.m_inSdt ||
info.m_inVct) ? 1 : 0;
1363 cur_chan_tr = QString(
"%1%2")
1364 .arg((*m_current).m_friendlyName, offset_str_tr);
1368 cur_chan = QString(
"%1%2")
1369 .arg((*m_current).m_friendlyName, offset_str);
1371 return max_chan_cnt;
1374QMap<uint,ChannelInsertInfo>
1378 QMap<uint,ChannelInsertInfo> pnum_to_dbchan;
1380 uint mplexid = (*trans_info).m_mplexid;
1381 int freqid = (*trans_info).m_friendlyNum;
1382 QString freqidStr = (freqid) ? QString::number(freqid) : QString(
"");
1383 QString iptv_channel = (*trans_info).m_iptvChannel;
1387 for (
const auto & chan : echan)
1389 uint pnum = chan.m_serviceid;
1391 info.m_serviceName = chan.m_name;
1392 info.m_inChannelsConf =
true;
1396 for (
const auto& pat_list : std::as_const(scan_info->
m_pats))
1398 for (
const auto *pat : pat_list)
1400 bool could_be_opencable =
false;
1401 for (
uint i = 0; i < pat->ProgramCount(); ++i)
1403 if ((pat->ProgramNumber(i) == 0) &&
1406 could_be_opencable =
true;
1410 for (
uint i = 0; i < pat->ProgramCount(); ++i)
1412 uint pnum = pat->ProgramNumber(i);
1416 info.m_patTsId = pat->TransportStreamID();
1417 info.m_couldBeOpencable = could_be_opencable;
1418 info.m_inPat =
true;
1425 for (
const auto *pmt : scan_info->
m_pmts)
1427 uint pnum = pmt->ProgramNumber();
1429 for (
uint i = 0; i < pmt->StreamCount(); ++i)
1431 info.m_couldBeOpencable |=
1436 pmt->ProgramInfo(), pmt->ProgramInfoLength(),
1439 for (
auto & desc : descs)
1446 info.m_couldBeOpencable =
true;
1450 info.m_inPmt =
true;
1454 for (
const auto *cvct : scan_info->
m_cvcts)
1456 for (
uint i = 0; i < cvct->ChannelCount(); ++i)
1458 uint pnum = cvct->ProgramNumber(i);
1465 if ((
info.m_atscMajorChannel & 0x3F0) == 0x3F0)
1467 info.m_chanNum = QString::number(((
info.m_atscMajorChannel & 0x00F) << 10) +
info.m_atscMinorChannel);
1477 for (
const auto *tvct : scan_info->
m_tvcts)
1479 for (
uint i = 0; i < tvct->ChannelCount(); ++i)
1481 uint pnum = tvct->ProgramNumber(i);
1489 QString siStandard = (scan_info->
m_mgt ==
nullptr) ?
"dvb" :
"atsc";
1490 for (
const auto& sdt_list : std::as_const(scan_info->
m_sdts))
1492 for (
const auto *sdt_it : sdt_list)
1494 for (
uint i = 0; i < sdt_it->ServiceCount(); ++i)
1496 uint pnum = sdt_it->ServiceID(i);
1504 QMap<qlonglong, uint> ukChanNums;
1505 QMap<qlonglong, uint> scnChanNums;
1506 QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1507 for (dbchan_it = pnum_to_dbchan.begin();
1508 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1513 for (
const auto *item : scan_info->
m_nits)
1515 for (
uint i = 0; i < item->TransportStreamCount(); ++i)
1518 if ((nit->
TSID(i) ==
info.m_sdtTsId) &&
1522 info.m_inNit =
true;
1537 const unsigned char *desc =
1553 const unsigned char *desc =
1564 ukChanNums[((qlonglong)
info.m_origNetId<<32) |
1573 const unsigned char *desc =
1584 scnChanNums[((qlonglong)
info.m_origNetId<<32) |
1615 QMap<uint,qlonglong> lcn_sid;
1617 for (
const auto *bat : scan_info->
m_bats)
1623 for (
uint t = 0;
t < bat->TransportStreamCount(); ++
t)
1625 uint netid = bat->OriginalNetworkID(
t);
1636 bat->TransportDescriptorsLength(
t));
1639 for (
const auto *item : parsed)
1664 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1668 if (lcn_sid.value(lcn,0) == 0)
1669 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1690 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1694 if (lcn_sid.value(lcn,0) == 0)
1695 lcn_sid[lcn] = ((qlonglong)netid<<32) | service_id;
1698 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1699 QString(
"LCN bid:%1 tid:%2 rid:%3 sid:%4 lcn:%5")
1700 .arg(bat->BouquetID()).arg(bat->TSID(
t)).arg(region_id).arg(service_id).arg(lcn));
1712 QMap<qlonglong, uint> sid_lcn;
1713 QMap<uint, qlonglong>::const_iterator r = lcn_sid.constEnd();
1714 while (r != lcn_sid.constBegin())
1717 qlonglong sid = r.value();
1725 for (dbchan_it = pnum_to_dbchan.begin();
1726 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1729 qlonglong key = ((qlonglong)
info.m_origNetId<<32) |
info.m_serviceId;
1730 QMap<qlonglong, uint>::const_iterator it;
1739 it = scnChanNums.constFind(key);
1740 if (it != scnChanNums.constEnd())
1742 info.m_simulcastChannel = *it;
1746 it = ukChanNums.constFind(key);
1747 if (it != ukChanNums.constEnd())
1749 info.m_logicalChannel = *it;
1753 it = sid_lcn.constFind(key);
1754 if (it != sid_lcn.constEnd())
1756 info.m_logicalChannel = *it;
1759 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
1760 QString(
"service %1 (0x%2) lcn:%3 scn:%4 callsign '%5'")
1761 .arg(
info.m_serviceId).arg(
info.m_serviceId,4,16,QChar(
'0'))
1762 .arg(
info.m_logicalChannel).arg(
info.m_simulcastChannel).arg(
info.m_callSign));
1766 for (dbchan_it = pnum_to_dbchan.begin();
1767 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1771 if (!
info.m_chanNum.isEmpty())
1774 if ((
info.m_siStandard ==
"mpeg") ||
1775 (
info.m_siStandard ==
"scte") ||
1776 (
info.m_siStandard ==
"opencable"))
1778 if (
info.m_freqId.isEmpty())
1780 info.m_chanNum = QString(
"%1-%2")
1781 .arg(
info.m_sourceId)
1782 .arg(
info.m_serviceId);
1786 info.m_chanNum = QString(
"%1-%2")
1788 .arg(
info.m_serviceId);
1794 for (dbchan_it = pnum_to_dbchan.begin();
1795 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1799 if (!
info.m_chanNum.isEmpty())
1802 if (!iptv_channel.isEmpty())
1804 info.m_chanNum = iptv_channel;
1805 if (
info.m_serviceId)
1806 info.m_chanNum +=
"-" + QString::number(
info.m_serviceId);
1811 for (dbchan_it = pnum_to_dbchan.begin();
1812 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1814 uint pnum = dbchan_it.key();
1819 return pnum_to_dbchan;
1833 QMap<uint,ChannelInsertInfo> pnum_to_dbchan =
1842 QMap<uint,ChannelInsertInfo>::iterator dbchan_it;
1843 for (dbchan_it = pnum_to_dbchan.begin();
1844 dbchan_it != pnum_to_dbchan.end(); ++dbchan_it)
1858 for (
auto & channel : pnum_to_dbchan)
1860 if (channel.m_inPat && channel.m_inPmt)
1869 if (
info.m_serviceId == 0)
1871 dbchan_it = pnum_to_dbchan.begin();
1878 info.m_chanNum = QString(
"%1").arg(
info.m_serviceId);
1879 info.m_logicalChannel =
info.m_serviceId;
1883 info.m_callSign = QString(
"MPTS_%1")
1886 else if (
info.m_siStandard ==
"mpeg" ||
1887 info.m_siStandard ==
"scte" ||
1888 info.m_siStandard ==
"opencable")
1890 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_freqId);
1892 else if (
info.m_atscMajorChannel > 0)
1894 if (
info.m_atscMajorChannel < 0x3F0)
1896 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_atscMajorChannel);
1900 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_freqId);
1903 else if (
info.m_serviceId > 0)
1905 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_serviceId);
1907 else if (!
info.m_chanNum.isEmpty())
1909 info.m_callSign = QString(
"MPTS_%1").arg(
info.m_chanNum);
1913 info.m_callSign =
"MPTS_UNKNOWN";
1916 info.m_serviceName =
info.m_callSign;
1917 info.m_atscMinorChannel = 0;
1918 info.m_format =
"MPTS";
1919 info.m_useOnAirGuide =
false;
1920 info.m_isEncrypted =
false;
1924 list.push_back(item);
2015 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"run -- begin");
2025 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"run -- end");
2050 bool was_moving =
false;
2051 bool is_moving =
false;
2053 if (was_moving && !is_moving)
2085 if (
m_timer.hasExpired((*m_current).m_timeoutTune.count()) &&
2113 QMutexLocker locker(&
m_lock);
2166 QString name = QString(
"TransportID %1").arg(it.key() & 0xffff);
2212 return channel->
Tune(tuning,
true);
2231 return channel->
Tune(tuning);
2236 QString offset_str = (transport.
offset()) ?
2237 QObject::tr(
" offset %2").arg(transport.
offset()) :
"";
2238 QString cur_chan = QString(
"%1%2")
2239 .arg((*m_current).m_friendlyName, offset_str);
2240 QString tune_msg_str =
2241 QObject::tr(
"ScanTransport Tuning to %1 mplexid(%2)")
2242 .arg(cur_chan).arg((*m_current).m_mplexid);
2246 if (transport.
offset() &&
2260 LOG(VB_CHANSCAN, LOG_INFO,
LOC + tune_msg_str);
2262 if (!
Tune(transport))
2265 LOG(VB_CHANSCAN, LOG_ERR,
LOC +
2266 QString(
"Failed to tune %1 mplexid(%2) at offset %3")
2268 .arg(transport.
offset()));
2294 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"StopScanner");
2317 const QString &modulation,
2318 const QString &country,
2319 const QString &table_start,
2320 const QString &table_end)
2322 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
2323 QString(
"%1:%2 ").arg(__FUNCTION__).arg(__LINE__) +
2324 QString(
"SourceID:%1 ").arg(
SourceID) +
2325 QString(
"std:%1 ").arg(
std) +
2326 QString(
"modulation:%1 ").arg(modulation) +
2327 QString(
"country:%1 ").arg(country) +
2328 QString(
"table_start:%1 ").arg(table_start) +
2329 QString(
"table_end:%1 ").arg(table_end));
2343 QString msg = QString(
"No freq table for (%1, %2, %3) found")
2344 .arg(
std, modulation, country);
2347 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
2348 QString(
"Looked up freq table (%1, %2, %3) w/%4 entries")
2349 .arg(
std, modulation, country, QString::number(tables.size())));
2351 QString start = table_start;
2352 const QString& end = table_end;
2354 for (
auto it = tables.begin(); it != tables.end(); ++it)
2362 name = strNameFormat;
2363 if (strNameFormat.indexOf(
"%") >= 0)
2364 name = strNameFormat.arg(name_num);
2366 if (start.isEmpty() || name == start)
2374 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanTransports " +
2381 if (!end.isEmpty() && name == end)
2384 if (!end.isEmpty() && name == end)
2388 while (!tables.empty())
2390 delete tables.back();
2407 const QString &cardtype,
2414 tunertype.
Parse(cardtype);
2416 auto it = channels.cbegin();
2417 for (
uint i = 0; it != channels.cend(); ++it, ++i)
2426 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanForChannels " + item.
toString());
2431 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ScanForChannels() no transports");
2451 fbox_chan_map_t::const_iterator Ichan = iptv_channels.begin();
2452 for (
uint idx = 0; Ichan != iptv_channels.end(); ++Ichan, ++idx)
2455 Ichan.value().m_tuning, Ichan.key(),
2460 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"ScanIPTVChannels " + item.
toString());
2465 LOG(VB_GENERAL, LOG_ERR,
LOC +
"ScanIPTVChannels() no transports");
2485 int sourceid,
const QMap<QString,QString> &startChan)
2487 auto iter = startChan.find(
"type");
2488 if (iter == startChan.end())
2490 iter = startChan.find(
"std");
2491 if (iter == startChan.end())
2494 QString si_std = ((*iter).toLower() !=
"atsc") ?
"dvb" :
"atsc";
2506 ok =
type.Parse(startChan[
"type"]);
2512 startChan[
"frequency"], startChan[
"inversion"],
2513 startChan[
"symbolrate"], startChan[
"fec"],
2514 startChan[
"polarity"],
2515 startChan[
"coderate_hp"], startChan[
"coderate_lp"],
2516 startChan[
"constellation"], startChan[
"trans_mode"],
2517 startChan[
"guard_interval"], startChan[
"hierarchy"],
2518 startChan[
"modulation"], startChan[
"bandwidth"],
2519 startChan[
"mod_sys"], startChan[
"rolloff"]);
2526 sourceid, QObject::tr(
"Frequency %1").arg(startChan[
"frequency"]),
2550 "SELECT sourceid, sistandard, transportid, frequency, modulation, mod_sys "
2551 "FROM dtv_multiplex "
2552 "WHERE mplexid = :MPLEXID");
2562 LOG(VB_GENERAL, LOG_ERR,
LOC +
"AddToList() " +
2563 QString(
"Failed to locate mplexid(%1) in DB").arg(mplexid));
2567 uint sourceid = query.
value(0).toUInt();
2568 QString sistandard = query.
value(1).toString();
2570 uint frequency = query.
value(3).toUInt();
2571 QString modulation = query.
value(4).toString();
2572 QString mod_sys = query.
value(5).toString();
2574 delsys.
Parse(mod_sys);
2576 QString fn = (tsid) ? QString(
"Transport ID %1").arg(tsid) :
2577 QString(
"Multiplex #%1").arg(mplexid);
2579 if (modulation ==
"8vsb")
2581 QString chan = QString(
"%1 Hz").arg(frequency);
2582 int findFrequency = (query.
value(3).toInt() / 1000) - 1750;
2585 if ((list.freq <= findFrequency + 200) &&
2586 (list.freq >= findFrequency - 200))
2588 chan = QString(
"%1").arg(list.name);
2591 fn = QObject::tr(
"ATSC Channel %1").arg(chan);
2599 LOG(VB_CHANSCAN, LOG_DEBUG,
LOC +
2600 QString(
"tunertype:%1 %2 sourceid:%3 sistandard:%4 fn:'%5' mplexid:%6")
2601 .arg(tt).arg(tt.
toString()).arg(sourceid).arg(sistandard, fn).arg(mplexid));
2605 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Adding " + fn);
2610 LOG(VB_CHANSCAN, LOG_INFO,
LOC +
"Not adding incomplete transport " + fn);
2660 uint mpeg_program_num,
2661 QString &service_name,
2663 QString &common_status_info)
2665 if (channels.empty())
2669 for (
const auto & channel : channels)
2671 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
2672 QString(
"comparing %1 %2 against %3 %4")
2673 .arg(channel.m_serviceid).arg(channel.m_name)
2674 .arg(mpeg_program_num).arg(common_status_info));
2676 if (channel.m_serviceid == mpeg_program_num)
2679 if (!channel.m_name.isEmpty())
2681 service_name = channel.m_name;
2682 callsign = channel.m_name;
2689 common_status_info += QString(
" %1 %2")
2690 .arg(QObject::tr(
"as"), service_name);
2695 QObject::tr(
"Skipping %1, not in imported channel map")
2696 .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