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 &name, QString &callsign,
1921 QString &tvformat, QString &modulation,
1922 QString &freqtable, QString &freqid,
1923 int &finetune, uint64_t &frequency,
1924 QString &dtv_si_std,
int &mpeg_prog_num,
1925 uint &atsc_major,
uint &atsc_minor,
1926 uint &dvb_transportid,
uint &dvb_networkid,
1939 atsc_major = atsc_minor = mplexid = 0;
1940 dvb_networkid = dvb_transportid = 0;
1946 "SELECT finetune, freqid, tvformat, freqtable, "
1947 " commmethod, mplexid, "
1948 " atsc_major_chan, atsc_minor_chan, serviceid, "
1949 " chanid, channel.name, callsign, visible "
1950 "FROM channel, videosource "
1951 "WHERE channel.deleted IS NULL AND "
1952 " videosource.sourceid = channel.sourceid AND "
1953 " channum = :CHANNUM AND "
1954 " channel.sourceid = :SOURCEID "
1955 "ORDER BY channel.visible > 0 DESC, channel.chanid ");
1967 finetune = query.
value(0).toInt();
1968 freqid = query.
value(1).toString();
1969 tvformat = query.
value(2).toString();
1970 freqtable = query.
value(3).toString();
1971 commfree = (query.
value(4).toInt() == -2);
1972 mplexid = query.
value(5).toUInt();
1973 atsc_major = query.
value(6).toUInt();
1974 atsc_minor = query.
value(7).toUInt();
1975 mpeg_prog_num = (query.
value(8).isNull()) ? -1
1976 : query.
value(8).toInt();
1977 chanid = query.
value(9).toUInt();
1978 name = query.
value(10).toString();
1979 callsign = query.
value(11).toString();
1985 while (query.
next())
1989 if (found == 0 && chanid)
1991 LOG(VB_GENERAL, LOG_WARNING,
1992 QString(
"No visible channels for %1, using invisble chanid %2")
1993 .arg(channum).arg(chanid));
1998 LOG(VB_GENERAL, LOG_WARNING,
1999 QString(
"Found multiple visible channels for %1, using chanid %2")
2000 .arg(channum).arg(chanid));
2005 LOG(VB_GENERAL, LOG_ERR,
2006 QString(
"Could not find channel '%1' in DB for source %2 '%3'.")
2011 if (!mplexid || (mplexid == 32767))
2015 dvb_transportid, dvb_networkid, dtv_si_std);
2022 "SELECT type+0, url, bitrate "
2023 "FROM iptv_channel "
2024 "WHERE chanid = :CHANID "
2038 std::array<uint,3> bitrate { 0, 0, 0, };
2039 while (query.
next())
2042 query.
value(0).toUInt();
2046 data_url = query.
value(1).toString();
2047 bitrate[0] = query.
value(2).toUInt();
2052 fec_url0 = query.
value(1).toString();
2053 bitrate[1] = query.
value(2).toUInt();
2058 fec_url1 = query.
value(1).toString();
2059 bitrate[2] = query.
value(2).toUInt();
2083 fec_url0, bitrate[1], fec_url1, bitrate[2]);
2084 LOG(VB_GENERAL, LOG_INFO, QString(
"Loaded %1 for %2")
2095 uint sourceid,
bool visible_only,
bool include_disconnected,
2096 const QString &group_by,
uint channel_groupid)
2102 QString qstr = QString(
2103 "SELECT videosource.sourceid, GROUP_CONCAT(capturecard.cardid) "
2105 "%1 JOIN capturecard ON capturecard.sourceid = videosource.sourceid "
2106 "GROUP BY videosource.sourceid")
2107 .arg((include_disconnected) ?
"LEFT" :
"");
2116 QMap<uint, QList<uint>> inputIdLists;
2117 while (query.
next())
2119 uint qSourceId = query.
value(0).toUInt();
2120 QList<uint> &inputIdList = inputIdLists[qSourceId];
2121 QStringList inputIds = query.
value(1).toString().split(
",");
2122 while (!inputIds.isEmpty())
2123 inputIdList.append(inputIds.takeFirst().toUInt());
2127 "SELECT channum, callsign, channel.chanid, "
2128 " atsc_major_chan, atsc_minor_chan, "
2129 " name, icon, mplexid, visible, "
2130 " channel.sourceid, "
2131 " GROUP_CONCAT(DISTINCT channelgroup.grpid), "
2134 "LEFT JOIN channelgroup ON channel.chanid = channelgroup.chanid ");
2136 qstr +=
"WHERE deleted IS NULL ";
2139 qstr += QString(
"AND channel.sourceid='%1' ").arg(sourceid);
2142 if (channel_groupid > 0)
2143 qstr += QString(
"AND channelgroup.grpid = '%1' ").arg(channel_groupid);
2146 qstr += QString(
"AND visible > 0 ");
2148 qstr +=
" GROUP BY chanid";
2150 if (!group_by.isEmpty())
2151 qstr += QString(
", %1").arg(group_by);
2160 while (query.
next())
2162 if (query.
value(0).toString().isEmpty() || !query.
value(2).toBool())
2165 uint qSourceID = query.
value(9).toUInt();
2167 query.
value(0).toString(),
2168 query.
value(1).toString(),
2169 query.
value(2).toUInt(),
2170 query.
value(3).toUInt(),
2171 query.
value(4).toUInt(),
2172 query.
value(7).toUInt(),
2175 query.
value(5).toString(),
2176 query.
value(6).toString(),
2181 for (
auto inputId : std::as_const(inputIdLists[qSourceID]))
2184 QStringList groupIDs = query.
value(10).toString().split(
",");
2185 while (!groupIDs.isEmpty())
2186 chan.
AddGroupId(groupIDs.takeFirst().toUInt());
2188 list.push_back(chan);
2199 QString select =
"SELECT chanid FROM channel WHERE deleted IS NULL ";
2201 if (onlyVisible || sourceid > 0)
2204 select +=
"AND visible > 0 ";
2206 select +=
"AND sourceid=" + QString::number(sourceid);
2209 std::vector<uint> list;
2217 while (query.
next())
2218 list.push_back(query.
value(0).toUInt());
2230 static QMutex s_sepExprLock;
2233 bool isIntA =
false;
2234 bool isIntB =
false;
2235 int a_int = a.
m_chanNum.toUInt(&isIntA);
2236 int b_int = b.
m_chanNum.toUInt(&isIntB);
2246 QMutexLocker locker(&s_sepExprLock);
2254 int major = a.
m_chanNum.left(idxA).toUInt(&tmp1);
2257 (a_major = major), (a_minor =
minor), (isIntA =
false);
2264 int major = b.
m_chanNum.left(idxB).toUInt(&tmp1);
2267 (b_major = major), (b_minor =
minor), (isIntB =
false);
2271 if ((a_minor > 0) && isIntA)
2273 int atsc_int = (QString(
"%1%2").arg(a_major).arg(a_minor)).toInt();
2274 a_minor = (atsc_int == a_int) ? a_minor : 0;
2277 if ((b_minor > 0) && isIntB)
2279 int atsc_int = (QString(
"%1%2").arg(b_major).arg(b_minor)).toInt();
2280 b_minor = (atsc_int == b_int) ? b_minor : 0;
2285 if ((a_minor || b_minor) &&
2286 (a_minor || isIntA) && (b_minor || isIntB))
2288 int a_maj = (!a_minor && isIntA) ? a_int : a_major;
2289 int b_maj = (!b_minor && isIntB) ? b_int : b_major;
2290 int cmp = a_maj - b_maj;
2294 cmp = a_minor - b_minor;
2299 if (isIntA && isIntB)
2302 int cmp = a_int - b_int;
2306 else if (isIntA ^ isIntB)
2328 select =
"SELECT chanid FROM channel WHERE deleted IS NULL ";
2330 select +=
"AND sourceid=" + QString::number(sourceid);
2338 return query.
size();
2342 bool eliminate_duplicates)
2344 bool cs = order.toLower() ==
"callsign";
2346 stable_sort(list.begin(), list.end(),
lt_callsign);
2348 stable_sort(list.begin(), list.end(),
lt_smart);
2350 if (eliminate_duplicates && !list.empty())
2353 tmp.push_back(list[0]);
2354 for (
size_t i = 1; i < list.size(); i++)
2357 (!cs &&
lt_smart(tmp.back(), list[i])))
2359 tmp.push_back(list[i]);
2375 const QString &channum)
2380 for (
int i = 0; i < (int)list.size(); ++i)
2401 uint mplexid_restriction,
2402 uint chanid_restriction,
2404 bool skip_non_visible,
2405 bool skip_same_channum_and_callsign,
2406 bool skip_other_sources)
2408 auto it =
find(sorted.cbegin(), sorted.cend(), old_chanid);
2410 if (it == sorted.end())
2411 it = sorted.begin();
2413 if (it == sorted.end())
2422 if (it == sorted.begin())
2424 it =
find(sorted.begin(), sorted.end(),
2425 sorted.rbegin()->m_chanId);
2426 if (it == sorted.end())
2436 while ((it != start) &&
2438 (skip_other_sources &&
2439 it->m_sourceId != start->m_sourceId) ||
2440 (skip_same_channum_and_callsign &&
2441 it->m_chanNum == start->m_chanNum &&
2442 it->m_callSign == start->m_callSign) ||
2443 ((mplexid_restriction != 0U) &&
2444 (mplexid_restriction != it->m_mplexId)) ||
2445 ((chanid_restriction != 0U) &&
2446 (chanid_restriction != it->m_chanId))));
2454 if (it == sorted.end())
2455 it = sorted.begin();
2457 while ((it != start) &&
2459 (skip_other_sources &&
2460 it->m_sourceId != start->m_sourceId) ||
2461 (skip_same_channum_and_callsign &&
2462 it->m_chanNum == start->m_chanNum &&
2463 it->m_callSign == start->m_callSign) ||
2464 ((mplexid_restriction != 0U) &&
2465 (mplexid_restriction != it->m_mplexId)) ||
2466 ((chanid_restriction != 0U) &&
2467 (chanid_restriction != it->m_chanId))));
2470 return it->m_chanId;
2474 uint &totalAvailable,
2479 uint channelGroupID,
2481 const QString& callsign,
2482 const QString& channum,
2483 bool ignoreUntunable)
2489 QString sql = QString(
2490 "SELECT parentid, GROUP_CONCAT(cardid ORDER BY cardid) "
2492 "WHERE parentid <> 0 "
2493 "GROUP BY parentid ");
2502 QMap<uint, QList<uint>> childIdLists;
2503 while (query.
next())
2505 auto parentId = query.
value(0).toUInt();
2506 auto &childIdList = childIdLists[parentId];
2507 auto childIds = query.
value(1).toString().split(
",");
2508 while (!childIds.isEmpty())
2509 childIdList.append(childIds.takeFirst().toUInt());
2512 sql =
"SELECT %1 channum, freqid, channel.sourceid, "
2513 "callsign, name, icon, finetune, videofilters, xmltvid, "
2514 "channel.recpriority, channel.contrast, channel.brightness, "
2515 "channel.colour, channel.hue, tvformat, "
2516 "visible, outputfilters, useonairguide, mplexid, "
2517 "serviceid, atsc_major_chan, atsc_minor_chan, last_record, "
2518 "default_authority, commmethod, tmoffset, iptvid, "
2520 "GROUP_CONCAT(DISTINCT `groups`.`groupids`), "
2521 "GROUP_CONCAT(DISTINCT capturecard.cardid "
2522 " ORDER BY livetvorder), "
2523 "MIN(livetvorder) livetvorder "
2525 if (!channelGroupID)
2529 " GROUP_CONCAT(grpid ORDER BY grpid) groupids "
2530 " FROM channelgroup ";
2532 sql +=
" WHERE grpid = :CHANGROUPID ";
2533 sql +=
" GROUP BY chanid "
2535 " ON channel.chanid = `groups`.`chanid` ";
2536 if (!ignoreUntunable && !liveTVOnly)
2538 sql +=
"JOIN capturecard "
2539 " ON capturecard.sourceid = channel.sourceid "
2540 " AND capturecard.parentid = 0 ";
2542 sql +=
" AND capturecard.livetvorder > 0 ";
2544 sql +=
"WHERE channel.deleted IS NULL ";
2546 sql +=
"AND channel.visible > 0 ";
2549 sql +=
"AND channel.sourceid = :SOURCEID ";
2552 sql +=
"GROUP BY channel.callsign ";
2554 sql +=
"GROUP BY channel.callsign, channel.channum ";
2556 sql +=
"GROUP BY channel.chanid ";
2559 sql +=
"ORDER BY channel.name ";
2563 sql +=
"ORDER BY LPAD(CAST(channel.channum AS UNSIGNED), 10, 0), "
2564 " LPAD(channel.channum, 10, 0) ";
2568 sql +=
"ORDER BY callsign = :CALLSIGN1 AND channum = :CHANNUM DESC, "
2569 " callsign = :CALLSIGN2 DESC, "
2571 " channel.recpriority DESC, "
2576 sql +=
"LIMIT :LIMIT ";
2579 sql +=
"OFFSET :STARTINDEX ";
2582 if (startIndex > 0 || count > 0)
2583 sql = sql.arg(
"SQL_CALC_FOUND_ROWS");
2589 if (channelGroupID > 0)
2590 query.
bindValue(
":CHANGROUPID", channelGroupID);
2599 query.
bindValue(
":STARTINDEX", startIndex);
2603 query.
bindValue(
":CALLSIGN1", callsign);
2605 query.
bindValue(
":CALLSIGN2", callsign);
2614 QList<uint> groupIdList;
2615 while (query.
next())
2631 channelInfo.
m_hue = query.
value(13).toUInt();
2648 QStringList groupIDs = query.
value(28).toString().split(
",");
2649 groupIdList.clear();
2650 while (!groupIDs.isEmpty())
2651 groupIdList.push_back(groupIDs.takeFirst().toUInt());
2652 std::sort(groupIdList.begin(), groupIdList.end());
2653 for (
auto groupId : groupIdList)
2656 QStringList parentIDs = query.
value(29).toString().split(
",");
2657 while (!parentIDs.isEmpty())
2659 auto parentId = parentIDs.takeFirst().toUInt();
2661 auto childIdList = childIdLists[parentId];
2662 for (
auto childId : childIdList)
2666 channelList.push_back(channelInfo);
2669 if ((startIndex > 0 || count > 0) &&
2670 query.
exec(
"SELECT FOUND_ROWS()") && query.
next())
2671 totalAvailable = query.
value(0).toUInt();
2673 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 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)
static bool GetChannelData(uint sourceid, uint &chanid, const QString &channum, QString &name, QString &callsign, 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)
@ 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