4#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
5#include <QtSystemDetection>
11#if defined(Q_OS_BSD4) || defined(Q_OS_WINDOWS)
14#include <sys/sysmacros.h>
22#include <QCoreApplication>
36#include "libmythbase/mythconfig.h"
66#include HDHOMERUN_HEADERFILE
71 bool _must_have_mplexid) :
72 m_initialSourceId(_initial_sourceid),
73 m_cardTypes(
std::move(_card_types)),
74 m_mustHaveMplexId(_must_have_mplexid)
79 "Select a video source that is connected to one "
80 "or more capture cards. Default is the video source "
81 "selected in the Channel Editor page."
90 "SELECT DISTINCT videosource.name, videosource.sourceid "
91 "FROM capturecard, videosource";
96 "WHERE capturecard.sourceid = videosource.sourceid AND "
97 " capturecard.hostname = :HOSTNAME ";
101 querystr += QString(
" AND capturecard.cardtype in %1 ")
108 " AND channel.sourceid = videosource.sourceid "
109 " AND channel.mplexid != 32767 "
110 " AND channel.mplexid != 0 ";
121 for (; query.
next(); cnt++)
124 query.
value(1).toString());
139 m_initialSourceId(_initial_sourceid)
144 "The video source that is "
145 "selected in the Channel Editor page."
154 "SELECT DISTINCT videosource.name, videosource.sourceid "
155 "FROM capturecard, videosource "
156 "WHERE capturecard.sourceid = videosource.sourceid AND "
157 " capturecard.hostname = :HOSTNAME AND "
158 " videosource.sourceid = :SOURCEID ";
183 setLabel(QObject::tr(
"Max recordings"));
187 "Maximum number of simultaneous recordings MythTV will "
188 "attempt using this device. If set to a value other than "
189 "1, MythTV can sometimes record multiple programs on "
190 "the same multiplex or overlapping copies of the same "
191 "program on a single channel."
207 setLabel(QObject::tr(
"Schedule as group"));
211 "Schedule all virtual inputs on this device as a group. "
212 "This is more efficient than scheduling each input "
213 "individually. Additional, virtual inputs will be "
214 "automatically added as needed to fulfill the recording "
227 QString sourceidTag(
":WHERESOURCEID");
229 QString query(
"sourceid = " + sourceidTag);
238 QString sourceidTag(
":SETSOURCEID");
241 QString query(
"sourceid = " + sourceidTag +
", " +
252 QString cardidTag(
":WHERECARDID");
254 QString query(
"cardid = " + cardidTag);
263 QString cardidTag(
":SETCARDID");
266 QString query(
"cardid = " + cardidTag +
", " +
283 setLabel(QObject::tr(
"Listings grabber"));
297 QObject::tr(
"Transmitted guide only (EIT)"),
"eitonly");
309 QMutexLocker lock(&
m_lock);
317 find_grabber_proc.
Run(25s);
318 LOG(VB_GENERAL, LOG_INFO,
319 loc +
"Running 'tv_find_grabbers " +
args.join(
" ") +
"'.");
320 uint status = find_grabber_proc.
Wait();
324 QTextStream ostream(find_grabber_proc.
ReadAll());
325 while (!ostream.atEnd())
327 QString grabber_list(ostream.readLine());
328 QStringList grabber_split =
329 grabber_list.split(
"|", Qt::SkipEmptyParts);
330 QString grabber_name = grabber_split[1] +
" (xmltv)";
331 QFileInfo grabber_file(grabber_split[0]);
334 m_progList.push_back(grabber_file.fileName());
335 LOG(VB_GENERAL, LOG_DEBUG,
"Found " + grabber_split[0]);
337 LOG(VB_GENERAL, LOG_INFO, loc +
"Finished running tv_find_grabbers");
341 LOG(VB_GENERAL, LOG_ERR, loc +
"Failed to run tv_find_grabbers");
346 LOG(VB_GENERAL, LOG_INFO, loc +
"Loading results of tv_find_grabbers");
359 "UPDATE videosource "
360 "SET userid=NULL, password=NULL "
361 "WHERE xmltvgrabber NOT IN ( 'technovera' )");
368 if (name_list.size() != prog_list.size())
375 for (
uint i = 0; i < (
uint) name_list.size(); i++)
383 if (!selValue.isEmpty())
406 std::chrono::milliseconds min_val,
407 std::chrono::milliseconds max_val,
408 std::chrono::milliseconds step,
409 const QString &setting) :
411 min_val.count(), max_val.count(), step.count())
423 template<typename T, typename = std::enable_if_t<!std::is_integral<T>()>>
425 {
setValueMs(duration_cast<std::chrono::milliseconds>(newSecs)); }
432 const QString &setting) :
449 setLabel(QObject::tr(
"Scan Frequency"));
450 setHelpText(QObject::tr(
"The frequency to start scanning this video source. "
451 "This is then default for 'Full Scan (Tuned)' channel scanning. "
452 "Frequency value in Hz for DVB-T/T2/C, in kHz for DVB-S/S2. "
453 "Leave at 0 if not known. "));
469 setLabel(QObject::tr(
"Network ID"));
472 setHelpText(QObject::tr(
"If your provider has asked you to configure a "
473 "specific network identifier (Network_ID), "
474 "enter it here. Leave it at -1 otherwise."));
491 setLabel(QObject::tr(
"Bouquet ID"));
492 setHelpText(QObject::tr(
"Bouquet ID for Freesat or Sky on satellite Astra-2 28.2E. "
493 "Leave this at 0 if you do not receive this satellite. "
494 "This is needed to get the Freesat and Sky channel numbers. "
495 "Value 272 selects Freesat bouquet 'England HD'. "
496 "See the MythTV Wiki https://www.mythtv.org/wiki/DVB_UK."));
514 setHelpText(QObject::tr(
"Region ID for Freesat or Sky on satellite Astra-2 28.2E. "
515 "Leave this at 0 you do not receive this satellite. "
516 "This is needed to get the Freesat and Sky channel numbers. "
517 "Value 1 selects region London. "
518 "See the MythTV Wiki https://www.mythtv.org/wiki/DVB_UK."));
535 setLabel(QObject::tr(
"Logical Channel Number Offset"));
536 setHelpText(QObject::tr(
"The offset is added to each logical channel number found "
537 "during a scan of a DVB video source. This makes it possible "
538 "to give different video sources a non-overlapping range "
539 "of channel numbers. Leave at 0 if you have only one video source "
540 "or if the video sources do not have DVB logical channel numbers."));
553 setLabel(QObject::tr(
"Channel frequency table"));
559 setHelpText(QObject::tr(
"Use default unless this source uses a "
560 "different frequency table than the system wide table "
561 "defined in the General settings."));
570 m_sourceId(_sourceid)
572 setLabel(QObject::tr(
"Channel frequency table"));
591 "WHERE sourceid = :SOURCEID");
617 LOG(VB_GENERAL, LOG_INFO,
"TransFreqTableSelector::Save(void)");
628 "UPDATE videosource "
629 "SET freqtable = :FREQTABLE "
630 "WHERE sourceid = :SOURCEID");
654 setLabel(QObject::tr(
"Perform EIT scan"));
656 "If enabled, program guide data for channels on this "
657 "source will be updated with data provided by the "
658 "channels themselves 'Over-the-Air'."));
668 const QString& _grabber,
670 m_parent(_parent), m_grabber(_grabber)
674 QString
filename = QString(
"%1/%2.xmltv")
684 config->setHelpText(tr(
"Run XMLTV configure command."));
695 QString err_msg = QObject::tr(
696 "You MUST run 'mythfilldatabase --manual' the first time,\n"
697 "instead of just 'mythfilldatabase'.\nYour grabber does not provide "
698 "channel numbers, so you have to set them manually.");
702 LOG(VB_GENERAL, LOG_ERR, err_msg);
721 : m_useEit(new
UseEIT(_parent))
730 label->setValue(QObject::tr(
"Use only the transmitted guide data."));
732 QObject::tr(
"This will usually only work with ATSC or DVB channels, "
733 "and generally provides data only for the next few days."));
745 : m_useEit(new
UseEIT(_parent))
752 label->setValue(QObject::tr(
"Do not configure a grabber"));
768 setLabel(QObject::tr(
"Video Source Setup"));
790 const QString &thecardtype)
793 query.
prepare(
"SELECT count(cardtype)"
795 " WHERE capturecard.sourceid = :SOURCEID "
796 " AND capturecard.cardtype = :CARDTYPE ;");
798 query.
bindValue(
":CARDTYPE", thecardtype);
802 int count = query.
value(0).toInt();
814 result.
prepare(
"SELECT name, sourceid FROM videosource;");
818 while (result.
next())
821 source->setLabel(result.
value(0).toString());
822 source->loadByID(result.
value(1).toInt());
831 result.
prepare(
"SELECT name, sourceid FROM videosource;");
835 while (result.
next())
838 result.
value(1).toString());
853 uint minor_max = UINT_MAX,
854 const QString& card = QString(),
855 const QRegularExpression& driver = QRegularExpression()) :
858 setLabel(QObject::tr(
"Video device"));
861 QDir dev(
"/dev/v4l",
"video*", QDir::Name, QDir::System);
863 card, driver,
false);
868 card, driver,
false);
871 dev.setPath(
"/dev/dtv");
873 card, driver,
false);
877 dev.setNameFilters(QStringList(
"dtv*"));
879 card, driver,
false);
887 [[maybe_unused]]
bool absPath =
true)
894 const QString& card,
const QRegularExpression& driver,
895 bool allow_duplicates)
898 QFileInfoList entries = dir.entryInfoList();
899 for (
const auto & fi : std::as_const(entries))
902 QString filepath = fi.absoluteFilePath();
903 int err =
lstat(filepath.toLocal8Bit().constData(), &st);
907 LOG(VB_GENERAL, LOG_ERR,
908 QString(
"Could not stat file: %1").arg(filepath));
913 if (!S_ISCHR(st.st_mode))
918 if (minor_min > minor_num || minor_max < minor_num)
926 QByteArray tmp = filepath.toLatin1();
927 int videofd = open(tmp.constData(), O_RDWR);
934 auto match = driver.match(driver_name);
935 if ((!driver.pattern().isEmpty() || match.hasMatch()) &&
936 (card.isEmpty() || (card_name == card)))
968 setLabel(QObject::tr(
"VBI device"));
970 setHelpText(QObject::tr(
"Device to read VBI (captions) from."));
976 QDir dev(
"/dev/v4l",
"vbi*", QDir::Name, QDir::System);
982 if ((count == 0U) && !
getValue().isEmpty())
996 [[maybe_unused]]
bool absPath =
true)
1002 const QString &driver)
1004 QStringList devices;
1005 QFileInfoList entries = dir.entryInfoList();
1006 for (
const auto & fi : std::as_const(entries))
1008 QString device = fi.absoluteFilePath();
1009 QByteArray adevice = device.toLatin1();
1010 int vbifd = open(adevice.constData(), O_RDWR);
1017 (driver.isEmpty() || (dn == driver)) &&
1018 (card.isEmpty() || (cn == card)))
1020 devices.push_back(device);
1027 for (
const QString& device : std::as_const(devices))
1030 return (
uint) devices.size();
1043 setHelpText(QObject::tr(
"Specify the command to run, with any "
1044 "needed arguments."));
1061 setLabel(QObject::tr(
"File path"));
1077 setLabel(QObject::tr(
"Audio device"));
1079 QDir dev(
"/dev",
"dsp*", QDir::Name, QDir::System);
1081 dev.setPath(
"/dev/sound");
1084#if CONFIG_AUDIO_ALSA
1088 setHelpText(QObject::tr(
"Device to read audio from, "
1089 "if audio is separate from the video."));
1098 std::chrono::milliseconds min_val) :
1101 setLabel(QObject::tr(
"Signal timeout (ms)"));
1104 "Maximum time (in milliseconds) MythTV waits for "
1105 "a signal when scanning for channels."));
1108 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1110 SignalTimeout(parent, value, duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1111 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1114 duration_cast<
std::chrono::milliseconds>(value),
1115 duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1123 std::chrono::milliseconds min_val) :
1126 setLabel(QObject::tr(
"Tuning timeout (ms)"));
1129 "Maximum time (in milliseconds) MythTV waits for "
1130 "a channel lock. For recordings, if this time is "
1131 "exceeded, the recording will be marked as failed."));
1134 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1136 ChannelTimeout(parent, value, duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1137 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1139 ChannelTimeout(parent, value, duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1148 setLabel(QObject::tr(
"Force audio sampling rate"));
1150 QObject::tr(
"If non-zero, override the audio sampling "
1151 "rate in the recording profile when this card is "
1152 "used. Use this if your capture card does not "
1153 "support all of the standard rates."));
1168 setLabel(QObject::tr(
"Do not adjust volume"));
1170 QObject::tr(
"Enable this option for budget BT878 based "
1171 "DVB-T cards such as the AverTV DVB-T which "
1172 "require the audio volume to be left alone."));
1187 setLabel(QObject::tr(
"DVB device"));
1189 QObject::tr(
"When you change this setting, the text below "
1190 "should change to the name and type of your card. "
1191 "If the card cannot be opened, an error message "
1192 "will be displayed."));
1210 std::stable_sort(sdevs.begin(), sdevs.end());
1215 QMap<QString,bool> in_use;
1217 for (
const QString& dev : std::as_const(sdevs))
1219 in_use[dev] =
std::find(db.begin(), db.end(), dev) != db.end();
1220 if (sel.isEmpty() && !in_use[dev])
1224 if (sel.isEmpty() && !sdevs.empty())
1227 QString usestr = QString(
" -- ");
1228 usestr += QObject::tr(
"Warning: already in use");
1230 for (
const QString& dev : std::as_const(sdevs))
1232 QString desc = dev + (in_use[dev] ? usestr :
"");
1233 desc = (
current == dev) ? dev : desc;
1257 setLabel(QObject::tr(
"Delivery system"));
1259 QObject::tr(
"If your card supports more than one delivery system "
1260 "then you can select here the one that you want to use."));
1269 setLabel(QObject::tr(
"Frontend ID"));
1271 QObject::tr(
"Identification string reported by the card. "
1272 "If the message \"Could not get card info...\" appears "
1273 "the card can be in use by another program."));
1284 setLabel(QObject::tr(
"Wait for SEQ start header"));
1287 QObject::tr(
"If enabled, drop packets from the start of a DVB "
1288 "recording until a sequence start header is seen."));
1304 setLabel(QObject::tr(
"Open DVB card on demand"));
1307 QObject::tr(
"If enabled, only open the DVB card when required, "
1308 "leaving it free for other programs at other times."));
1324 setLabel(QObject::tr(
"Use DVB card for active EIT scan"));
1327 QObject::tr(
"If enabled, activate active scanning for "
1328 "program data (EIT). When this option is enabled "
1329 "the DVB card is constantly in use."));
1344 setLabel(QObject::tr(
"DVB tuning delay (ms)"));
1347 QObject::tr(
"Some Linux DVB drivers, in particular for the "
1348 "Hauppauge Nova-T, require that we slow down "
1349 "the tuning process by specifying a delay "
1350 "(in milliseconds)."));
1363 for (
auto & i : list)
1365 QString guid = i.GetGUIDString();
1384 setLabel(QObject::tr(
"Cable box model"));
1385 addSelection(QObject::tr(
"Motorola Generic"),
"MOTO GENERIC");
1386 addSelection(QObject::tr(
"SA/Cisco Generic"),
"SA GENERIC");
1402 QString
help = QObject::tr(
1403 "Choose the model that most closely resembles your set top box. "
1404 "Depending on firmware revision SA4200HD may work better for a "
1424 name.replace(
"Scientific-Atlanta",
"SA");
1425 name.replace(
", Inc.",
"");
1426 name.replace(
"Explorer(R)",
"");
1427 name = name.simplified();
1428 setValue((name.isEmpty()) ?
"" : name);
1437 "firewire_connection"))
1439 setLabel(QObject::tr(
"Connection Type"));
1482#if CONFIG_FIREWIRE_LINUX
1490 model->SetGUID(dev->getValue());
1491 desc->SetGUID(dev->getValue());
1505HDHomeRunDeviceID::HDHomeRunDeviceID(
const CaptureCard &parent,
1506 HDHomeRunConfigurationGroup &_group) :
1514HDHomeRunDeviceID::~HDHomeRunDeviceID()
1516 delete GetStorage();
1519void HDHomeRunDeviceID::Load(
void)
1522 m_group.SetDeviceCheckBoxes(getValue());
1525void HDHomeRunDeviceID::Save(
void)
1527 setValue(m_group.GetDeviceCheckBoxes());
1534 explicit HDHomeRunEITScan(
const CaptureCard &parent) :
1538 setLabel(QObject::tr(
"Use HDHomeRun for active EIT scan"));
1541 QObject::tr(
"If enabled, activate active scanning for "
1542 "program data (EIT). When this option is enabled "
1543 "the HDHomeRun is constantly in use."));
1546 ~HDHomeRunEITScan()
override
1556 explicit UseHDHomeRunDevice(QString &deviceid, QString &model,
1559 setLabel(QObject::tr(
"Use HDHomeRun %1 (%2 %3)")
1560 .arg(deviceid, model, ipaddr));
1563 QObject::tr(
"If enabled, use tuners from this HDHomeRun "
1568HDHomeRunConfigurationGroup::HDHomeRunConfigurationGroup
1571 m_deviceId(new HDHomeRunDeviceID(a_parent, *this))
1578 QMap<QString, HDHomeRunDevice>::iterator dit;
1579 for (dit = m_deviceList.begin(); dit != m_deviceList.end(); ++dit)
1581 HDHomeRunDevice &dev = *dit;
1582 dev.m_checkbox =
new UseHDHomeRunDevice(
1583 dev.m_deviceId, dev.m_model, dev.m_cardIp);
1591 buttonRecOpt->setLabel(tr(
"Recording Options"));
1594 buttonRecOpt->addChild(
new HDHomeRunEITScan(
m_parent));
1598void HDHomeRunConfigurationGroup::FillDeviceList(
void)
1600 m_deviceList.clear();
1606 for (
const auto & dev : std::as_const(devs))
1608 QStringList devinfo = dev.split(
" ");
1609 const QString& devid = devinfo.at(0);
1610 const QString& devip = devinfo.at(1);
1611 const QString& model = devinfo.at(2);
1613 HDHomeRunDevice tmpdevice;
1614 tmpdevice.m_model = model;
1615 tmpdevice.m_cardIp = devip;
1616 tmpdevice.m_deviceId = devid;
1619 tmpdevice.m_checkbox =
nullptr;
1620 m_deviceList[tmpdevice.m_deviceId] = tmpdevice;
1625 QMap<QString, HDHomeRunDevice>::iterator debugit;
1626 for (debugit = m_deviceList.begin(); debugit != m_deviceList.end(); ++debugit)
1628 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1: %2 %3")
1629 .arg(debugit.key()).arg((*debugit).model)
1630 .arg((*debugit).cardip));
1635void HDHomeRunConfigurationGroup::SetDeviceCheckBoxes(
const QString& devices)
1637 QStringList devstrs = devices.split(
",");
1638 for (
const QString& devstr : std::as_const(devstrs))
1643 QByteArray ba = devstr.toUtf8();
1645 ba.data(),
nullptr);
1648 QString devid = QString(
"%1").arg(
1649 hdhomerun_device_get_device_id(device), 8, 16).toUpper();
1650 hdhomerun_device_destroy(device);
1653 QMap<QString, HDHomeRunDevice>::iterator dit;
1654 dit = m_deviceList.find(devid);
1655 if (dit != m_deviceList.end())
1656 (*dit).m_checkbox->setValue(
true);
1660QString HDHomeRunConfigurationGroup::GetDeviceCheckBoxes(
void)
1664 QStringList devstrs;
1665 QMap<QString, HDHomeRunDevice>::iterator dit;
1666 for (dit = m_deviceList.begin(); dit != m_deviceList.end(); ++dit)
1668 if ((*dit).m_checkbox->boolValue())
1669 devstrs << (*dit).m_deviceId;
1671 QString devices = devstrs.join(
",");
1683 setLabel(QObject::tr(
"IP Address"));
1684 setHelpText(QObject::tr(
"Device IP or ID of a VBox device. eg. '192.168.1.100' or 'vbox_3718'"));
1714 setHelpText(QObject::tr(
"Number and type of the tuner to use. eg '1-DVBT/T2'."));
1788 m_deviceId(deviceid),
1791 m_cardTuner(cardtuner),
1792 m_deviceList(devicelist),
1795 setLabel(QObject::tr(
"Available devices"));
1798 "Device IP or ID, tuner number and tuner type of available VBox devices."));
1809 std::vector<QString> devs;
1810 QMap<QString, bool> in_use;
1816 devs.push_back(it.key());
1817 in_use[it.key()] = (*it).m_inUse;
1820 QString man_addr = VBoxDeviceIDList::tr(
"Manually Enter IP Address");
1821 QString sel = man_addr;
1822 devs.push_back(sel);
1824 for (
const auto & dev : devs)
1825 sel = (
current == dev) ? dev : sel;
1827 QString usestr = QString(
" -- ");
1828 usestr += QObject::tr(
"Warning: already in use");
1830 for (
const auto & dev : devs)
1832 QString desc = dev + (in_use[dev] ? usestr :
"");
1840 else if (sel == man_addr && !
current.isEmpty())
1843 QStringList selection =
current.split(
"-");
1864 if (v == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1869 else if (!v.isEmpty())
1871 if (
m_oldValue == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1896 setValue(
"http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
1899 QObject::tr(
"URL of M3U file containing RTSP/RTP/UDP/HTTP channel URLs,"
1900 " example for HDHomeRun: http://<ipv4>/lineup.m3u and for Freebox:"
1901 " http://mafreebox.freebox.fr/freeboxtv/playlist.m3u."
1920 setLabel(QObject::tr(
"ASI device"));
1938 std::stable_sort(sdevs.begin(), sdevs.end());
1947 QMap<QString,bool> in_use;
1949 for (
const QString& dev : std::as_const(sdevs))
1951 in_use[dev] =
std::find(db.begin(), db.end(), dev) != db.end();
1952 if (sel.isEmpty() && !in_use[dev])
1957 if (sel.isEmpty() && !sdevs.empty())
1960 QString usestr = QString(
" -- ");
1961 usestr += QObject::tr(
"Warning: already in use");
1965 for (
const QString& dev : std::as_const(sdevs))
1967 QString desc = dev + (in_use[dev] ? usestr :
"");
1968 desc = (
current == dev) ? dev : desc;
1970 found |= (dev == sel);
1974 if (!found && !
current.isEmpty())
1976 QString desc =
current +
" -- " +
1977 QObject::tr(
"Warning: unable to open");
2015 if (device.isEmpty())
2032 LOG(VB_GENERAL, LOG_WARNING,
2033 "ASIConfigurationGroup::probeCard(), Warning: " +
error);
2049 device->setHelpText(tr(
"A local file used to simulate a recording."
2050 " Leave empty to use MythEvents to trigger an"
2051 " external program to import recording files."));
2073 QFileInfo fileInfo(device);
2076 if (device.startsWith(
"file:", Qt::CaseInsensitive))
2077 fileInfo.setFile(device.mid(5));
2079 if (fileInfo.exists())
2081 if (fileInfo.isReadable() && (fileInfo.isFile()))
2084 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2088 ci = tr(
"File not readable");
2093 ci = tr(
"File %1 does not exist").arg(device);
2145 for (
const auto & dev : std::as_const(devs))
2147 QStringList devinfo = dev.split(
" ");
2148 const QString&
id = devinfo.at(0);
2149 const QString& ip = devinfo.at(1);
2150 const QString& tunerNo = devinfo.at(2);
2151 const QString& tunerType = devinfo.at(3);
2170 for (
const auto & dev : std::as_const(db))
2172 QMap<QString, VBoxDevice>::iterator dit;
2176 (*dit).m_inUse =
true;
2184CetonSetting::CetonSetting(QString label,
const QString& helptext)
2186 setLabel(std::move(label));
2187 setHelpText(helptext);
2189 this, &CetonSetting::UpdateDevices);
2192void CetonSetting::UpdateDevices(
const QString &v)
2198void CetonSetting::LoadValue(
const QString &value)
2203CetonDeviceID::CetonDeviceID(
const CaptureCard &parent) :
2211CetonDeviceID::~CetonDeviceID()
2213 delete GetStorage();
2216void CetonDeviceID::SetIP(
const QString &ip)
2218 static const QRegularExpression ipV4Regex
2219 {
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){4}$" };
2220 auto match = ipV4Regex.match(ip +
".");
2221 if (match.hasMatch())
2224 setValue(QString(
"%1-RTP.%3").arg(m_ip, m_tuner));
2228void CetonDeviceID::SetTuner(
const QString &tuner)
2230 static const QRegularExpression oneDigit {
"^\\d$" };
2231 auto match = oneDigit.match(tuner);
2232 if (match.hasMatch())
2235 setValue(QString(
"%1-RTP.%2").arg(m_ip, m_tuner));
2239void CetonDeviceID::Load(
void)
2241 GetStorage()->Load();
2245void CetonDeviceID::UpdateValues(
void)
2247 static const QRegularExpression newstyle { R
"(^([0-9.]+)-(\d|RTP)\.(\d)$)" };
2248 auto match = newstyle.match(getValue());
2249 if (match.hasMatch())
2251 emit LoadedIP(match.captured(1));
2252 emit LoadedTuner(match.captured(3));
2258 auto *deviceid =
new CetonDeviceID(parent);
2260 desc->setLabel(tr(
"CetonConfigurationGroup",
"Description"));
2261 auto *ip =
new CetonSetting(tr(
"IP Address"),
2262 tr(
"IP Address of the Ceton device (192.168.200.1 by default)"));
2263 auto *tuner =
new CetonSetting(tr(
"Tuner"),
2264 tr(
"Number of the tuner on the Ceton device (first tuner is number 0)"));
2273 QObject::connect(ip, &CetonSetting::NewValue,
2274 deviceid, &CetonDeviceID::SetIP);
2275 QObject::connect(tuner, &CetonSetting::NewValue,
2276 deviceid, &CetonDeviceID::SetTuner);
2278 QObject::connect(deviceid, &CetonDeviceID::LoadedIP,
2279 ip, &CetonSetting::LoadValue);
2280 QObject::connect(deviceid, &CetonDeviceID::LoadedTuner,
2281 tuner, &CetonSetting::LoadValue);
2305 const QString &inputtype) :
2311 QRegularExpression drv {
"^(?!ivtv|hdpvr|(saa7164(.*))).*$" };
2335 QString cn = tr(
"Failed to open");
2339 QByteArray adevice = device.toLatin1();
2340 int videofd = open(adevice.constData(), O_RDWR);
2344 ci = cn = tr(
"Failed to probe");
2345 else if (!dn.isEmpty())
2346 ci = cn +
" [" + dn +
"]";
2361 QRegularExpression drv {
"^(ivtv|(saa7164(.*)))$" };
2384 QString cn = tr(
"Failed to open");
2388 QByteArray adevice = device.toLatin1();
2389 int videofd = open(adevice.constData(), O_RDWR);
2393 ci = cn = tr(
"Failed to probe");
2394 else if (!dn.isEmpty())
2395 ci = cn +
" [" + dn +
"]";
2411 device->setHelpText(tr(
"A local MPEG file used to simulate a recording."));
2434 QFileInfo fileInfo(device);
2435 if (fileInfo.exists())
2437 if (fileInfo.isReadable() && (fileInfo.isFile()))
2440 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2444 ci = tr(
"File not readable");
2449 ci = tr(
"File does not exist");
2457ExternalConfigurationGroup::ExternalConfigurationGroup(
CaptureCard &a_parent,
2464 device->setLabel(tr(
"Command path"));
2465 device->setHelpText(tr(
"A 'black box' application controlled via stdin, status on "
2466 "stderr and TransportStream read from stdout.\n"
2467 "Use absolute path or path relative to the current directory."));
2477 this, &ExternalConfigurationGroup::probeApp);
2479 probeApp(device->getValue());
2482void ExternalConfigurationGroup::probeApp(
const QString & path)
2484 int idx1 = path.startsWith(
"file:", Qt::CaseInsensitive) ? 5 : 0;
2485 int idx2 = path.indexOf(
' ', idx1);
2488 QFileInfo fileInfo(path.mid(idx1, idx2 - idx1));
2490 if (fileInfo.exists())
2492 ci = tr(
"File '%1' is valid.").arg(fileInfo.absoluteFilePath());
2493 if (!fileInfo.isReadable() || !fileInfo.isFile())
2494 ci = tr(
"WARNING: File '%1' is not readable.")
2495 .arg(fileInfo.absoluteFilePath());
2496 if (!fileInfo.isExecutable())
2497 ci = tr(
"WARNING: File '%1' is not executable.")
2498 .arg(fileInfo.absoluteFilePath());
2502 ci = tr(
"WARNING: File '%1' does not exist.")
2503 .arg(fileInfo.absoluteFilePath());
2506 m_info->setValue(ci);
2507 m_info->setHelpText(ci);
2519 QRegularExpression(
"^hdpvr$"));
2542 QString cn = tr(
"Failed to open");
2546 int videofd = open(device.toLocal8Bit().constData(), O_RDWR);
2550 ci = cn = tr(
"Failed to probe");
2551 else if (!dn.isEmpty())
2552 ci = cn +
" [" + dn +
"]";
2568 setLabel(QObject::tr(
"V4L2 encoder devices (multirec capable)"));
2583 if (!device_name.isEmpty())
2590 QString card_name = tr(
"Failed to open");
2591 QString card_info = card_name;
2610 if (audioinput->fillSelections(device_name) > 1)
2612 audioinput->setName(
"AudioInput");
2625 vbidev->setName(
"VBIDevice");
2643 setLabel(QObject::tr(
"Capture Card Setup"));
2645 auto* cardtype =
new CardType(parent);
2660 new HDHomeRunConfigurationGroup(parent, *cardtype));
2670 new SatIPConfigurationGroup(parent, *cardtype));
2674 FirewireConfigurationGroup(parent, *cardtype);
2678 CetonSetting::CetonConfigurationGroup(parent, *cardtype);
2709 new ExternalConfigurationGroup(parent,
2735 "SELECT cardid, videodevice, cardtype, displayname "
2737 "WHERE hostname = :HOSTNAME AND parentid = 0 "
2751 while (query.
next())
2754 QString videodevice = query.
value(1).toString();
2755 QString cardtype = query.
value(2).toString();
2756 QString displayname = query.
value(3).toString();
2758 QString label = QString(
"%1 (%2)")
2762 card->loadByID(cardid);
2763 card->setLabel(label);
2800 if (dev != init_dev)
2802 if (!init_dev.isEmpty())
2821 for (
uint clone : clones)
2838 setLabel(QObject::tr(
"Card type"));
2839 setHelpText(QObject::tr(
"Change the cardtype to the appropriate type for "
2840 "the capture card you are configuring."));
2848 QObject::tr(
"DVB-T/S/C, ATSC or ISDB-T tuner card"),
"DVB");
2853 QObject::tr(
"V4L2 encoder"),
"V4L2ENC");
2855 QObject::tr(
"HD-PVR H.264 encoder"),
"HDPVR");
2860 QObject::tr(
"HDHomeRun networked tuner"),
"HDHOMERUN");
2865 QObject::tr(
"Sat>IP networked tuner"),
"SATIP");
2870 QObject::tr(
"V@Box TV Gateway networked tuner"),
"VBOX");
2875 QObject::tr(
"FireWire cable box"),
"FIREWIRE");
2880 QObject::tr(
"Ceton Cablecard tuner"),
"CETON");
2884 setting->
addSelection(QObject::tr(
"IPTV recorder"),
"FREEBOX");
2889 QObject::tr(
"Analog to MPEG-2 encoder card (PVR-150/250/350, etc)"),
"MPEG");
2891 QObject::tr(
"Analog to MJPEG encoder card (Matrox G200, DC10, etc)"),
"MJPEG");
2893 QObject::tr(
"Analog to MPEG-4 encoder (Plextor ConvertX USB, etc)"),
2896 QObject::tr(
"Analog capture card"),
"V4L");
2900 setting->
addSelection(QObject::tr(
"DVEO ASI recorder"),
"ASI");
2903 setting->
addSelection(QObject::tr(
"Import test recorder"),
"IMPORT");
2904 setting->
addSelection(QObject::tr(
"Demo test recorder"),
"DEMO");
2906 setting->
addSelection(QObject::tr(
"External (black box) recorder"),
2929 setLabel(QObject::tr(
"Input name"));
2945 addSelection(QObject::tr(
"(None)"),
"None");
2947 if (storage ==
nullptr)
2954 while (!inputs.isEmpty())
2956 addSelection(inputs.front());
2967 setLabel(QObject::tr(
"Delivery system"));
2969 "This shows the delivery system (modulation), for instance DVB-T2, "
2970 "that you have selected when you configured the capture card. "
2971 "This must be the same as the modulation used by the video source. "));
2983 setLabel(QObject::tr(
"Display name"));
2985 "This name is displayed on screen when Live TV begins "
2986 "and in various other places. Make sure the last two "
2987 "characters are unique for each input or use a "
2988 "slash ('/') to designate the unique portion."));
3024 setLabel(QObject::tr(
"Video source"));
3025 addSelection(QObject::tr(
"(None)"),
"0");
3036 addSelection(QObject::tr(
"(None)"),
"0");
3045 m_cardInput(parent),
3046 m_groupNum(group_num)
3048 setLabel(QObject::tr(
"Input group") +
3049 QString(
" %1").arg(m_groupNum + 1));
3051 "Leave as 'Generic' unless this input is shared with "
3052 "another device. Only one of the inputs in an input "
3053 "group will be allowed to record at any given time."));
3056 void Load(
void)
override;
3060 uint inputid = m_cardInput.getInputID();
3063 if (m_groupId && (m_groupId != new_groupid))
3081 LOG(VB_GENERAL, LOG_DEBUG, QString(
"InputGroup::Load() %1 %2")
3082 .arg(m_groupNum).arg(m_cardInput.getInputID()));
3085 uint inputid = m_cardInput.getInputID();
3086 QMap<uint, uint> grpcnt;
3087 std::vector<QString> names;
3088 std::vector<uint> grpid;
3089 std::vector<uint> selected_groupids;
3091 names.push_back(QObject::tr(
"Generic"));
3097 "SELECT cardinputid, inputgroupid, inputgroupname "
3099 "WHERE inputgroupname LIKE 'user:%' "
3100 "ORDER BY inputgroupid, cardinputid, inputgroupname");
3108 while (query.
next())
3111 if ((inputid != 0U) && (query.
value(0).toUInt() == inputid))
3112 selected_groupids.push_back(groupid);
3116 if (grpcnt[groupid] == 1)
3118 names.push_back(query.
value(2).toString().mid(5, -1));
3119 grpid.push_back(groupid);
3126 if (m_groupNum < selected_groupids.size())
3127 m_groupId = selected_groupids[m_groupNum];
3130 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group num: %1 id: %2")
3131 .arg(m_groupNum).arg(m_groupId));
3134 for (
uint i = 0; i < selected_groupids.size(); i++)
3135 msg += QString(
"%1 ").arg(selected_groupids[i]);
3136 LOG(VB_GENERAL, LOG_DEBUG, msg);
3143 for (
size_t i = 0; i < names.size(); i++)
3145 bool sel = (m_groupId == grpid[i]);
3146 index = (sel) ? i : index;
3149 LOG(VB_GENERAL, LOG_DEBUG, QString(
"grpid %1, name '%2', i %3, s %4")
3150 .arg(grpid[i]).arg(names[i]) .arg(index).arg(sel ?
"T" :
"F"));
3153 addSelection(names[i], QString::number(grpid[i]), sel);
3157 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group index: %1").arg(index));
3172 setLabel(QObject::tr(
"Use quick tuning"));
3173 addSelection(QObject::tr(
"Never"),
"0",
true);
3174 addSelection(QObject::tr(
"Live TV only"),
"1",
false);
3175 addSelection(QObject::tr(
"Always"),
"2",
false);
3177 "If enabled, MythTV will tune using only the "
3178 "MPEG program number. The program numbers "
3179 "change more often than DVB or ATSC tuning "
3180 "parameters, so this is slightly less reliable. "
3181 "This will also inhibit EIT gathering during "
3182 "Live TV and recording."));
3192 setLabel(QObject::tr(
"External channel change command"));
3194 setHelpText(QObject::tr(
"If specified, this command will be run to "
3195 "change the channel for inputs which have an external "
3196 "tuner device such as a cable box. The first argument "
3197 "will be the channel number."));
3212 setLabel(QObject::tr(
"Preset tuner to channel"));
3214 setHelpText(QObject::tr(
"Leave this blank unless you have an external "
3215 "tuner that is connected to the tuner input of your card. "
3216 "If so, you will need to specify the preset channel for "
3217 "the signal (normally 3 or 4)."));
3229 if (sourceid.isEmpty() || !sourceid.toUInt())
3234 if (storage ==
nullptr)
3241 if (channels.empty())
3243 addSelection(tr(
"Please add channels to this source"),
3244 startChan.isEmpty() ?
"0" : startChan);
3252 bool has_visible =
false;
3253 for (
size_t i = 0; i < channels.size() && !has_visible; i++)
3256 for (
auto & channel : channels)
3258 const QString channum = channel.m_chanNum;
3259 bool sel = channum == startChan;
3260 if (!has_visible || channel.m_visible || sel)
3262 addSelection(channum, channum, sel);
3274 setLabel(QObject::tr(
"Input priority"));
3276 setHelpText(QObject::tr(
"If the input priority is not equal for "
3277 "all inputs, the scheduler may choose to record a show "
3278 "at a later time so that it can record on an input with "
3279 "a higher value."));
3295 setLabel(QObject::tr(
"Schedule order"));
3297 setHelpText(QObject::tr(
"If priorities and other factors are equal "
3298 "the scheduler will choose the available "
3299 "input with the lowest, non-zero value. "
3300 "Setting this value to zero will make the "
3301 "input unavailable to the scheduler."));
3317 setLabel(QObject::tr(
"Live TV order"));
3319 setHelpText(QObject::tr(
"When entering Live TV, the available, local "
3320 "input with the lowest, non-zero value will "
3321 "be used. If no local inputs are available, "
3322 "the available, remote input with the lowest, "
3323 "non-zero value will be used. "
3324 "Setting this value to zero will make the "
3325 "input unavailable to live TV."));
3341 setLabel(QObject::tr(
"Use DishNet long-term EIT data"));
3345 "If you point your satellite dish toward DishNet's birds, "
3346 "you may wish to enable this feature. For best results, "
3347 "enable general EIT collection as well."));
3378 if (
"DVB" == cardtype)
3400 if (
"DVB" == cardtype)
3405 tr(
"Use channel scanner to find channels for this input."));
3408 tr(
"This uses the listings data source to "
3409 "provide the channels for this input.") +
" " +
3410 tr(
"This can take a long time to run."));
3419 interact->setLabel(QObject::tr(
"Interactions between inputs"));
3429 interact->addChild(
new LiveTVOrder(*
this, _cardid));
3433 ingrpbtn->setHelpText(
3434 QObject::tr(
"Input groups are only needed when two or more cards "
3435 "share the same resource such as a FireWire card and "
3436 "an analog card input controlling the same set top box."));
3437 interact->addChild(ingrpbtn);
3443 setObjectName(
"CardInput");
3469 bool enable = (sourceid.toInt() > 0);
3486 auto *settingdialog =
3489 if (settingdialog->Create())
3497 delete settingdialog;
3505 ShowOkPopup(tr(
"Sorry, this Input Group name cannot be blank."));
3509 QString new_name = QString(
"user:") + name;
3512 query.
prepare(
"SELECT inputgroupname "
3514 "WHERE inputgroupname = :GROUPNAME");
3515 query.
bindValue(
":GROUPNAME", new_name);
3525 ShowOkPopup(tr(
"Sorry, this Input Group name is already in use."));
3560 LOG(VB_GENERAL, LOG_ERR,
3561 QString(
"Sorry, %1 cards do not yet support scanning.")
3573 [srcid,
this, num_channels_before]()
3577 if (num_channels_before)
3591 LOG(VB_GENERAL, LOG_ERR,
"You must compile the backend "
3592 "to be able to scan for channels");
3612 cardtype !=
"HDHOMERUN" &&
3613 !num_channels_before)
3615 LOG(VB_GENERAL, LOG_ERR,
"Skipping channel fetch, you need to "
3616 "scan for channels first.");
3625 if (num_channels_before)
3634 QString cardinputidTag(
":WHERECARDID");
3636 QString query(
"cardid = " + cardinputidTag);
3645 QString cardinputidTag(
":SETCARDID");
3648 QString query(
"cardid = " + cardinputidTag +
", " +
3667 query.
prepare(
"SELECT cardid FROM capturecard "
3668 "WHERE cardid = :CARDID AND inputname = :INPUTNAME");
3670 query.
bindValue(
":INPUTNAME", _inputname);
3723 tr(
"Are you sure you want to delete "
3732 tr(
"Are you sure you want to delete "
3733 "ALL capture cards?"),
3741 card->setLabel(tr(
"New capture card"));
3767 "WHERE hostname = :HOSTNAME");
3773 tr(
"Error getting list of cards for this host. "
3774 "Unable to delete capturecards for %1")
3781 while (cards.
next())
3797 AddSelection(QObject::tr(
"(Delete all capture cards on %1)")
3800 AddSelection(QObject::tr(
"(Delete all capture cards)"),
3814 AddSelection(QObject::tr(
"(Delete all video sources)"),
3837 tr(
"Are you sure you want to delete "
3838 "ALL video sources?"),
3856 source->setLabel(tr(
"New video source"));
3878 "SELECT cardid, videodevice, cardtype, displayname "
3880 "WHERE hostname = :HOSTNAME "
3881 " AND parentid = 0 "
3891 while (query.
next())
3894 QString videodevice = query.
value(1).toString();
3895 QString cardtype = query.
value(2).toString();
3896 QString displayname = query.
value(3).toString();
3898 auto *cardinput =
new CardInput(cardtype, videodevice, cardid);
3899 cardinput->loadByID(cardid);
3900 QString inputlabel = QString(
"%1 (%2) -> %3")
3902 displayname, cardinput->getSourceName());
3904 cardinput->setLabel(inputlabel);
3912static QString remove_chaff(
const QString &name)
3915 QString short_name = name;
3916 if (short_name.startsWith(
"LG Electronics"))
3917 short_name = short_name.right(short_name.length() - 15);
3918 if (short_name.startsWith(
"Oren"))
3919 short_name = short_name.right(short_name.length() - 5);
3920 if (short_name.startsWith(
"Nextwave"))
3921 short_name = short_name.right(short_name.length() - 9);
3922 if (short_name.startsWith(
"frontend", Qt::CaseInsensitive))
3923 short_name = short_name.left(short_name.length() - 9);
3924 if (short_name.endsWith(
"VSB/QAM"))
3925 short_name = short_name.left(short_name.length() - 8);
3926 if (short_name.endsWith(
"VSB"))
3927 short_name = short_name.left(short_name.length() - 4);
3928 if (short_name.endsWith(
"DVB-T"))
3929 short_name = short_name.left(short_name.length() - 6);
3935 short_name = short_name.simplified();
3936 if (short_name.startsWith(
"or51211", Qt::CaseInsensitive))
3937 short_name =
"pcHDTV HD-2000";
3938 else if (short_name.startsWith(
"or51132", Qt::CaseInsensitive))
3939 short_name =
"pcHDTV HD-3000";
3940 else if (short_name.startsWith(
"bcm3510", Qt::CaseInsensitive))
3941 short_name =
"Air2PC v1";
3942 else if (short_name.startsWith(
"nxt2002", Qt::CaseInsensitive) ||
3943 short_name.startsWith(
"nxt200x", Qt::CaseInsensitive))
3944 short_name =
"Air2PC v2";
3945 else if (short_name.startsWith(
"lgdt3302", Qt::CaseInsensitive))
3946 short_name =
"DViCO HDTV3";
3947 else if (short_name.startsWith(
"lgdt3303", Qt::CaseInsensitive))
3948 short_name =
"DViCO v2 or Air2PC v3 or pcHDTV HD-5500";
3973 if (videodevice.isEmpty())
3991 QString err_open = tr(
"Could not open card %1").arg(videodevice);
3992 QString err_other = tr(
"Could not get card info for card %1").arg(videodevice);
4038 if (frontend_name.toLower().indexOf(
"usb") >= 0)
4045 if ((frontend_name ==
"DiBcom 3000P/M-C DVB-T") ||
4047 "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
4053 QString short_name = remove_chaff(frontend_name);
4054 m_buttonAnalog->setVisible(
4055 short_name.startsWith(
"zarlink zl10353",
4056 Qt::CaseInsensitive) ||
4057 short_name.startsWith(
"wintv hvr 900 m/r: 65008/a1c0",
4058 Qt::CaseInsensitive) ||
4059 short_name.startsWith(
"philips tda10046h",
4060 Qt::CaseInsensitive));
4066 QString short_name = remove_chaff(frontend_name);
4074 if (frontend_name ==
"Nextwave NXT200X VSB/QAM frontend")
4081 if (frontend_name.toLower().indexOf(
"usb") < 0)
4083 m_buttonAnalog->setVisible(
4084 short_name.startsWith(
"pchdtv", Qt::CaseInsensitive) ||
4085 short_name.startsWith(
"dvico", Qt::CaseInsensitive) ||
4086 short_name.startsWith(
"nextwave", Qt::CaseInsensitive));
4099 for (
const auto & item : std::as_const(delsyslist))
4101 LOG(VB_GENERAL, LOG_DEBUG, QString(
"DVBCardType: add deliverysystem:%1")
4109 if (!delsys.isEmpty())
4121 QString dev, QString
type) :
4123 m_lastDevice(
std::move(dev)), m_lastCardType(
std::move(
type))
4125 setLabel(QObject::tr(
"Audio input"));
4126 setHelpText(QObject::tr(
"If there is more than one audio input, "
4127 "select which one to use."));
4140 if (device.isEmpty())
4144 QStringList inputs =
4147 for (
uint i = 0; i < (
uint)inputs.size(); i++)
4152 return inputs.size();
4235 explicit DiSEqCPosition(
const CaptureCard &parent,
int value,
int min_val) :
4239 setLabel(QObject::tr(
"DiSEqC position"));
4240 setHelpText(QObject::tr(
"Position of the LNB on the DiSEqC switch. "
4241 "Leave at 1 if there is no DiSEqC switch "
4242 "and the LNB is directly connected to the SatIP server. "
4243 "This value is used as signal source (attribute src) in "
4244 "the SatIP tune command."));
4248 ~DiSEqCPosition()
override
4254SatIPConfigurationGroup::SatIPConfigurationGroup
4257 m_deviceId(new SatIPDeviceID(a_parent))
4263 m_friendlyName =
new SatIPDeviceAttribute(tr(
"Friendly name"), tr(
"Friendly name of the Sat>IP server"));
4264 m_tunerType =
new SatIPDeviceAttribute(tr(
"Tuner type"), tr(
"Type of the selected tuner"));
4265 m_tunerIndex =
new SatIPDeviceAttribute(tr(
"Tuner index"), tr(
"Index of the tuner on the Sat>IP server"));
4267 m_deviceIdList =
new SatIPDeviceIDList(
4268 m_deviceId, m_friendlyName, m_tunerType, m_tunerIndex, &m_deviceList,
m_parent);
4280 connect(m_deviceIdList, &SatIPDeviceIDList::NewTuner,
4281 m_deviceId, &SatIPDeviceID::SetTuner);
4284void SatIPConfigurationGroup::FillDeviceList(
void)
4286 m_deviceList.clear();
4292 for (
const auto & dev : std::as_const(devs))
4294 QStringList devparts = dev.split(
" ");
4295 const QString&
id = devparts.value(0);
4296 const QString& name = devparts.value(1);
4297 const QString& ip = devparts.value(2);
4298 const QString& tunerno = devparts.value(3);
4299 const QString& tunertype = devparts.value(4);
4302 device.m_deviceId = id;
4303 device.m_cardIP = ip;
4304 device.m_inUse =
false;
4305 device.m_friendlyName = name;
4306 device.m_tunerNo = tunerno;
4307 device.m_tunerType = tunertype;
4308 device.m_mythDeviceId = QString(
"%1:%2:%3").arg(
id, tunertype, tunerno);
4310 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3").arg(name, tunertype, tunerno);
4312 m_deviceList[device.m_mythDeviceId] = device;
4314 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"SatIP: Add %1 '%2' '%3'")
4315 .arg(device.m_mythDeviceId, device.m_friendlyName, friendlyIdentifier));
4321 for (
const auto& dev : std::as_const(db))
4323 auto dit = m_deviceList.find(dev);
4324 if (dit != m_deviceList.end())
4326 (*dit).m_inUse =
true;
4331SatIPDeviceIDList::SatIPDeviceIDList(
4332 SatIPDeviceID *deviceId,
4333 SatIPDeviceAttribute *friendlyName,
4334 SatIPDeviceAttribute *tunerType,
4335 SatIPDeviceAttribute *tunerIndex,
4336 SatIPDeviceList *deviceList,
4338 m_deviceId(deviceId),
4339 m_friendlyName(friendlyName),
4340 m_tunerType(tunerType),
4341 m_tunerIndex(tunerIndex),
4342 m_deviceList(deviceList),
4346 setHelpText(tr(
"Device IP or ID, tuner number and tuner type of available Sat>IP device"));
4349 this, &SatIPDeviceIDList::UpdateDevices);
4352void SatIPDeviceIDList::Load(
void)
4356 int cardid = m_parent.getCardID();
4359 fillSelections(device);
4362void SatIPDeviceIDList::UpdateDevices(
const QString &v)
4364 SatIPDevice dev = (*m_deviceList)[v];
4365 m_deviceId->setValue(dev.m_mythDeviceId);
4366 m_friendlyName->setValue(dev.m_friendlyName);
4367 m_tunerType->setValue(dev.m_tunerType);
4368 m_tunerIndex->setValue(dev.m_tunerNo);
4371void SatIPDeviceIDList::fillSelections(
const QString &cur)
4375 std::vector<QString> names;
4376 std::vector<QString> devs;
4377 QMap<QString, bool> in_use;
4382 SatIPDeviceList::iterator it = m_deviceList->begin();
4383 for(; it != m_deviceList->end(); ++it)
4385 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3")
4386 .arg((*it).m_friendlyName, (*it).m_tunerType, (*it).m_tunerNo);
4387 names.push_back(friendlyIdentifier);
4389 devs.push_back(it.key());
4390 in_use[it.key()] = (*it).m_inUse;
4393 for (
const auto& it2s : devs)
4395 sel = (
current == it2s) ? it2s : sel;
4398 QString usestr = QString(
" -- ");
4399 usestr += tr(
"Warning: already in use");
4401 for (
uint i = 0; i < devs.size(); ++i)
4403 const QString& dev = devs[i];
4404 const QString& name = names[i];
4405 bool dev_in_use = (dev == sel) ?
false : in_use[devs[i]];
4406 QString desc = name + (dev_in_use ? usestr :
"");
4407 addSelection(desc, dev, dev == sel);
4411SatIPDeviceID::SatIPDeviceID(
const CaptureCard &parent) :
4421SatIPDeviceID::~SatIPDeviceID()
4423 delete GetStorage();
4426void SatIPDeviceID::Load(
void)
4431void SatIPDeviceID::SetTuner(
const QString &tuner)
4436SatIPDeviceAttribute::SatIPDeviceAttribute(
const QString& label,
const QString& helptext)
4439 setHelpText(helptext);
std::vector< ChannelInfo > ChannelInfoList
TransTextEditSetting * m_cardInfo
void probeCard(const QString &device)
ASIConfigurationGroup(CaptureCard &parent, CardType &cardType)
ASIDevice(const CaptureCard &parent)
void fillSelections(const QString ¤t)
Adds all available cards to list If current is >= 0 it will be considered available even if no device...
AudioDevice(const CaptureCard &parent)
AudioRateLimit(const CaptureCard &parent)
BouquetID(const VideoSource &parent, signed int value, signed int min_val)
QString GetSetClause(MSqlBindings &bindings) const override
const CaptureCard & m_parent
QString GetWhereClause(MSqlBindings &bindings) const override
int getCardID(void) const
void ShowDeleteAllCaptureCardsDialog(void) const
void DeleteAllCaptureCardsOnHost(bool doDelete)
void(CaptureCardEditor::*)(void) const CCESlotConst
void(CaptureCardEditor::*)(void) CCESlot
void DeleteAllCaptureCards(bool doDelete)
void ShowDeleteAllCaptureCardsDialogOnHost(void) const
void AddSelection(const QString &label, CCESlot slot)
CaptureCardGroup(CaptureCard &parent)
~CaptureCardSpinBoxSetting() override
void setValueMs(std::chrono::duration< T > newSecs)
CaptureCardSpinBoxSetting(const CaptureCard &parent, std::chrono::milliseconds min_val, std::chrono::milliseconds max_val, std::chrono::milliseconds step, const QString &setting)
void setValueMs(std::chrono::milliseconds newValue)
CaptureCardTextEditSetting(const CaptureCard &parent, const QString &setting)
~CaptureCardTextEditSetting() override
Hostname(const CaptureCard &parent)
void deleteEntry(void) override
QString GetRawCardType(void) const
bool canDelete(void) override
int getCardID(void) const
CaptureCard(bool use_card_group=true)
static void fillSelections(GroupSetting *setting)
static void fillSelections(MythUIComboBoxSetting *setting)
CardType(const CaptureCard &parent)
static int GetASIDeviceNumber(const QString &device, QString *error=nullptr)
static bool IsTunerSharingCapable(const QString &rawtype)
static INPUT_TYPES toInputType(const QString &name)
static void GetDeviceInputNames(const QString &device, const QString &inputtype, QStringList &inputs)
static bool IsUnscanable(const QString &rawtype)
static uint CreateInputGroup(const QString &name)
static QString GetRawInputType(uint inputid)
static QString GetAudioDevice(uint inputid)
static QString ProbeDVBFrontendName(const QString &device)
Returns the input type from the video device.
static QString ProbeDVBType(const QString &device)
static bool InputSetMaxRecordings(uint parentid, uint max_recordings)
static QStringList ProbeDeliverySystems(const QString &device)
static uint CreateDeviceInputGroup(uint inputid, const QString &type, const QString &host, const QString &device)
static QString GetStartChannel(uint inputid)
static QString GetDeviceLabel(const QString &inputtype, const QString &videodevice)
static QString GetVBoxdesc(const QString &id, const QString &ip, const QString &tunerNo, const QString &tunerType)
Get a nicely formatted string describing the device.
static QStringList GetVideoDevices(const QString &rawtype, QString hostname=QString())
Returns the videodevices of the matching inputs, duplicates removed.
static bool HasTuner(const QString &rawtype, const QString &device)
static QString GetDeliverySystemFromDB(uint inputid)
static bool UnlinkInputGroup(uint inputid, uint inputgroupid)
static bool LinkInputGroup(uint inputid, uint inputgroupid)
static QString GetVideoDevice(uint inputid)
static bool IsInNeedOfExternalInputConf(uint inputid)
static void ClearVideoDeviceCache()
static uint CloneCard(uint src_inputid, uint dst_inputid)
static bool IsV4L(const QString &rawtype)
static std::vector< uint > GetChildInputIDs(uint inputid)
static QString GetDeviceName(dvb_dev_type_t type, const QString &device)
static bool IsEncoder(const QString &rawtype)
static bool DeleteInput(uint inputid)
static QString ProbeDefaultDeliverySystem(const QString &device)
static QStringList ProbeVideoDevices(const QString &rawtype)
static bool IsCableCardPresent(uint inputid, const QString &inputType)
static bool GetV4LInfo(int videofd, QString &input, QString &driver, uint32_t &version, uint32_t &capabilities)
static bool DeleteAllInputs(void)
static QStringList ProbeAudioInputs(const QString &device, const QString &inputtype=QString())
static uint GetDeviceInputGroup(uint inputid)
ChannelTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::duration< T > min_secs)
ChannelTimeout(const CaptureCard &parent, std::chrono::duration< T > value, std::chrono::duration< T > min_secs)
ChannelTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::milliseconds min_val)
static void SortChannels(ChannelInfoList &list, const QString &order, bool eliminate_duplicates=false)
static ChannelInfoList GetAllChannels(uint sourceid)
Returns channels that are not connected to an input and channels that are not marked as visible.
CommandPath(const CaptureCard &parent)
QString GetColumnName(void) const
void fillSelections(const QString ¤t)
Adds all available cards to list If current is >= 0 it will be considered available even if no device...
DVBCardNum(const CaptureCard &parent)
DVBCardType(const CaptureCard &parent)
void reloadDiseqcTree(const QString &device)
DiSEqCDevTree * m_diseqcTree
DVBConfigurationGroup(CaptureCard &a_parent, CardType &cardType)
~DVBConfigurationGroup() override
SignalTimeout * m_signalTimeout
ChannelTimeout * m_channelTimeout
void probeCard(const QString &videodevice)
DVBTuningDelay * m_tuningDelay
DVBEITScan(const CaptureCard &parent)
DVBNetID(const VideoSource &parent, signed int value, signed int min_val)
~DVBNoSeqStart() override
DVBNoSeqStart(const CaptureCard &parent)
DVBOnDemand(const CaptureCard &parent)
DVBTuningDelay(const CaptureCard &parent)
DemoConfigurationGroup(CaptureCard &parent, CardType &cardtype)
void probeCard(const QString &device)
DVB-S device settings class.
bool Store(uint card_input_id) const
Stores configuration chain to DB for specified card input id.
bool Load(uint card_input_id)
Loads configuration chain from DB for specified card input id.
bool Load(const QString &device)
Loads the device tree from the database.
bool Store(uint cardid, const QString &device="")
Stores the device tree to the database.
static bool Exists(int cardid)
Check if a Diseqc device tree exists.
static void InvalidateTrees(void)
Invalidate cached trees.
DishNetEIT(const CardInput &parent)
EITOnly_config(const VideoSource &_parent, StandardSetting *_setting)
~ExternalChannelCommand() override
ExternalChannelCommand(const CardInput &parent)
FileDevice(const CaptureCard &parent)
FirewireConnection(const CaptureCard &parent)
~FirewireConnection() override
const FirewireGUID * m_guid
void SetGUID(const QString &_guid)
static std::vector< AVCInfo > GetSTBList(void)
static QString GetModelName(uint vendor_id, uint model_id)
AVCInfo GetAVCInfo(const QString &guid) const
FirewireGUID(const CaptureCard &parent)
QMap< QString, AVCInfo > m_guidToAvcInfo
const FirewireGUID * m_guid
FirewireModel(const CaptureCard &parent, const FirewireGUID *_guid)
void SetGUID(const QString &_guid)
FirewireSpeed(const CaptureCard &parent)
~FirewireSpeed() override
FreqTableSelector(const VideoSource &parent)
~FreqTableSelector() override
void probeCard(const QString &device)
GroupSetting * m_cardInfo
TunerCardAudioInput * m_audioInput
HDPVRConfigurationGroup(CaptureCard &parent, CardType &cardtype)
static QString TestMimeType(const QString &sFileName)
IPTVHost(const CaptureCard &parent)
void setValue(int value) override
ImportConfigurationGroup(CaptureCard &parent, CardType &cardtype)
void probeCard(const QString &device)
~InstanceCount() override
InstanceCount(const CardInput &parent)
LCNOffset(const VideoSource &parent, signed int value, signed int min_val)
LiveTVOrder(const CardInput &parent, int _value)
void probeCard(const QString &device)
MPEGConfigurationGroup(CaptureCard &parent, CardType &cardtype)
GroupSetting * m_cardInfo
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetHostName(void)
QString GetSetting(const QString &key, const QString &defaultval="")
static void DBError(const QString &where, const MSqlQuery &query)
MythScreenStack * GetMainStack()
MythScreenStack * GetStack(const QString &Stackname)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Screen in which all other widgets are contained and rendered.
virtual bool Create(void)
uint Wait(std::chrono::seconds timeout=0s)
void Run(std::chrono::seconds timeout=0s)
Runs a command inside the /bin/sh shell. Returns immediately.
Dialog prompting the user to enter a text string.
void setValue(const QString &newValue) override
void addSelection(const QString &label, QString value=QString(), bool select=false)
QString getValueLabel(void) const
void fillSelectionsFromDir(const QDir &dir, bool absPath=true)
void setValue(int value) override
int getValueIndex(const QString &value) const
NoGrabber_config(const VideoSource &_parent)
PresetTuner(const CardInput &parent)
QuickTune(const CardInput &parent)
RegionID(const VideoSource &parent, signed int value, signed int min_val)
~ScanFrequencyStart() override
ScanFrequencyStart(const VideoSource &parent)
SchedGroupFalse(const CaptureCard &parent)
~SchedGroupFalse() override
SchedGroup(const CardInput &parent)
~ScheduleOrder() override
ScheduleOrder(const CardInput &parent, int _value)
SignalTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::milliseconds min_val)
SignalTimeout(const CaptureCard &parent, std::chrono::duration< T > value, std::chrono::duration< T > min_secs)
SignalTimeout(const CaptureCard &parent, std::chrono::milliseconds value, std::chrono::duration< T > min_secs)
SkipBtAudio(const CaptureCard &parent)
SourceID(const CardInput &parent)
static bool GetListingsLoginData(uint sourceid, QString &grabber, QString &userid, QString &passwd, QString &lineupid)
static bool DeleteSource(uint sourceid)
static bool DeleteAllSources(void)
static uint GetChannelCount(uint sourceid)
static bool UpdateChannelsFromListings(uint sourceid, const QString &inputtype=QString(), bool wait=false)
virtual void addChild(StandardSetting *child)
StandardSetting * m_parent
virtual void setReadOnly(bool readonly)
void addTargetedChild(const QString &value, StandardSetting *setting)
virtual void clearSettings()
void settingsChanged(StandardSetting *selectedSetting=nullptr)
virtual void setHelpText(const QString &str)
StandardSetting * getParent() const
void setVisible(bool visible)
virtual QList< StandardSetting * > * getSubSettings()
virtual void setValue(const QString &newValue)
Storage * GetStorage(void) const
void valueChanged(const QString &newValue)
virtual QString getValue(void) const
virtual void setEnabled(bool enabled)
virtual void setLabel(QString str)
void SetSourceID(const QString &sourceid)
virtual QString GetDBValue(void) const =0
virtual void Load(void)=0
QString m_loadedFreqTable
void SetSourceID(uint sourceid)
TransFreqTableSelector(uint sourceid)
UseEIT(const VideoSource &parent)
GroupSetting * m_cardInfo
void probeCard(const QString &device)
V4L2encGroup(CaptureCard &parent, CardType &cardType)
QString DriverName(void) const
bool HasSlicedVBI(void) const
QString CardName(void) const
V4LConfigurationGroup(CaptureCard &parent, CardType &cardtype, const QString &inputtype)
void probeCard(const QString &device)
GroupSetting * m_cardInfo
VBIDevice(const CaptureCard &parent)
uint fillSelectionsFromDir(const QDir &dir, const QString &card, const QString &driver)
uint setFilter(const QString &card, const QString &driver)
void fillSelectionsFromDir(const QDir &dir, bool absPath=true)
VBoxDeviceList m_deviceList
VBoxDeviceID * m_deviceId
VBoxDeviceIDList * m_deviceIdList
void FillDeviceList(void)
VBoxTunerIndex * m_cardTuner
VBoxConfigurationGroup(CaptureCard &parent, CardType &cardtype)
void fillSelections(const QString ¤t)
Adds all available device-tuner combinations to list.
VBoxDeviceID * m_deviceId
const CaptureCard & m_parent
VBoxDeviceList * m_deviceList
VBoxTunerIndex * m_cardTuner
void UpdateDevices(const QString &v)
VBoxDeviceIDList(VBoxDeviceID *deviceid, StandardSetting *desc, VBoxIP *cardip, VBoxTunerIndex *cardtuner, VBoxDeviceList *devicelist, const CaptureCard &parent)
void SetTuner(const QString &tuner)
void SetOverrideDeviceID(const QString &deviceid)
VBoxDeviceID(const CaptureCard &parent)
void SetIP(const QString &ip)
QString m_overrideDeviceId
void NewIP(const QString &)
void SetOldValue(const QString &s)
void setEnabled(bool e) override
void UpdateDevices(const QString &v)
void UpdateDevices(const QString &v)
void setEnabled(bool e) override
void NewTuner(const QString &)
void SetOldValue(const QString &s)
void fillSelectionsFromDir(const QDir &dir, bool absPath=true)
VideoDevice(const CaptureCard &parent, uint minor_min=0, uint minor_max=UINT_MAX, const QString &card=QString(), const QRegularExpression &driver=QRegularExpression())
QString Driver(void) const
uint fillSelectionsFromDir(const QDir &dir, uint minor_min, uint minor_max, const QString &card, const QRegularExpression &driver, bool allow_duplicates)
QMap< uint, uint > m_minorList
QString GetWhereClause(MSqlBindings &bindings) const override
const VideoSource & m_parent
QString GetSetClause(MSqlBindings &bindings) const override
void DeleteAllSources(bool doDelete)
static bool cardTypesInclude(int SourceID, const QString &thecardtype)
void(VideoSourceEditor::*)(void) VSESlot
void ShowDeleteAllSourcesDialog(void) const
void(VideoSourceEditor::*)(void) const VSESlotConst
void AddSelection(const QString &label, VSESlot slot)
VideoSourceSelector(uint _initial_sourceid, QString _card_types, bool _must_have_mplexid)
VideoSourceShow(uint _initial_sourceid)
static void fillSelections(GroupSetting *setting)
int getSourceID(void) const
QString getSourceName(void) const
bool canDelete(void) override
void deleteEntry(void) override
void LoadXMLTVGrabbers(QStringList name_list, QStringList prog_list)
static QStringList m_nameList
static QStringList m_progList
XMLTVGrabber(const VideoSource &parent)
const VideoSource & m_parent
QStringList m_grabberArgs
const VideoSource & m_parent
XMLTV_generic_config(const VideoSource &_parent, const QString &_grabber, StandardSetting *_setting)
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)
@ GENERIC_EXIT_OK
Exited with no error.
const CHANLISTS_vec gChanLists
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
MythMainWindow * GetMythMainWindow(void)
@ kMSStdOut
allow access to stdout
@ kMSRunShell
run process through shell
@ kMSDontDisableDrawing
avoid disabling UI drawing
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
VERBOSE_PREAMBLE Most true
static void IPTVConfigurationGroup(CaptureCard &parent, CardType &cardType)
QMap< QString, VBoxDevice > VBoxDeviceList
static bool is_grabber_external(const QString &grabber)