11#include <QReadWriteLock>
12#include <QRegularExpression>
23#define LOC QString("ChanUtil: ")
40 "WHERE sourceid = :SOURCEID "
41 " AND sistandard = :SISTANDARD ";
43 if (sistandard.toLower() !=
"dvb")
44 qstr +=
"AND frequency = :FREQUENCY ";
47 qstr +=
"AND transportid = :TRANSPORTID ";
48 qstr +=
"AND networkid = :NETWORKID ";
49 qstr +=
"AND polarity = :POLARITY ";
56 query.
bindValue(
":SOURCEID", db_source_id);
57 query.
bindValue(
":SISTANDARD", sistandard);
59 if (sistandard.toLower() !=
"dvb")
60 query.
bindValue(
":FREQUENCY", QString::number(frequency));
63 query.
bindValue(
":TRANSPORTID", transport_id);
64 query.
bindValue(
":NETWORKID", network_id);
65 query.
bindValue(
":POLARITY", QChar(
static_cast<uint>(polarity)));
75 return query.
value(0).toUInt();
81 int db_source_id,
const QString& sistandard,
82 uint64_t frequency,
const QString& modulation,
84 int transport_id,
int network_id,
85 int symbol_rate,
signed char bandwidth,
86 signed char polarity,
signed char inversion,
87 signed char trans_mode,
88 const QString& inner_FEC,
const QString& constellation,
89 signed char hierarchy,
const QString& hp_code_rate,
90 const QString& lp_code_rate,
const QString& guard_interval,
91 const QString& mod_sys,
const QString& rolloff)
97 db_source_id, sistandard, frequency,
99 transport_id, network_id, polarity);
101 LOG(VB_CHANSCAN, LOG_INFO,
"insert_dtv_multiplex(" +
102 QString(
"dbid:%1 std:'%2' ").arg(db_source_id).arg(sistandard) +
103 QString(
"freq:%1 mod:%2 ").arg(frequency).arg(modulation) +
104 QString(
"tid:%1 nid:%2 ").arg(transport_id).arg(network_id) +
105 QString(
"pol:%1 msys:%2 ...)").arg(QChar(
static_cast<uint>(polarity))).arg(mod_sys) +
106 QString(
"mplexid:%1").arg(mplex));
108 bool isDVB = (sistandard.toLower() ==
"dvb");
111 "UPDATE dtv_multiplex "
112 "SET frequency = :FREQUENCY1, ";
114 updateStr += (!modulation.isNull()) ?
115 "modulation = :MODULATION, " :
"";
116 updateStr += (symbol_rate >= 0) ?
117 "symbolrate = :SYMBOLRATE, " :
"";
118 updateStr += (bandwidth >= 0) ?
119 "bandwidth = :BANDWIDTH, " :
"";
120 updateStr += (polarity >= 0) ?
121 "polarity = :POLARITY, " :
"";
122 updateStr += (inversion >= 0) ?
123 "inversion = :INVERSION, " :
"";
124 updateStr += (trans_mode >= 0) ?
125 "transmission_mode= :TRANS_MODE, " :
"";
126 updateStr += (!inner_FEC.isNull()) ?
127 "fec = :INNER_FEC, " :
"";
128 updateStr += (!constellation.isNull()) ?
129 "constellation = :CONSTELLATION, " :
"";
130 updateStr += (hierarchy >= 0) ?
131 "hierarchy = :HIERARCHY, " :
"";
132 updateStr += (!hp_code_rate.isNull()) ?
133 "hp_code_rate = :HP_CODE_RATE, " :
"";
134 updateStr += (!lp_code_rate.isNull()) ?
135 "lp_code_rate = :LP_CODE_RATE, " :
"";
136 updateStr += (!guard_interval.isNull()) ?
137 "guard_interval = :GUARD_INTERVAL, " :
"";
138 updateStr += (!mod_sys.isNull()) ?
139 "mod_sys = :MOD_SYS, " :
"";
140 updateStr += (symbol_rate >= 0) ?
141 "rolloff = :ROLLOFF, " :
"";
142 updateStr += (transport_id && !isDVB) ?
143 "transportid = :TRANSPORTID, " :
"";
145 updateStr = updateStr.left(updateStr.length()-2) +
" ";
148 "WHERE sourceid = :SOURCEID AND "
149 " sistandard = :SISTANDARD AND ";
151 updateStr += (isDVB) ?
152 " polarity = :WHEREPOLARITY AND "
153 " transportid = :TRANSPORTID AND networkid = :NETWORKID " :
154 " frequency = :FREQUENCY2 ";
157 "INSERT INTO dtv_multiplex "
158 " (sourceid, sistandard, frequency, ";
160 insertStr += (!modulation.isNull()) ?
"modulation, " :
"";
161 insertStr += (transport_id || isDVB) ?
"transportid, " :
"";
162 insertStr += (isDVB) ?
"networkid, " :
"";
163 insertStr += (symbol_rate >= 0) ?
"symbolrate, " :
"";
164 insertStr += (bandwidth >= 0) ?
"bandwidth, " :
"";
165 insertStr += (polarity >= 0) ?
"polarity, " :
"";
166 insertStr += (inversion >= 0) ?
"inversion, " :
"";
167 insertStr += (trans_mode >= 0) ?
"transmission_mode, " :
"";
168 insertStr += (!inner_FEC.isNull()) ?
"fec, " :
"";
169 insertStr += (!constellation.isNull()) ?
"constellation, " :
"";
170 insertStr += (hierarchy >= 0) ?
"hierarchy, " :
"";
171 insertStr += (!hp_code_rate.isNull()) ?
"hp_code_rate, " :
"";
172 insertStr += (!lp_code_rate.isNull()) ?
"lp_code_rate, " :
"";
173 insertStr += (!guard_interval.isNull()) ?
"guard_interval, " :
"";
174 insertStr += (!mod_sys.isNull()) ?
"mod_sys, " :
"";
175 insertStr += (!rolloff.isNull()) ?
"rolloff, " :
"";
176 insertStr = insertStr.left(insertStr.length()-2) +
") ";
180 " (:SOURCEID, :SISTANDARD, :FREQUENCY1, ";
181 insertStr += (!modulation.isNull()) ?
":MODULATION, " :
"";
182 insertStr += (transport_id || isDVB) ?
":TRANSPORTID, " :
"";
183 insertStr += (isDVB) ?
":NETWORKID, " :
"";
184 insertStr += (symbol_rate >= 0) ?
":SYMBOLRATE, " :
"";
185 insertStr += (bandwidth >= 0) ?
":BANDWIDTH, " :
"";
186 insertStr += (polarity >= 0) ?
":POLARITY, " :
"";
187 insertStr += (inversion >= 0) ?
":INVERSION, " :
"";
188 insertStr += (trans_mode >= 0) ?
":TRANS_MODE, " :
"";
189 insertStr += (!inner_FEC.isNull()) ?
":INNER_FEC, " :
"";
190 insertStr += (!constellation.isNull()) ?
":CONSTELLATION, " :
"";
191 insertStr += (hierarchy >= 0) ?
":HIERARCHY, " :
"";
192 insertStr += (!hp_code_rate.isNull()) ?
":HP_CODE_RATE, " :
"";
193 insertStr += (!lp_code_rate.isNull()) ?
":LP_CODE_RATE, " :
"";
194 insertStr += (!guard_interval.isNull()) ?
":GUARD_INTERVAL, " :
"";
195 insertStr += (!mod_sys.isNull()) ?
":MOD_SYS, " :
"";
196 insertStr += (!rolloff.isNull()) ?
":ROLLOFF, " :
"";
197 insertStr = insertStr.left(insertStr.length()-2) +
");";
199 query.
prepare((mplex) ? updateStr : insertStr);
201 query.
bindValue(
":SOURCEID", db_source_id);
202 query.
bindValue(
":SISTANDARD", sistandard);
203 query.
bindValue(
":FREQUENCY1", QString::number(frequency));
209 query.
bindValue(
":TRANSPORTID", transport_id);
210 query.
bindValue(
":NETWORKID", network_id);
211 query.
bindValue(
":WHEREPOLARITY", QChar(
static_cast<uint>(polarity)));
215 query.
bindValue(
":FREQUENCY2", QString::number(frequency));
217 query.
bindValue(
":TRANSPORTID", transport_id);
222 if (transport_id || isDVB)
223 query.
bindValue(
":TRANSPORTID", transport_id);
225 query.
bindValue(
":NETWORKID", network_id);
228 if (!modulation.isNull())
229 query.
bindValue(
":MODULATION", modulation);
231 if (symbol_rate >= 0)
232 query.
bindValue(
":SYMBOLRATE", symbol_rate);
234 query.
bindValue(
":BANDWIDTH", QString(
"%1").arg((
char)bandwidth));
236 query.
bindValue(
":POLARITY", QString(
"%1").arg((
char)polarity));
238 query.
bindValue(
":INVERSION", QString(
"%1").arg((
char)inversion));
240 query.
bindValue(
":TRANS_MODE", QString(
"%1").arg((
char)trans_mode));
242 if (!inner_FEC.isNull())
243 query.
bindValue(
":INNER_FEC", inner_FEC);
244 if (!constellation.isNull())
245 query.
bindValue(
":CONSTELLATION", constellation);
247 query.
bindValue(
":HIERARCHY", QString(
"%1").arg((
char)hierarchy));
248 if (!hp_code_rate.isNull())
249 query.
bindValue(
":HP_CODE_RATE", hp_code_rate);
250 if (!lp_code_rate.isNull())
251 query.
bindValue(
":LP_CODE_RATE", lp_code_rate);
252 if (!guard_interval.isNull())
253 query.
bindValue(
":GUARD_INTERVAL",guard_interval);
254 if (!mod_sys.isNull())
256 if (!rolloff.isNull())
269 db_source_id, sistandard, frequency,
271 transport_id, network_id, polarity);
273 LOG(VB_CHANSCAN, LOG_INFO, QString(
"insert_dtv_multiplex -- ") +
274 QString(
"inserted mplexid %1").arg(mplex));
298 uint dummy_netid = 0;
300 dummy_tsid, dummy_netid, dummy_sistd);
304 (
int)sourceid,
"dvb",
307 (
int)tsid, (
int)netid,
314 QString(), QString());
317 muxes.push_back(mux);
341 QString(), QString(),
345 muxes.push_back(mux);
365 QString(), QString(),
366 QString(), QString());
369 muxes.push_back(mux);
374 uint64_t frequency,
const QString& modulation,
375 int transport_id,
int network_id)
378 sourceid, sistandard,
379 frequency, modulation,
380 transport_id, network_id,
384 QString(), QString(),
386 QString(), QString(),
387 QString(), QString());
391 int sourceid,
const QString& sistandard,
392 uint64_t
freq,
const QString& modulation,
394 int transport_id,
int network_id,
395 int symbol_rate,
signed char bandwidth,
396 signed char polarity,
signed char inversion,
397 signed char trans_mode,
398 const QString& inner_FEC,
const QString& constellation,
399 signed char hierarchy,
const QString& hp_code_rate,
400 const QString& lp_code_rate,
const QString& guard_interval,
401 const QString& mod_sys,
const QString& rolloff)
404 sourceid, sistandard,
407 transport_id, network_id,
408 symbol_rate, bandwidth,
411 inner_FEC, constellation,
412 hierarchy, hp_code_rate,
413 lp_code_rate, guard_interval,
418 int transport_id,
int network_id)
424 transport_id, network_id,
441 std::vector<uint> muxes;
454 for (
const auto *j : list)
470 "WHERE deleted IS NULL AND "
471 " sourceid = :SOURCEID AND "
472 " channum = :CHANNUM");
479 else if (query.
next())
480 return query.
value(0).toInt();
491 "FROM dtv_multiplex "
492 "WHERE sourceid = :SOURCEID AND "
493 " frequency = :FREQUENCY");
496 query.
bindValue(
":FREQUENCY", QString::number(frequency));
505 return query.
value(0).toInt();
517 "FROM dtv_multiplex "
518 "WHERE networkid = :NETWORKID AND "
519 " transportid = :TRANSPORTID AND "
520 " frequency = :FREQUENCY AND "
521 " sourceid = :SOURCEID");
524 query.
bindValue(
":NETWORKID", network_id);
525 query.
bindValue(
":TRANSPORTID", transport_id);
526 query.
bindValue(
":FREQUENCY", QString::number(frequency));
535 return query.
value(0).toInt();
547 "FROM dtv_multiplex "
548 "WHERE networkid = :NETWORKID AND "
549 " transportid = :TRANSPORTID AND "
550 " sourceid = :SOURCEID");
553 query.
bindValue(
":NETWORKID", network_id);
554 query.
bindValue(
":TRANSPORTID", transport_id);
563 return query.
value(0).toInt();
575 "WHERE chanid = :CHANID");
581 else if (query.
next())
582 return query.
value(0).toInt();
615 LOG(VB_CHANSCAN, LOG_INFO,
616 QString(
"GetBetterMplexID(mplexId %1, tId %2, netId %3)")
617 .arg(current_mplexid).arg(transport_id).arg(network_id));
620 int q_transportid = 0;
623 query.
prepare(
"SELECT networkid, transportid "
624 "FROM dtv_multiplex "
625 "WHERE mplexid = :MPLEX_ID");
627 query.
bindValue(
":MPLEX_ID", current_mplexid);
631 else if (query.
next())
633 q_networkid = query.
value(0).toInt();
634 q_transportid = query.
value(1).toInt();
638 if ((q_networkid == network_id) && (q_transportid == transport_id))
640 LOG(VB_CHANSCAN, LOG_INFO,
641 QString(
"GetBetterMplexID(): Returning perfect match %1")
642 .arg(current_mplexid));
643 return current_mplexid;
647 if (!q_networkid && !q_transportid)
649 int qsize = query.
size();
650 query.
prepare(
"UPDATE dtv_multiplex "
651 "SET networkid = :NETWORK_ID, "
652 " transportid = :TRANSPORT_ID "
653 "WHERE mplexid = :MPLEX_ID");
655 query.
bindValue(
":NETWORK_ID", network_id);
656 query.
bindValue(
":TRANSPORT_ID", transport_id);
657 query.
bindValue(
":MPLEX_ID", current_mplexid);
662 LOG(VB_CHANSCAN, LOG_INFO,
663 QString(
"GetBetterMplexID(): net id and transport id "
664 "are null, qsize(%1), Returning %2")
665 .arg(qsize).arg(current_mplexid));
666 return current_mplexid;
670 std::array<QString,2> theQueries
672 QString(
"SELECT a.mplexid "
673 "FROM dtv_multiplex a, dtv_multiplex b "
674 "WHERE a.networkid = :NETWORK_ID AND "
675 " a.transportid = :TRANSPORT_ID AND "
676 " a.sourceid = b.sourceid AND "
677 " b.mplexid = :MPLEX_ID"),
679 QString(
"SELECT mplexid "
680 "FROM dtv_multiplex "
681 "WHERE networkid = :NETWORK_ID AND "
682 " transportid = :TRANSPORT_ID"),
685 for (
uint i=0; i<2; i++)
689 query.
bindValue(
":NETWORK_ID", network_id);
690 query.
bindValue(
":TRANSPORT_ID", transport_id);
692 query.
bindValue(
":MPLEX_ID", current_mplexid);
697 if (query.
size() == 1 && query.
next())
699 LOG(VB_CHANSCAN, LOG_INFO,
700 QString(
"GetBetterMplexID(): query#%1 qsize(%2) "
702 .arg(i).arg(query.
size()).arg(current_mplexid));
703 return query.
value(0).toInt();
708 int ret = (i==0) ? current_mplexid : query.
value(0).toInt();
709 LOG(VB_CHANSCAN, LOG_INFO,
710 QString(
"GetBetterMplexID(): query#%1 qsize(%2) "
712 .arg(i).arg(query.
size()).arg(ret));
718 LOG(VB_CHANSCAN, LOG_INFO,
"GetBetterMplexID(): Returning -1");
725 uint &dvb_transportid,
729 if (!mplexid || (mplexid == 32767))
734 "SELECT transportid, networkid, frequency, modulation, sistandard "
735 "FROM dtv_multiplex "
736 "WHERE mplexid = :MPLEXID");
748 dvb_transportid = query.
value(0).toUInt();
749 dvb_networkid = query.
value(1).toUInt();
750 frequency = query.
value(2).toULongLong();
751 modulation = query.
value(3).toString();
752 si_std = query.
value(4).toString();
763 query.
prepare(QString(
"SELECT %1 FROM channel "
764 "WHERE chanid = :CHANID").arg(field));
775 return query.
value(0).toString();
792 query.
prepare(
"SELECT sourceid "
793 "FROM dtv_multiplex "
794 "WHERE mplexid = :MPLEXID");
803 return query.
value(0).toInt();
815 "WHERE chanid = :CHANID");
820 else if (query.
next())
821 return query.
value(0).toUInt();
829 query.
prepare(
"SELECT cardtype "
830 "FROM capturecard, channel "
831 "WHERE channel.chanid = :CHANID AND "
832 " channel.sourceid = capturecard.sourceid "
833 "GROUP BY cardtype");
843 list.push_back(query.
value(0).toString());
863 query.
prepare(
"SELECT pid, tableid FROM pidcache "
864 "WHERE chanid = :CHANID");
876 int pid = query.
value(0).toInt();
877 int tid = query.
value(1).toInt();
878 if ((pid >= 0) && (tid >= 0))
879 pid_cache.emplace_back(pid, tid);
881 stable_sort(pid_cache.begin(), pid_cache.end(),
lt_pidcache);
900 query.
prepare(
"DELETE FROM pidcache WHERE chanid = :CHANID");
904 "DELETE FROM pidcache "
905 "WHERE chanid = :CHANID AND tableid < 65536");
919 stable_sort(pid_cache.begin(), pid_cache.end(),
lt_pidcache);
923 "INSERT INTO pidcache "
924 "SET chanid = :CHANID, pid = :PID, tableid = :TABLEID");
928 auto ito = old_cache.begin();
929 for (
const auto& itn : pid_cache)
932 for (; ito != old_cache.end() && ito->GetPID() < itn.GetPID(); ++ito);
935 if (ito != old_cache.end() && ito->GetPID() == itn.GetPID())
939 query.
bindValue(
":TABLEID", itn.GetComposite());
953 const QString &channum)
963 "WHERE deleted IS NULL AND "
964 " channum = :CHANNUM AND "
965 " sourceid = :SOURCEID")
966 .arg(channel_field));
973 else if (query.
next())
974 retval = query.
value(0).toString();
981 const QString &channum)
987 retval = val.toInt();
989 return (retval) ? retval : -1;
994 if (channel_name.isEmpty())
998 query.
prepare(
"SELECT channum FROM channel WHERE sourceid = :SOURCEID "
1000 "AND deleted IS NULL;" );
1002 query.
bindValue(
":NAME", channel_name.left(64));
1012 return query.
value(0).toString();
1016 const QString &new_channum,
1017 const QString &old_channum)
1019 if (new_channum.isEmpty() || old_channum.isEmpty())
1022 if (new_channum == old_channum)
1033 LOG(VB_CHANNEL, LOG_INFO, QString(
"IsOnSameMultiplex? %1==%2 -> %3")
1034 .arg(old_mplexid).arg(new_mplexid)
1035 .arg(old_mplexid == new_mplexid));
1037 return old_mplexid == new_mplexid;
1047 QStringList reclist;
1054 "SELECT capturecard.cardid "
1056 "LEFT JOIN capturecard ON channel.sourceid = capturecard.sourceid "
1057 "WHERE channel.chanid = :CHANID AND "
1058 " capturecard.livetvorder > 0 "
1059 "ORDER BY capturecard.livetvorder, capturecard.cardid");
1068 while (query.
next())
1069 reclist << query.
value(0).toString();
1081 QStringList reclist;
1088 "SELECT capturecard.cardid "
1090 "LEFT JOIN capturecard ON channel.sourceid = capturecard.sourceid "
1091 "WHERE channel.deleted IS NULL AND "
1092 " channel.channum = :CHANNUM AND "
1093 " capturecard.livetvorder > 0 "
1094 "ORDER BY capturecard.livetvorder, capturecard.cardid");
1103 while (query.
next())
1104 reclist << query.
value(0).toString();
1117 uint chanid,
const QString &channum)
1121 if (!channum.isEmpty())
1130 std::vector<uint> conflicting;
1135 "SELECT chanid from channel "
1136 "WHERE deleted IS NULL AND "
1137 " sourceid = :SOURCEID AND "
1138 " channum = :CHANNUM");
1144 "SELECT chanid from channel "
1145 "WHERE deleted IS NULL AND "
1146 " channum = :CHANNUM");
1153 conflicting.push_back(0);
1157 while (query.
next())
1158 conflicting.push_back(query.
value(0).toUInt());
1164 const QString& value,
1166 const QString &channum)
1171 QString(
"UPDATE channel SET channel.%1=:VALUE "
1172 "WHERE channel.channum = :CHANNUM AND "
1173 " channel.sourceid = :SOURCEID").arg(field_name));
1179 return query.
exec();
1183 const QString& value,
1189 QString(
"UPDATE channel SET channel.%1=:VALUE "
1190 "WHERE channel.chanid = :CHANID").arg(field_name));
1195 return query.
exec();
1216 "SELECT chanid, m.default_authority "
1218 "LEFT JOIN dtv_multiplex m "
1219 "ON (c.mplexid = m.mplexid) "
1220 "WHERE deleted IS NULL");
1223 while (query.
next())
1225 if (!query.
value(1).toString().isEmpty())
1228 query.
value(1).toString();
1239 "SELECT chanid, default_authority "
1241 "WHERE deleted IS NULL");
1244 while (query.
next())
1246 if (!query.
value(1).toString().isEmpty())
1249 query.
value(1).toString();
1273 static QReadWriteLock s_channelIconMapLock;
1274 static QHash<uint,QString> s_channelIconMap;
1275 static bool s_runInit =
true;
1277 s_channelIconMapLock.lockForRead();
1279 QString ret(s_channelIconMap.value(chanid,
"_cold_"));
1281 s_channelIconMapLock.unlock();
1283 if (ret !=
"_cold_")
1286 s_channelIconMapLock.lockForWrite();
1289 QString iconquery =
"SELECT chanid, icon FROM channel";
1292 iconquery +=
" WHERE visible > 0";
1294 iconquery +=
" WHERE chanid = :CHANID";
1305 s_channelIconMap.reserve(query.
size());
1306 while (query.
next())
1308 s_channelIconMap[query.
value(0).toUInt()] =
1309 query.
value(1).toString();
1315 s_channelIconMap[chanid] = (query.
next()) ?
1316 query.
value(1).toString() :
"";
1324 ret = s_channelIconMap.value(chanid,
"");
1326 s_channelIconMapLock.unlock();
1333 return tr(
"UNKNOWN",
"Synthesized callsign");
1337 int major_channel,
int minor_channel,
1343 query.
prepare(
"SELECT sourceid "
1344 "FROM dtv_multiplex "
1345 "WHERE mplexid = :MPLEXID");
1355 int source_id = query.
value(0).toInt();
1358 query.
prepare(
"SELECT chanid FROM channel,dtv_multiplex "
1359 "WHERE channel.deleted IS NULL AND "
1360 " channel.sourceid = :SOURCEID AND "
1361 " atsc_major_chan = :MAJORCHAN AND "
1362 " atsc_minor_chan = :MINORCHAN AND "
1363 " dtv_multiplex.transportid = :TRANSPORTID AND "
1364 " dtv_multiplex.mplexid = :MPLEXID AND "
1365 " dtv_multiplex.sourceid = channel.sourceid AND "
1366 " dtv_multiplex.mplexid = channel.mplexid");
1368 query.
bindValue(
":SOURCEID", source_id);
1369 query.
bindValue(
":MAJORCHAN", major_channel);
1370 query.
bindValue(
":MINORCHAN", minor_channel);
1371 query.
bindValue(
":TRANSPORTID", service_transport_id);
1375 return query.
value(0).toInt();
1379 query.
prepare(
"SELECT chanid FROM channel "
1380 "WHERE deleted IS NULL AND "
1381 "sourceid = :SOURCEID AND "
1382 "atsc_major_chan = :MAJORCHAN AND "
1383 "atsc_minor_chan = :MINORCHAN");
1385 query.
bindValue(
":SOURCEID", source_id);
1386 query.
bindValue(
":MAJORCHAN", major_channel);
1387 query.
bindValue(
":MINORCHAN", minor_channel);
1390 return query.
value(0).toInt();
1393 query.
prepare(
"SELECT chanid FROM channel "
1394 "WHERE deleted IS NULL AND "
1395 "sourceid = :SOURCEID AND "
1396 "serviceID = :SERVICEID AND "
1397 "mplexid = :MPLEXID");
1399 query.
bindValue(
":SOURCEID", source_id);
1400 query.
bindValue(
":SERVICEID", program_number);
1404 return query.
value(0).toInt();
1412 query.
prepare(
"SELECT chanid "
1414 "WHERE deleted IS NULL AND "
1415 " sourceid = :SOURCEID AND "
1416 " freqid = :FREQID");
1423 else if (query.
next())
1424 return query.
value(0).toUInt();
1432 QString qstr =
"SELECT MAX(chanid) FROM channel ";
1433 qstr += (sourceid) ?
"WHERE sourceid = :SOURCEID" :
"";
1443 else if (!query.
next())
1444 LOG(VB_GENERAL, LOG_ERR,
"Error getting chanid for new channel.");
1446 return query.
value(0).toUInt();
1457 "WHERE chanid = :CHANID");
1462 else if (query.
size() == 0)
1475 static const QRegularExpression kNonDigitRE { R
"(\D)" };
1477 int chansep = chan_num.indexOf(kNonDigitRE);
1481 (sourceid * 10000) +
1482 (chan_num.left(chansep).toInt() * 100) +
1483 chan_num.right(chan_num.length() - chansep - 1).toInt();
1487 chanid = (sourceid * 10000) + chan_num.toInt();
1494 chanid = std::max(
get_max_chanid(sourceid) + 1, sourceid * 10000);
1511 uint new_channel_id,
1512 const QString &callsign,
1513 const QString &service_name,
1514 const QString &chan_num,
1516 uint atsc_major_channel,
1517 uint atsc_minor_channel,
1518 bool use_on_air_guide,
1520 const QString &freqid,
1521 const QString& icon,
1523 const QString& xmltvid,
1524 const QString& default_authority,
1532 QString chanNum = (chan_num ==
"-1") ?
1533 QString::number(service_id) : chan_num;
1536 "INSERT INTO channel "
1537 " (chanid, channum, sourceid, "
1538 " callsign, name, serviceid, ";
1539 qstr += (db_mplexid > 0) ?
"mplexid, " :
"";
1540 qstr += (!freqid.isEmpty()) ?
"freqid, " :
"";
1542 " atsc_major_chan, atsc_minor_chan, "
1543 " useonairguide, visible, tvformat, "
1544 " icon, xmltvid, default_authority, "
1545 " service_type, recpriority, tmoffset, "
1548 " (:CHANID, :CHANNUM, :SOURCEID, "
1549 " :CALLSIGN, :NAME, :SERVICEID, ";
1550 qstr += (db_mplexid > 0) ?
":MPLEXID, " :
"";
1551 qstr += (!freqid.isEmpty()) ?
":FREQID, " :
"";
1553 " :MAJORCHAN, :MINORCHAN, "
1554 " :USEOAG, :VISIBLE, :TVFORMAT, "
1555 " :ICON, :XMLTVID, :AUTHORITY, "
1556 " :SERVICETYPE, :RECPRIORITY, :TMOFFSET, "
1561 query.
bindValue (
":CHANID", new_channel_id);
1563 query.
bindValue (
":SOURCEID", db_sourceid);
1568 query.
bindValue(
":MPLEXID", db_mplexid);
1570 query.
bindValue(
":SERVICEID", service_id);
1571 query.
bindValue(
":MAJORCHAN", atsc_major_channel);
1572 query.
bindValue(
":MINORCHAN", atsc_minor_channel);
1573 query.
bindValue(
":USEOAG", use_on_air_guide);
1576 if (!freqid.isEmpty())
1579 QString tvformat = (atsc_minor_channel > 0) ?
"ATSC" : std::move(format);
1584 query.
bindValue (
":SERVICETYPE", service_type);
1585 query.
bindValue (
":RECPRIORITY", recpriority);
1586 query.
bindValue (
":TMOFFSET", tmOffset);
1587 query.
bindValue (
":COMMMETHOD", commMethod);
1600 const QString &callsign,
1601 const QString &service_name,
1602 const QString &chan_num,
1604 uint atsc_major_channel,
1605 uint atsc_minor_channel,
1606 bool use_on_air_guide,
1608 const QString& freqid,
1609 const QString& icon,
1611 const QString& xmltvid,
1612 const QString& default_authority,
1621 QString tvformat = (atsc_minor_channel > 0) ?
"ATSC" : std::move(format);
1622 bool set_channum = !chan_num.isEmpty() && chan_num !=
"-1";
1623 QString qstr = QString(
1625 "SET %1 %2 %3 %4 %5 %6 %7 %8 %9 "
1626 " mplexid = :MPLEXID, serviceid = :SERVICEID, "
1627 " atsc_major_chan = :MAJORCHAN, atsc_minor_chan = :MINORCHAN, "
1628 " callsign = :CALLSIGN, name = :NAME, "
1629 " sourceid = :SOURCEID, useonairguide = :USEOAG, "
1630 " visible = :VISIBLE, service_type = :SERVICETYPE "
1631 "WHERE chanid=:CHANID")
1632 .arg((!set_channum) ?
"" :
"channum = :CHANNUM, ",
1633 (freqid.isEmpty()) ?
"" :
"freqid = :FREQID, ",
1634 (icon.isEmpty()) ?
"" :
"icon = :ICON, ",
1635 (tvformat.isEmpty()) ?
"" :
"tvformat = :TVFORMAT, ",
1636 (xmltvid.isEmpty()) ?
"" :
"xmltvid = :XMLTVID, ",
1637 (default_authority.isEmpty()) ?
1638 "" :
"default_authority = :AUTHORITY,",
1639 (recpriority == INT_MIN) ?
"" :
"recpriority = :RECPRIORITY, ",
1640 (tmOffset == INT_MIN) ?
"" :
"tmOffset = :TMOFFSET, ",
1641 (commMethod == INT_MIN) ?
"" :
"commmethod = :COMMMETHOD, ");
1651 query.
bindValue (
":SOURCEID", source_id);
1655 query.
bindValue(
":MPLEXID", db_mplexid);
1656 query.
bindValue(
":SERVICEID", service_id);
1657 query.
bindValue(
":MAJORCHAN", atsc_major_channel);
1658 query.
bindValue(
":MINORCHAN", atsc_minor_channel);
1659 query.
bindValue(
":USEOAG", use_on_air_guide);
1661 query.
bindValue(
":SERVICETYPE", service_type);
1663 if (!freqid.isNull())
1665 if (!tvformat.isNull())
1669 if (!xmltvid.isNull())
1671 if (!default_authority.isNull())
1672 query.
bindValue(
":AUTHORITY", default_authority);
1673 if (recpriority != INT_MIN)
1674 query.
bindValue(
":RECPRIORITY", recpriority);
1675 if (tmOffset != INT_MIN)
1677 if (commMethod != INT_MIN)
1678 query.
bindValue(
":COMMMETHOD", commMethod);
1694 "WHERE chanid = :ID");
1705 QString channum = query.
value(0).toString();
1707 if (!channum.isEmpty())
1718 "SELECT xmltvid, useonairguide, visible "
1720 "WHERE chanid = :ID");
1731 QString xmltvid = query.
value(0).toString();
1732 bool useeit = query.
value(1).toBool();
1736 if (!xmltvid.isEmpty())
1740 LOG(VB_GENERAL, LOG_ERR,
1741 "Using EIT and xmltv for the same channel "
1742 "is an unsupported configuration.");
1759 "DELETE FROM iptv_channel "
1760 "WHERE chanid=:CHANID");
1770 "INSERT INTO iptv_channel (chanid, url, type, bitrate) "
1771 "VALUES (:CHANID, :URL, :TYPE, :BITRATE)");
1816 "SET deleted = NOW() "
1817 "WHERE chanid = :ID");
1834 "SET visible = :VISIBLE "
1835 "WHERE chanid = :ID");
1852 query.
prepare(
"UPDATE dtv_multiplex "
1853 "SET serviceversion = :VERSION "
1854 "WHERE mplexid = :MPLEXID");
1871 query.
prepare(
"SELECT serviceversion "
1872 "FROM dtv_multiplex "
1873 "WHERE mplexid = :MPLEXID");
1884 return query.
value(0).toInt();
1896 "SELECT atsc_major_chan, atsc_minor_chan "
1898 "WHERE deleted IS NULL AND "
1899 " channum = :CHANNUM AND "
1900 " sourceid = :SOURCEID");
1907 else if (query.
next())
1909 major = query.
value(0).toUInt();
1919 uint &chanid,
const QString &channum,
1920 QString &tvformat, QString &modulation,
1921 QString &freqtable, QString &freqid,
1922 int &finetune, uint64_t &frequency,
1923 QString &dtv_si_std,
int &mpeg_prog_num,
1924 uint &atsc_major,
uint &atsc_minor,
1925 uint &dvb_transportid,
uint &dvb_networkid,
1938 atsc_major = atsc_minor = mplexid = 0;
1939 dvb_networkid = dvb_transportid = 0;
1945 "SELECT finetune, freqid, tvformat, freqtable, "
1946 " commmethod, mplexid, "
1947 " atsc_major_chan, atsc_minor_chan, serviceid, "
1949 "FROM channel, videosource "
1950 "WHERE channel.deleted IS NULL AND "
1951 " videosource.sourceid = channel.sourceid AND "
1952 " channum = :CHANNUM AND "
1953 " channel.sourceid = :SOURCEID "
1954 "ORDER BY channel.visible > 0 DESC, channel.chanid ");
1966 finetune = query.
value(0).toInt();
1967 freqid = query.
value(1).toString();
1968 tvformat = query.
value(2).toString();
1969 freqtable = query.
value(3).toString();
1970 commfree = (query.
value(4).toInt() == -2);
1971 mplexid = query.
value(5).toUInt();
1972 atsc_major = query.
value(6).toUInt();
1973 atsc_minor = query.
value(7).toUInt();
1974 mpeg_prog_num = (query.
value(8).isNull()) ? -1
1975 : query.
value(8).toInt();
1976 chanid = query.
value(9).toUInt();
1982 while (query.
next())
1986 if (found == 0 && chanid)
1988 LOG(VB_GENERAL, LOG_WARNING,
1989 QString(
"No visible channels for %1, using invisble chanid %2")
1990 .arg(channum).arg(chanid));
1995 LOG(VB_GENERAL, LOG_WARNING,
1996 QString(
"Found multiple visible channels for %1, using chanid %2")
1997 .arg(channum).arg(chanid));
2002 LOG(VB_GENERAL, LOG_ERR,
2003 QString(
"Could not find channel '%1' in DB for source %2 '%3'.")
2008 if (!mplexid || (mplexid == 32767))
2012 dvb_transportid, dvb_networkid, dtv_si_std);
2019 "SELECT type+0, url, bitrate "
2020 "FROM iptv_channel "
2021 "WHERE chanid = :CHANID "
2035 std::array<uint,3> bitrate { 0, 0, 0, };
2036 while (query.
next())
2039 query.
value(0).toUInt();
2043 data_url = query.
value(1).toString();
2044 bitrate[0] = query.
value(2).toUInt();
2049 fec_url0 = query.
value(1).toString();
2050 bitrate[1] = query.
value(2).toUInt();
2055 fec_url1 = query.
value(1).toString();
2056 bitrate[2] = query.
value(2).toUInt();
2080 fec_url0, bitrate[1], fec_url1, bitrate[2]);
2081 LOG(VB_GENERAL, LOG_INFO, QString(
"Loaded %1 for %2")
2092 uint sourceid,
bool visible_only,
bool include_disconnected,
2093 const QString &group_by,
uint channel_groupid)
2099 QString qstr = QString(
2100 "SELECT videosource.sourceid, GROUP_CONCAT(capturecard.cardid) "
2102 "%1 JOIN capturecard ON capturecard.sourceid = videosource.sourceid "
2103 "GROUP BY videosource.sourceid")
2104 .arg((include_disconnected) ?
"LEFT" :
"");
2113 QMap<uint, QList<uint>> inputIdLists;
2114 while (query.
next())
2116 uint qSourceId = query.
value(0).toUInt();
2117 QList<uint> &inputIdList = inputIdLists[qSourceId];
2118 QStringList inputIds = query.
value(1).toString().split(
",");
2119 while (!inputIds.isEmpty())
2120 inputIdList.append(inputIds.takeFirst().toUInt());
2124 "SELECT channum, callsign, channel.chanid, "
2125 " atsc_major_chan, atsc_minor_chan, "
2126 " name, icon, mplexid, visible, "
2127 " channel.sourceid, "
2128 " GROUP_CONCAT(DISTINCT channelgroup.grpid), "
2131 "LEFT JOIN channelgroup ON channel.chanid = channelgroup.chanid ");
2133 qstr +=
"WHERE deleted IS NULL ";
2136 qstr += QString(
"AND channel.sourceid='%1' ").arg(sourceid);
2139 if (channel_groupid > 0)
2140 qstr += QString(
"AND channelgroup.grpid = '%1' ").arg(channel_groupid);
2143 qstr += QString(
"AND visible > 0 ");
2145 qstr +=
" GROUP BY chanid";
2147 if (!group_by.isEmpty())
2148 qstr += QString(
", %1").arg(group_by);
2157 while (query.
next())
2159 if (query.
value(0).toString().isEmpty() || !query.
value(2).toBool())
2162 uint qSourceID = query.
value(9).toUInt();
2164 query.
value(0).toString(),
2165 query.
value(1).toString(),
2166 query.
value(2).toUInt(),
2167 query.
value(3).toUInt(),
2168 query.
value(4).toUInt(),
2169 query.
value(7).toUInt(),
2172 query.
value(5).toString(),
2173 query.
value(6).toString(),
2178 for (
auto inputId : std::as_const(inputIdLists[qSourceID]))
2181 QStringList groupIDs = query.
value(10).toString().split(
",");
2182 while (!groupIDs.isEmpty())
2183 chan.
AddGroupId(groupIDs.takeFirst().toUInt());
2185 list.push_back(chan);
2196 QString select =
"SELECT chanid FROM channel WHERE deleted IS NULL ";
2198 if (onlyVisible || sourceid > 0)
2201 select +=
"AND visible > 0 ";
2203 select +=
"AND sourceid=" + QString::number(sourceid);
2206 std::vector<uint> list;
2214 while (query.
next())
2215 list.push_back(query.
value(0).toUInt());
2227 static QMutex s_sepExprLock;
2230 bool isIntA =
false;
2231 bool isIntB =
false;
2232 int a_int = a.
m_chanNum.toUInt(&isIntA);
2233 int b_int = b.
m_chanNum.toUInt(&isIntB);
2243 QMutexLocker locker(&s_sepExprLock);
2251 int major = a.
m_chanNum.left(idxA).toUInt(&tmp1);
2254 (a_major = major), (a_minor =
minor), (isIntA =
false);
2261 int major = b.
m_chanNum.left(idxB).toUInt(&tmp1);
2264 (b_major = major), (b_minor =
minor), (isIntB =
false);
2268 if ((a_minor > 0) && isIntA)
2270 int atsc_int = (QString(
"%1%2").arg(a_major).arg(a_minor)).toInt();
2271 a_minor = (atsc_int == a_int) ? a_minor : 0;
2274 if ((b_minor > 0) && isIntB)
2276 int atsc_int = (QString(
"%1%2").arg(b_major).arg(b_minor)).toInt();
2277 b_minor = (atsc_int == b_int) ? b_minor : 0;
2282 if ((a_minor || b_minor) &&
2283 (a_minor || isIntA) && (b_minor || isIntB))
2285 int a_maj = (!a_minor && isIntA) ? a_int : a_major;
2286 int b_maj = (!b_minor && isIntB) ? b_int : b_major;
2287 int cmp = a_maj - b_maj;
2291 cmp = a_minor - b_minor;
2296 if (isIntA && isIntB)
2299 int cmp = a_int - b_int;
2303 else if (isIntA ^ isIntB)
2325 select =
"SELECT chanid FROM channel WHERE deleted IS NULL ";
2327 select +=
"AND sourceid=" + QString::number(sourceid);
2335 return query.
size();
2339 bool eliminate_duplicates)
2341 bool cs = order.toLower() ==
"callsign";
2343 stable_sort(list.begin(), list.end(),
lt_callsign);
2345 stable_sort(list.begin(), list.end(),
lt_smart);
2347 if (eliminate_duplicates && !list.empty())
2350 tmp.push_back(list[0]);
2351 for (
size_t i = 1; i < list.size(); i++)
2356 tmp.push_back(list[i]);
2372 const QString &channum)
2377 for (
int i = 0; i < (int)list.size(); ++i)
2398 uint mplexid_restriction,
2399 uint chanid_restriction,
2401 bool skip_non_visible,
2402 bool skip_same_channum_and_callsign,
2403 bool skip_other_sources)
2405 auto it =
find(sorted.cbegin(), sorted.cend(), old_chanid);
2407 if (it == sorted.end())
2408 it = sorted.begin();
2410 if (it == sorted.end())
2419 if (it == sorted.begin())
2421 it =
find(sorted.begin(), sorted.end(),
2422 sorted.rbegin()->m_chanId);
2423 if (it == sorted.end())
2433 while ((it != start) &&
2435 (skip_other_sources &&
2436 it->m_sourceId != start->m_sourceId) ||
2437 (skip_same_channum_and_callsign &&
2438 it->m_chanNum == start->m_chanNum &&
2439 it->m_callSign == start->m_callSign) ||
2440 ((mplexid_restriction != 0U) &&
2441 (mplexid_restriction != it->m_mplexId)) ||
2442 ((chanid_restriction != 0U) &&
2443 (chanid_restriction != it->m_chanId))));
2451 if (it == sorted.end())
2452 it = sorted.begin();
2454 while ((it != start) &&
2456 (skip_other_sources &&
2457 it->m_sourceId != start->m_sourceId) ||
2458 (skip_same_channum_and_callsign &&
2459 it->m_chanNum == start->m_chanNum &&
2460 it->m_callSign == start->m_callSign) ||
2461 ((mplexid_restriction != 0U) &&
2462 (mplexid_restriction != it->m_mplexId)) ||
2463 ((chanid_restriction != 0U) &&
2464 (chanid_restriction != it->m_chanId))));
2467 return it->m_chanId;
2471 uint &totalAvailable,
2476 uint channelGroupID,
2478 const QString& callsign,
2479 const QString& channum,
2480 bool ignoreUntunable)
2486 QString sql = QString(
2487 "SELECT parentid, GROUP_CONCAT(cardid ORDER BY cardid) "
2489 "WHERE parentid <> 0 "
2490 "GROUP BY parentid ");
2499 QMap<uint, QList<uint>> childIdLists;
2500 while (query.
next())
2502 auto parentId = query.
value(0).toUInt();
2503 auto &childIdList = childIdLists[parentId];
2504 auto childIds = query.
value(1).toString().split(
",");
2505 while (!childIds.isEmpty())
2506 childIdList.append(childIds.takeFirst().toUInt());
2509 sql =
"SELECT %1 channum, freqid, channel.sourceid, "
2510 "callsign, name, icon, finetune, videofilters, xmltvid, "
2511 "channel.recpriority, channel.contrast, channel.brightness, "
2512 "channel.colour, channel.hue, tvformat, "
2513 "visible, outputfilters, useonairguide, mplexid, "
2514 "serviceid, atsc_major_chan, atsc_minor_chan, last_record, "
2515 "default_authority, commmethod, tmoffset, iptvid, "
2517 "GROUP_CONCAT(DISTINCT `groups`.`groupids`), "
2518 "GROUP_CONCAT(DISTINCT capturecard.cardid "
2519 " ORDER BY livetvorder), "
2520 "MIN(livetvorder) livetvorder "
2522 if (!channelGroupID)
2526 " GROUP_CONCAT(grpid ORDER BY grpid) groupids "
2527 " FROM channelgroup ";
2529 sql +=
" WHERE grpid = :CHANGROUPID ";
2530 sql +=
" GROUP BY chanid "
2532 " ON channel.chanid = `groups`.`chanid` ";
2533 if (!ignoreUntunable && !liveTVOnly)
2535 sql +=
"JOIN capturecard "
2536 " ON capturecard.sourceid = channel.sourceid "
2537 " AND capturecard.parentid = 0 ";
2539 sql +=
" AND capturecard.livetvorder > 0 ";
2541 sql +=
"WHERE channel.deleted IS NULL ";
2543 sql +=
"AND channel.visible > 0 ";
2546 sql +=
"AND channel.sourceid = :SOURCEID ";
2549 sql +=
"GROUP BY channel.callsign ";
2551 sql +=
"GROUP BY channel.callsign, channel.channum ";
2553 sql +=
"GROUP BY channel.chanid ";
2556 sql +=
"ORDER BY channel.name ";
2560 sql +=
"ORDER BY LPAD(CAST(channel.channum AS UNSIGNED), 10, 0), "
2561 " LPAD(channel.channum, 10, 0) ";
2565 sql +=
"ORDER BY callsign = :CALLSIGN1 AND channum = :CHANNUM DESC, "
2566 " callsign = :CALLSIGN2 DESC, "
2568 " channel.recpriority DESC, "
2573 sql +=
"LIMIT :LIMIT ";
2576 sql +=
"OFFSET :STARTINDEX ";
2579 if (startIndex > 0 || count > 0)
2580 sql = sql.arg(
"SQL_CALC_FOUND_ROWS");
2586 if (channelGroupID > 0)
2587 query.
bindValue(
":CHANGROUPID", channelGroupID);
2596 query.
bindValue(
":STARTINDEX", startIndex);
2600 query.
bindValue(
":CALLSIGN1", callsign);
2602 query.
bindValue(
":CALLSIGN2", callsign);
2611 QList<uint> groupIdList;
2612 while (query.
next())
2628 channelInfo.
m_hue = query.
value(13).toUInt();
2645 QStringList groupIDs = query.
value(28).toString().split(
",");
2646 groupIdList.clear();
2647 while (!groupIDs.isEmpty())
2648 groupIdList.push_back(groupIDs.takeFirst().toUInt());
2649 std::sort(groupIdList.begin(), groupIdList.end());
2650 for (
auto groupId : groupIdList)
2653 QStringList parentIDs = query.
value(29).toString().split(
",");
2654 while (!parentIDs.isEmpty())
2656 auto parentId = parentIDs.takeFirst().toUInt();
2658 auto childIdList = childIdLists[parentId];
2659 for (
auto childId : childIdList)
2663 channelList.push_back(channelInfo);
2666 if ((startIndex > 0 || count > 0) &&
2667 query.
exec(
"SELECT FOUND_ROWS()") && query.
next())
2668 totalAvailable = query.
value(0).toUInt();
2670 totalAvailable = query.
size();
std::vector< ChannelInfo > ChannelInfoList
static bool lt_pidcache(const pid_cache_item_t a, const pid_cache_item_t b)
static uint get_dtv_multiplex(uint db_source_id, const QString &sistandard, uint64_t frequency, uint transport_id, uint network_id, signed char polarity)
static void handle_transport_desc(std::vector< uint > &muxes, const MPEGDescriptor &desc, uint sourceid, uint tsid, uint netid)
static bool chanid_available(uint chanid)
bool lt_callsign(const ChannelInfo &a, const ChannelInfo &b)
bool lt_smart(const ChannelInfo &a, const ChannelInfo &b)
static QStringList get_valid_recorder_list(uint chanid)
Returns list of the recorders that have chanid in their sources.
static uint insert_dtv_multiplex(int db_source_id, const QString &sistandard, uint64_t frequency, const QString &modulation, int transport_id, int network_id, int symbol_rate, signed char bandwidth, signed char polarity, signed char inversion, signed char trans_mode, const QString &inner_FEC, const QString &constellation, signed char hierarchy, const QString &hp_code_rate, const QString &lp_code_rate, const QString &guard_interval, const QString &mod_sys, const QString &rolloff)
static uint get_max_chanid(uint sourceid)
std::vector< pid_cache_item_t > pid_cache_t
unsigned long long FrequencyHz(void) const
QString ModulationString(void) const
QString FECInnerString(void) const
uint SymbolRateHz(void) const
ChannelVisibleType m_visible
void AddGroupId(uint lgroupid)
void AddInputId(uint linputid)
QString m_defaultAuthority
ChannelVisibleType m_visible
static std::vector< uint > GetChanIDs(int sourceid=-1, bool onlyVisible=false)
static QStringList GetValidRecorderList(uint chanid, const QString &channum)
Returns list of the recorders that have chanid or channum in their sources.
static bool s_channelDefaultAuthority_runInit
static uint GetMplexID(uint sourceid, const QString &channum)
static int GetChanID(int db_mplexid, int service_transport_id, int major_channel, int minor_channel, int program_number)
static QMap< uint, QString > s_channelDefaultAuthorityMap
static QStringList GetInputTypes(uint chanid)
static QString GetChannelNumber(uint sourceid, const QString &channel_name)
static QReadWriteLock s_channelDefaultAuthorityMapLock
static bool DeleteChannel(uint channel_id)
static bool GetCachedPids(uint chanid, pid_cache_t &pid_cache)
Returns cached MPEG PIDs when given a Channel ID.
static QString GetIcon(uint chanid)
static int GetBetterMplexID(int current_mplexid, int transport_id, int network_id)
Returns best match multiplex ID, creating one if needed.
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
static int GetServiceVersion(int mplexid)
static int GetSourceID(int mplexid)
static QString GetChannelValueStr(const QString &channel_field, uint sourceid, const QString &channum)
static const QString kATSCSeparators
static bool UpdateIPTVTuningData(uint channel_id, const IPTVTuningData &tuning)
static bool SaveCachedPids(uint chanid, const pid_cache_t &_pid_cache, bool delete_all=false)
Saves PIDs for PSIP tables to database.
static bool UpdateChannel(uint db_mplexid, uint source_id, uint 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=QString(), const QString &icon=QString(), QString format=QString(), const QString &xmltvid=QString(), const QString &default_authority=QString(), uint service_type=0, int recpriority=INT_MIN, int tmOffset=INT_MIN, int commMethod=INT_MIN)
static uint CreateMultiplex(int sourceid, const QString &sistandard, uint64_t frequency, const QString &modulation, int transport_id=-1, int network_id=-1)
static bool IsOnSameMultiplex(uint srcid, const QString &new_channum, const QString &old_channum)
static std::vector< uint > CreateMultiplexes(int sourceid, const NetworkInformationTable *nit)
static std::chrono::minutes GetTimeOffset(int chan_id)
Returns the listings time offset in minutes for given channel.
static bool SetVisible(uint channel_id, ChannelVisibleType visible)
static bool SetChannelValue(const QString &field_name, const QString &value, uint sourceid, const QString &channum)
static int GetChannelValueInt(const QString &channel_field, uint sourceid, const QString &channum)
static bool GetChannelData(uint sourceid, uint &chanid, const QString &channum, QString &tvformat, QString &modulation, QString &freqtable, QString &freqid, int &finetune, uint64_t &frequency, QString &dtv_si_std, int &mpeg_prog_num, uint &atsc_major, uint &atsc_minor, uint &dvb_transportid, uint &dvb_networkid, uint &mplexid, bool &commfree)
static int GetNearestChannel(const ChannelInfoList &list, const QString &channum)
static QString GetDefaultAuthority(uint chanid)
Returns the DVB default authority for the chanid given.
static QString GetChannelStringField(int chan_id, const QString &field)
@ kChanGroupByCallsignAndChannum
static std::vector< uint > GetConflicting(const QString &channum, uint sourceid=0)
static uint GetNextChannel(const ChannelInfoList &sorted, uint old_chanid, uint mplexid_restriction, uint chanid_restriction, ChannelChangeDirection direction, bool skip_non_visible=true, bool skip_same_channum_and_callsign=false, bool skip_other_sources=false)
static uint GetChannelCount(int sourceid=-1)
static int CreateChanID(uint sourceid, const QString &chan_num)
Creates a unique channel ID for database use.
static QString GetChanNum(int chan_id)
Returns the channel-number string of the given channel.
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 ChannelInfoList GetChannelsInternal(uint sourceid, bool visible_only, bool include_disconnected, const QString &group_by, uint channel_groupid)
static bool GetTuningParams(uint mplexid, QString &modulation, uint64_t &frequency, uint &dvb_transportid, uint &dvb_networkid, QString &si_std)
static ChannelInfoList LoadChannels(uint startIndex, uint count, uint &totalAvailable, bool ignoreHidden=true, OrderBy orderBy=kChanOrderByChanNum, GroupBy groupBy=kChanGroupByChanid, uint sourceID=0, uint channelGroupID=0, bool liveTVOnly=false, const QString &callsign="", const QString &channum="", bool ignoreUntunable=true)
Load channels from database into a list of ChannelInfo objects.
static IPTVTuningData GetIPTVTuningData(uint chanid)
static void UpdateChannelNumberFromDB(ChannelInsertInfo &chan)
static QString GetUnknownCallsign(void)
static void UpdateInsertInfoFromDB(ChannelInsertInfo &chan)
static bool SetServiceVersion(int mplexid, int version)
static uint FindChannel(uint sourceid, const QString &freqid)
static uint GetSourceIDForChannel(uint chanid)
static bool GetATSCChannel(uint sourceid, const QString &channum, uint &major, uint &minor)
DTVTransmitMode m_transMode
DTVModulation m_modulation
DTVModulationSystem m_modSys
DTVGuardInterval m_guardInterval
@ satellite_delivery_system
@ terrestrial_delivery_system
QString GetFECTypeString(uint i) const
QUrl GetDataURL(void) const
QUrl GetFECURL0(void) const
QUrl GetFECURL1(void) const
uint GetBitrate(uint i) const
QString GetDeviceName(void) const
static desc_list_t Parse(const unsigned char *data, uint len)
uint DescriptorTag(void) const
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
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
static MSqlQueryInfo ChannelCon()
Returns dedicated connection. (Required for using temporary SQL tables.)
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.
static void DBError(const QString &where, const MSqlQuery &query)
uint64_t FrequencykHz(void) const
uint SymbolRateHz(void) const
QString FECInnerString(void) const
QString ModulationString(void) const
QString PolarizationString() const
QString RollOffString(void) const
QString ModulationSystemString(void) const
static QString GetSourceName(uint sourceid)
QString HierarchyString(void) const
QString CodeRateHPString(void) const
QString CodeRateLPString(void) const
uint64_t FrequencyHz(void) const
QString GuardIntervalString(void) const
QString ConstellationString(void) const
QString TransmissionModeString(void) const
QString BandwidthString(void) const
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
static const std::array< const uint32_t, 4 > freq
std::vector< const unsigned char * > desc_list_t
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MBASE_PUBLIC int naturalCompare(const QString &_a, const QString &_b, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
This method chops the input a and b into pieces of digits and non-digits (a1.05 becomes a | 1 | .
ChannelChangeDirection
ChannelChangeDirection is an enumeration of possible channel changing directions.
@ CHANNEL_DIRECTION_FAVORITE