6#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__OpenBSD__) || defined(_WIN32)
9#include <sys/sysmacros.h>
17#include <QCoreApplication>
31#include "libmythbase/mythconfig.h"
61#include HDHOMERUN_HEADERFILE
66 bool _must_have_mplexid) :
67 m_initialSourceId(_initial_sourceid),
68 m_cardTypes(
std::move(_card_types)),
69 m_mustHaveMplexId(_must_have_mplexid)
74 "Select a video source that is connected to one "
75 "or more capture cards. Default is the video source "
76 "selected in the Channel Editor page."
85 "SELECT DISTINCT videosource.name, videosource.sourceid "
86 "FROM capturecard, videosource";
91 "WHERE capturecard.sourceid = videosource.sourceid AND "
92 " capturecard.hostname = :HOSTNAME ";
96 querystr += QString(
" AND capturecard.cardtype in %1 ")
103 " AND channel.sourceid = videosource.sourceid "
104 " AND channel.mplexid != 32767 "
105 " AND channel.mplexid != 0 ";
116 for (; query.
next(); cnt++)
119 query.
value(1).toString());
134 m_initialSourceId(_initial_sourceid)
139 "The video source that is "
140 "selected in the Channel Editor page."
149 "SELECT DISTINCT videosource.name, videosource.sourceid "
150 "FROM capturecard, videosource "
151 "WHERE capturecard.sourceid = videosource.sourceid AND "
152 " capturecard.hostname = :HOSTNAME AND "
153 " videosource.sourceid = :SOURCEID ";
178 setLabel(QObject::tr(
"Max recordings"));
182 "Maximum number of simultaneous recordings MythTV will "
183 "attempt using this device. If set to a value other than "
184 "1, MythTV can sometimes record multiple programs on "
185 "the same multiplex or overlapping copies of the same "
186 "program on a single channel."
202 setLabel(QObject::tr(
"Schedule as group"));
206 "Schedule all virtual inputs on this device as a group. "
207 "This is more efficient than scheduling each input "
208 "individually. Additional, virtual inputs will be "
209 "automatically added as needed to fulfill the recording "
222 QString sourceidTag(
":WHERESOURCEID");
224 QString query(
"sourceid = " + sourceidTag);
233 QString sourceidTag(
":SETSOURCEID");
236 QString query(
"sourceid = " + sourceidTag +
", " +
247 QString cardidTag(
":WHERECARDID");
249 QString query(
"cardid = " + cardidTag);
258 QString cardidTag(
":SETCARDID");
261 QString query(
"cardid = " + cardidTag +
", " +
278 setLabel(QObject::tr(
"Listings grabber"));
292 QObject::tr(
"Transmitted guide only (EIT)"),
"eitonly");
303#pragma message( "tv_find_grabbers is not supported yet on windows." )
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");
360 "UPDATE videosource "
361 "SET userid=NULL, password=NULL "
362 "WHERE xmltvgrabber NOT IN ( 'technovera' )");
369 if (name_list.size() != prog_list.size())
376 for (
uint i = 0; i < (
uint) name_list.size(); i++)
384 if (!selValue.isEmpty())
407 std::chrono::milliseconds min_val,
408 std::chrono::milliseconds max_val,
409 std::chrono::milliseconds step,
410 const QString &setting) :
412 min_val.count(), max_val.count(), step.count())
424 template<typename T, typename = std::enable_if_t<!std::is_integral<T>()>>
426 {
setValueMs(duration_cast<std::chrono::milliseconds>(newSecs)); }
433 const QString &setting) :
450 setLabel(QObject::tr(
"Scan Frequency"));
451 setHelpText(QObject::tr(
"The frequency to start scanning this video source. "
452 "This is then default for 'Full Scan (Tuned)' channel scanning. "
453 "Frequency value in Hz for DVB-T/T2/C, in kHz for DVB-S/S2. "
454 "Leave at 0 if not known. "));
470 setLabel(QObject::tr(
"Network ID"));
473 setHelpText(QObject::tr(
"If your provider has asked you to configure a "
474 "specific network identifier (Network_ID), "
475 "enter it here. Leave it at -1 otherwise."));
492 setLabel(QObject::tr(
"Bouquet ID"));
493 setHelpText(QObject::tr(
"Bouquet ID for Freesat or Sky on satellite Astra-2 28.2E. "
494 "Leave this at 0 if you do not receive this satellite. "
495 "This is needed to get the Freesat and Sky channel numbers. "
496 "Value 272 selects Freesat bouquet 'England HD'. "
497 "See the MythTV Wiki https://www.mythtv.org/wiki/DVB_UK."));
515 setHelpText(QObject::tr(
"Region ID for Freesat or Sky on satellite Astra-2 28.2E. "
516 "Leave this at 0 you do not receive this satellite. "
517 "This is needed to get the Freesat and Sky channel numbers. "
518 "Value 1 selects region London. "
519 "See the MythTV Wiki https://www.mythtv.org/wiki/DVB_UK."));
536 setLabel(QObject::tr(
"Logical Channel Number Offset"));
537 setHelpText(QObject::tr(
"The offset is added to each logical channel number found "
538 "during a scan of a DVB video source. This makes it possible "
539 "to give different video sources a non-overlapping range "
540 "of channel numbers. Leave at 0 if you have only one video source "
541 "or if the video sources do not have DVB logical channel numbers."));
554 setLabel(QObject::tr(
"Channel frequency table"));
560 setHelpText(QObject::tr(
"Use default unless this source uses a "
561 "different frequency table than the system wide table "
562 "defined in the General settings."));
571 m_sourceId(_sourceid)
573 setLabel(QObject::tr(
"Channel frequency table"));
592 "WHERE sourceid = :SOURCEID");
618 LOG(VB_GENERAL, LOG_INFO,
"TransFreqTableSelector::Save(void)");
629 "UPDATE videosource "
630 "SET freqtable = :FREQTABLE "
631 "WHERE sourceid = :SOURCEID");
655 setLabel(QObject::tr(
"Perform EIT scan"));
657 "If enabled, program guide data for channels on this "
658 "source will be updated with data provided by the "
659 "channels themselves 'Over-the-Air'."));
669 const QString& _grabber,
671 m_parent(_parent), m_grabber(_grabber)
675 QString
filename = QString(
"%1/%2.xmltv")
685 config->setHelpText(tr(
"Run XMLTV configure command."));
696 QString err_msg = QObject::tr(
697 "You MUST run 'mythfilldatabase --manual' the first time,\n"
698 "instead of just 'mythfilldatabase'.\nYour grabber does not provide "
699 "channel numbers, so you have to set them manually.");
703 LOG(VB_GENERAL, LOG_ERR, err_msg);
722 : m_useEit(new
UseEIT(_parent))
731 label->setValue(QObject::tr(
"Use only the transmitted guide data."));
733 QObject::tr(
"This will usually only work with ATSC or DVB channels, "
734 "and generally provides data only for the next few days."));
746 : m_useEit(new
UseEIT(_parent))
753 label->setValue(QObject::tr(
"Do not configure a grabber"));
769 setLabel(QObject::tr(
"Video Source Setup"));
791 const QString &thecardtype)
794 query.
prepare(
"SELECT count(cardtype)"
796 " WHERE capturecard.sourceid = :SOURCEID "
797 " AND capturecard.cardtype = :CARDTYPE ;");
799 query.
bindValue(
":CARDTYPE", thecardtype);
803 int count = query.
value(0).toInt();
815 result.
prepare(
"SELECT name, sourceid FROM videosource;");
819 while (result.
next())
822 source->setLabel(result.
value(0).toString());
823 source->loadByID(result.
value(1).toInt());
832 result.
prepare(
"SELECT name, sourceid FROM videosource;");
836 while (result.
next())
839 result.
value(1).toString());
854 uint minor_max = UINT_MAX,
855 const QString& card = QString(),
856 const QRegularExpression& driver = QRegularExpression()) :
859 setLabel(QObject::tr(
"Video device"));
862 QDir dev(
"/dev/v4l",
"video*", QDir::Name, QDir::System);
864 card, driver,
false);
869 card, driver,
false);
872 dev.setPath(
"/dev/dtv");
874 card, driver,
false);
878 dev.setNameFilters(QStringList(
"dtv*"));
880 card, driver,
false);
888 [[maybe_unused]]
bool absPath =
true)
895 const QString& card,
const QRegularExpression& driver,
896 bool allow_duplicates)
899 QFileInfoList entries = dir.entryInfoList();
900 for (
const auto & fi : std::as_const(entries))
903 QString filepath = fi.absoluteFilePath();
904 int err =
lstat(filepath.toLocal8Bit().constData(), &st);
908 LOG(VB_GENERAL, LOG_ERR,
909 QString(
"Could not stat file: %1").arg(filepath));
914 if (!S_ISCHR(st.st_mode))
919 if (minor_min > minor_num || minor_max < minor_num)
927 QByteArray
tmp = filepath.toLatin1();
928 int videofd = open(
tmp.constData(), O_RDWR);
935 auto match = driver.match(driver_name);
936 if ((!driver.pattern().isEmpty() || match.hasMatch()) &&
937 (card.isEmpty() || (card_name == card)))
969 setLabel(QObject::tr(
"VBI device"));
971 setHelpText(QObject::tr(
"Device to read VBI (captions) from."));
977 QDir dev(
"/dev/v4l",
"vbi*", QDir::Name, QDir::System);
983 if ((count == 0U) && !
getValue().isEmpty())
997 [[maybe_unused]]
bool absPath =
true)
1003 const QString &driver)
1005 QStringList devices;
1006 QFileInfoList entries = dir.entryInfoList();
1007 for (
const auto & fi : std::as_const(entries))
1009 QString device = fi.absoluteFilePath();
1010 QByteArray adevice = device.toLatin1();
1011 int vbifd = open(adevice.constData(), O_RDWR);
1018 (driver.isEmpty() || (dn == driver)) &&
1019 (card.isEmpty() || (cn == card)))
1021 devices.push_back(device);
1028 for (
const QString& device : std::as_const(devices))
1031 return (
uint) devices.size();
1044 setHelpText(QObject::tr(
"Specify the command to run, with any "
1045 "needed arguments."));
1062 setLabel(QObject::tr(
"File path"));
1078 setLabel(QObject::tr(
"Audio device"));
1080 QDir dev(
"/dev",
"dsp*", QDir::Name, QDir::System);
1082 dev.setPath(
"/dev/sound");
1085#if CONFIG_AUDIO_ALSA
1089 setHelpText(QObject::tr(
"Device to read audio from, "
1090 "if audio is separate from the video."));
1099 std::chrono::milliseconds min_val) :
1102 setLabel(QObject::tr(
"Signal timeout (ms)"));
1105 "Maximum time (in milliseconds) MythTV waits for "
1106 "a signal when scanning for channels."));
1109 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1111 SignalTimeout(parent, value, duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1112 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1115 duration_cast<
std::chrono::milliseconds>(value),
1116 duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1124 std::chrono::milliseconds min_val) :
1127 setLabel(QObject::tr(
"Tuning timeout (ms)"));
1130 "Maximum time (in milliseconds) MythTV waits for "
1131 "a channel lock. For recordings, if this time is "
1132 "exceeded, the recording will be marked as failed."));
1135 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1137 ChannelTimeout(parent, value, duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1138 template<
typename T,
typename = std::enable_if_t<std::is_
floating_po
int_v<T>> >
1140 ChannelTimeout(parent, value, duration_cast<
std::chrono::milliseconds>(min_secs)) {};
1149 setLabel(QObject::tr(
"Force audio sampling rate"));
1151 QObject::tr(
"If non-zero, override the audio sampling "
1152 "rate in the recording profile when this card is "
1153 "used. Use this if your capture card does not "
1154 "support all of the standard rates."));
1169 setLabel(QObject::tr(
"Do not adjust volume"));
1171 QObject::tr(
"Enable this option for budget BT878 based "
1172 "DVB-T cards such as the AverTV DVB-T which "
1173 "require the audio volume to be left alone."));
1188 setLabel(QObject::tr(
"DVB device"));
1190 QObject::tr(
"When you change this setting, the text below "
1191 "should change to the name and type of your card. "
1192 "If the card cannot be opened, an error message "
1193 "will be displayed."));
1211 std::stable_sort(sdevs.begin(), sdevs.end());
1216 QMap<QString,bool> in_use;
1218 for (
const QString& dev : std::as_const(sdevs))
1220 in_use[dev] =
std::find(db.begin(), db.end(), dev) != db.end();
1221 if (sel.isEmpty() && !in_use[dev])
1225 if (sel.isEmpty() && !sdevs.empty())
1228 QString usestr = QString(
" -- ");
1229 usestr += QObject::tr(
"Warning: already in use");
1231 for (
const QString& dev : std::as_const(sdevs))
1233 QString desc = dev + (in_use[dev] ? usestr :
"");
1234 desc = (
current == dev) ? dev : desc;
1258 setLabel(QObject::tr(
"Delivery system"));
1260 QObject::tr(
"If your card supports more than one delivery system "
1261 "then you can select here the one that you want to use."));
1270 setLabel(QObject::tr(
"Frontend ID"));
1272 QObject::tr(
"Identification string reported by the card. "
1273 "If the message \"Could not get card info...\" appears "
1274 "the card can be in use by another program."));
1285 setLabel(QObject::tr(
"Wait for SEQ start header"));
1288 QObject::tr(
"If enabled, drop packets from the start of a DVB "
1289 "recording until a sequence start header is seen."));
1305 setLabel(QObject::tr(
"Open DVB card on demand"));
1308 QObject::tr(
"If enabled, only open the DVB card when required, "
1309 "leaving it free for other programs at other times."));
1325 setLabel(QObject::tr(
"Use DVB card for active EIT scan"));
1328 QObject::tr(
"If enabled, activate active scanning for "
1329 "program data (EIT). When this option is enabled "
1330 "the DVB card is constantly in use."));
1345 setLabel(QObject::tr(
"DVB tuning delay (ms)"));
1348 QObject::tr(
"Some Linux DVB drivers, in particular for the "
1349 "Hauppauge Nova-T, require that we slow down "
1350 "the tuning process by specifying a delay "
1351 "(in milliseconds)."));
1364 for (
auto & i : list)
1366 QString guid = i.GetGUIDString();
1385 setLabel(QObject::tr(
"Cable box model"));
1386 addSelection(QObject::tr(
"Motorola Generic"),
"MOTO GENERIC");
1387 addSelection(QObject::tr(
"SA/Cisco Generic"),
"SA GENERIC");
1403 QString
help = QObject::tr(
1404 "Choose the model that most closely resembles your set top box. "
1405 "Depending on firmware revision SA4200HD may work better for a "
1425 name.replace(
"Scientific-Atlanta",
"SA");
1426 name.replace(
", Inc.",
"");
1427 name.replace(
"Explorer(R)",
"");
1428 name = name.simplified();
1429 setValue((name.isEmpty()) ?
"" : name);
1438 "firewire_connection"))
1440 setLabel(QObject::tr(
"Connection Type"));
1483#if CONFIG_FIREWIRE_LINUX
1491 model->SetGUID(dev->getValue());
1492 desc->SetGUID(dev->getValue());
1506HDHomeRunDeviceID::HDHomeRunDeviceID(
const CaptureCard &parent,
1507 HDHomeRunConfigurationGroup &_group) :
1515HDHomeRunDeviceID::~HDHomeRunDeviceID()
1517 delete GetStorage();
1520void HDHomeRunDeviceID::Load(
void)
1523 m_group.SetDeviceCheckBoxes(getValue());
1526void HDHomeRunDeviceID::Save(
void)
1528 setValue(m_group.GetDeviceCheckBoxes());
1535 explicit HDHomeRunEITScan(
const CaptureCard &parent) :
1539 setLabel(QObject::tr(
"Use HDHomeRun for active EIT scan"));
1542 QObject::tr(
"If enabled, activate active scanning for "
1543 "program data (EIT). When this option is enabled "
1544 "the HDHomeRun is constantly in use."));
1547 ~HDHomeRunEITScan()
override
1557 explicit UseHDHomeRunDevice(QString &deviceid, QString &model,
1560 setLabel(QObject::tr(
"Use HDHomeRun %1 (%2 %3)")
1561 .arg(deviceid, model, ipaddr));
1564 QObject::tr(
"If enabled, use tuners from this HDHomeRun "
1569HDHomeRunConfigurationGroup::HDHomeRunConfigurationGroup
1572 m_deviceId(new HDHomeRunDeviceID(a_parent, *this))
1579 QMap<QString, HDHomeRunDevice>::iterator dit;
1580 for (dit = m_deviceList.begin(); dit != m_deviceList.end(); ++dit)
1582 HDHomeRunDevice &dev = *dit;
1583 dev.m_checkbox =
new UseHDHomeRunDevice(
1584 dev.m_deviceId, dev.m_model, dev.m_cardIp);
1592 buttonRecOpt->setLabel(tr(
"Recording Options"));
1595 buttonRecOpt->addChild(
new HDHomeRunEITScan(
m_parent));
1599void HDHomeRunConfigurationGroup::FillDeviceList(
void)
1601 m_deviceList.clear();
1607 for (
const auto & dev : std::as_const(devs))
1609 QStringList devinfo = dev.split(
" ");
1610 const QString& devid = devinfo.at(0);
1611 const QString& devip = devinfo.at(1);
1612 const QString& model = devinfo.at(2);
1614 HDHomeRunDevice tmpdevice;
1615 tmpdevice.m_model = model;
1616 tmpdevice.m_cardIp = devip;
1617 tmpdevice.m_deviceId = devid;
1620 tmpdevice.m_checkbox =
nullptr;
1621 m_deviceList[tmpdevice.m_deviceId] = tmpdevice;
1626 QMap<QString, HDHomeRunDevice>::iterator debugit;
1627 for (debugit = m_deviceList.begin(); debugit != m_deviceList.end(); ++debugit)
1629 LOG(VB_GENERAL, LOG_DEBUG, QString(
"%1: %2 %3")
1630 .arg(debugit.key()).arg((*debugit).model)
1631 .arg((*debugit).cardip));
1636void HDHomeRunConfigurationGroup::SetDeviceCheckBoxes(
const QString& devices)
1638 QStringList devstrs = devices.split(
",");
1639 for (
const QString& devstr : std::as_const(devstrs))
1644 QByteArray ba = devstr.toUtf8();
1646 ba.data(),
nullptr);
1649 QString devid = QString(
"%1").arg(
1650 hdhomerun_device_get_device_id(device), 8, 16).toUpper();
1651 hdhomerun_device_destroy(device);
1654 QMap<QString, HDHomeRunDevice>::iterator dit;
1655 dit = m_deviceList.find(devid);
1656 if (dit != m_deviceList.end())
1657 (*dit).m_checkbox->setValue(
true);
1661QString HDHomeRunConfigurationGroup::GetDeviceCheckBoxes(
void)
1665 QStringList devstrs;
1666 QMap<QString, HDHomeRunDevice>::iterator dit;
1667 for (dit = m_deviceList.begin(); dit != m_deviceList.end(); ++dit)
1669 if ((*dit).m_checkbox->boolValue())
1670 devstrs << (*dit).m_deviceId;
1672 QString devices = devstrs.join(
",");
1684 setLabel(QObject::tr(
"IP Address"));
1685 setHelpText(QObject::tr(
"Device IP or ID of a VBox device. eg. '192.168.1.100' or 'vbox_3718'"));
1715 setHelpText(QObject::tr(
"Number and type of the tuner to use. eg '1-DVBT/T2'."));
1789 m_deviceId(deviceid),
1792 m_cardTuner(cardtuner),
1793 m_deviceList(devicelist),
1796 setLabel(QObject::tr(
"Available devices"));
1799 "Device IP or ID, tuner number and tuner type of available VBox devices."));
1810 std::vector<QString> devs;
1811 QMap<QString, bool> in_use;
1817 devs.push_back(it.key());
1818 in_use[it.key()] = (*it).m_inUse;
1821 QString man_addr = VBoxDeviceIDList::tr(
"Manually Enter IP Address");
1822 QString sel = man_addr;
1823 devs.push_back(sel);
1825 for (
const auto & dev : devs)
1826 sel = (
current == dev) ? dev : sel;
1828 QString usestr = QString(
" -- ");
1829 usestr += QObject::tr(
"Warning: already in use");
1831 for (
const auto & dev : devs)
1833 QString desc = dev + (in_use[dev] ? usestr :
"");
1841 else if (sel == man_addr && !
current.isEmpty())
1844 QStringList selection =
current.split(
"-");
1865 if (v == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1870 else if (!v.isEmpty())
1872 if (
m_oldValue == VBoxDeviceIDList::tr(
"Manually Enter IP Address"))
1897 setValue(
"http://mafreebox.freebox.fr/freeboxtv/playlist.m3u");
1900 QObject::tr(
"URL of M3U file containing RTSP/RTP/UDP/HTTP channel URLs,"
1901 " example for HDHomeRun: http://<ipv4>/lineup.m3u and for Freebox:"
1902 " http://mafreebox.freebox.fr/freeboxtv/playlist.m3u."
1921 setLabel(QObject::tr(
"ASI device"));
1939 std::stable_sort(sdevs.begin(), sdevs.end());
1948 QMap<QString,bool> in_use;
1950 for (
const QString& dev : std::as_const(sdevs))
1952 in_use[dev] =
std::find(db.begin(), db.end(), dev) != db.end();
1953 if (sel.isEmpty() && !in_use[dev])
1958 if (sel.isEmpty() && !sdevs.empty())
1961 QString usestr = QString(
" -- ");
1962 usestr += QObject::tr(
"Warning: already in use");
1966 for (
const QString& dev : std::as_const(sdevs))
1968 QString desc = dev + (in_use[dev] ? usestr :
"");
1969 desc = (
current == dev) ? dev : desc;
1971 found |= (dev == sel);
1975 if (!found && !
current.isEmpty())
1977 QString desc =
current +
" -- " +
1978 QObject::tr(
"Warning: unable to open");
2016 if (device.isEmpty())
2033 LOG(VB_GENERAL, LOG_WARNING,
2034 "ASIConfigurationGroup::probeCard(), Warning: " +
error);
2050 device->setHelpText(tr(
"A local file used to simulate a recording."
2051 " Leave empty to use MythEvents to trigger an"
2052 " external program to import recording files."));
2074 QFileInfo fileInfo(device);
2077 if (device.startsWith(
"file:", Qt::CaseInsensitive))
2078 fileInfo.setFile(device.mid(5));
2080 if (fileInfo.exists())
2082 if (fileInfo.isReadable() && (fileInfo.isFile()))
2085 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2089 ci = tr(
"File not readable");
2094 ci = tr(
"File %1 does not exist").arg(device);
2146 for (
const auto & dev : std::as_const(devs))
2148 QStringList devinfo = dev.split(
" ");
2149 const QString&
id = devinfo.at(0);
2150 const QString& ip = devinfo.at(1);
2151 const QString& tunerNo = devinfo.at(2);
2152 const QString& tunerType = devinfo.at(3);
2171 for (
const auto & dev : std::as_const(db))
2173 QMap<QString, VBoxDevice>::iterator dit;
2177 (*dit).m_inUse =
true;
2185CetonSetting::CetonSetting(QString label,
const QString& helptext)
2187 setLabel(std::move(label));
2188 setHelpText(helptext);
2190 this, &CetonSetting::UpdateDevices);
2193void CetonSetting::UpdateDevices(
const QString &v)
2199void CetonSetting::LoadValue(
const QString &value)
2204CetonDeviceID::CetonDeviceID(
const CaptureCard &parent) :
2212CetonDeviceID::~CetonDeviceID()
2214 delete GetStorage();
2217void CetonDeviceID::SetIP(
const QString &ip)
2219 static const QRegularExpression ipV4Regex
2220 {
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){4}$" };
2221 auto match = ipV4Regex.match(ip +
".");
2222 if (match.hasMatch())
2225 setValue(QString(
"%1-RTP.%3").arg(m_ip, m_tuner));
2229void CetonDeviceID::SetTuner(
const QString &tuner)
2231 static const QRegularExpression oneDigit {
"^\\d$" };
2232 auto match = oneDigit.match(tuner);
2233 if (match.hasMatch())
2236 setValue(QString(
"%1-RTP.%2").arg(m_ip, m_tuner));
2240void CetonDeviceID::Load(
void)
2242 GetStorage()->Load();
2246void CetonDeviceID::UpdateValues(
void)
2248 static const QRegularExpression newstyle { R
"(^([0-9.]+)-(\d|RTP)\.(\d)$)" };
2249 auto match = newstyle.match(getValue());
2250 if (match.hasMatch())
2252 emit LoadedIP(match.captured(1));
2253 emit LoadedTuner(match.captured(3));
2259 auto *deviceid =
new CetonDeviceID(parent);
2261 desc->setLabel(tr(
"CetonConfigurationGroup",
"Description"));
2262 auto *ip =
new CetonSetting(tr(
"IP Address"),
2263 tr(
"IP Address of the Ceton device (192.168.200.1 by default)"));
2264 auto *tuner =
new CetonSetting(tr(
"Tuner"),
2265 tr(
"Number of the tuner on the Ceton device (first tuner is number 0)"));
2274 QObject::connect(ip, &CetonSetting::NewValue,
2275 deviceid, &CetonDeviceID::SetIP);
2276 QObject::connect(tuner, &CetonSetting::NewValue,
2277 deviceid, &CetonDeviceID::SetTuner);
2279 QObject::connect(deviceid, &CetonDeviceID::LoadedIP,
2280 ip, &CetonSetting::LoadValue);
2281 QObject::connect(deviceid, &CetonDeviceID::LoadedTuner,
2282 tuner, &CetonSetting::LoadValue);
2306 const QString &inputtype) :
2312 QRegularExpression drv {
"^(?!ivtv|hdpvr|(saa7164(.*))).*$" };
2336 QString cn = tr(
"Failed to open");
2340 QByteArray adevice = device.toLatin1();
2341 int videofd = open(adevice.constData(), O_RDWR);
2345 ci = cn = tr(
"Failed to probe");
2346 else if (!dn.isEmpty())
2347 ci = cn +
" [" + dn +
"]";
2362 QRegularExpression drv {
"^(ivtv|(saa7164(.*)))$" };
2385 QString cn = tr(
"Failed to open");
2389 QByteArray adevice = device.toLatin1();
2390 int videofd = open(adevice.constData(), O_RDWR);
2394 ci = cn = tr(
"Failed to probe");
2395 else if (!dn.isEmpty())
2396 ci = cn +
" [" + dn +
"]";
2412 device->setHelpText(tr(
"A local MPEG file used to simulate a recording."));
2435 QFileInfo fileInfo(device);
2436 if (fileInfo.exists())
2438 if (fileInfo.isReadable() && (fileInfo.isFile()))
2441 cs = tr(
"%1 MB").arg(fileInfo.size() / 1024 / 1024);
2445 ci = tr(
"File not readable");
2450 ci = tr(
"File does not exist");
2458ExternalConfigurationGroup::ExternalConfigurationGroup(
CaptureCard &a_parent,
2465 device->setLabel(tr(
"Command path"));
2466 device->setHelpText(tr(
"A 'black box' application controlled via stdin, status on "
2467 "stderr and TransportStream read from stdout.\n"
2468 "Use absolute path or path relative to the current directory."));
2478 this, &ExternalConfigurationGroup::probeApp);
2480 probeApp(device->getValue());
2483void ExternalConfigurationGroup::probeApp(
const QString & path)
2485 int idx1 = path.startsWith(
"file:", Qt::CaseInsensitive) ? 5 : 0;
2486 int idx2 = path.indexOf(
' ', idx1);
2489 QFileInfo fileInfo(path.mid(idx1, idx2 - idx1));
2491 if (fileInfo.exists())
2493 ci = tr(
"File '%1' is valid.").arg(fileInfo.absoluteFilePath());
2494 if (!fileInfo.isReadable() || !fileInfo.isFile())
2495 ci = tr(
"WARNING: File '%1' is not readable.")
2496 .arg(fileInfo.absoluteFilePath());
2497 if (!fileInfo.isExecutable())
2498 ci = tr(
"WARNING: File '%1' is not executable.")
2499 .arg(fileInfo.absoluteFilePath());
2503 ci = tr(
"WARNING: File '%1' does not exist.")
2504 .arg(fileInfo.absoluteFilePath());
2507 m_info->setValue(ci);
2508 m_info->setHelpText(ci);
2520 QRegularExpression(
"^hdpvr$"));
2543 QString cn = tr(
"Failed to open");
2547 int videofd = open(device.toLocal8Bit().constData(), O_RDWR);
2551 ci = cn = tr(
"Failed to probe");
2552 else if (!dn.isEmpty())
2553 ci = cn +
" [" + dn +
"]";
2569 setLabel(QObject::tr(
"V4L2 encoder devices (multirec capable)"));
2584 if (!device_name.isEmpty())
2591 QString card_name = tr(
"Failed to open");
2592 QString card_info = card_name;
2611 if (audioinput->fillSelections(device_name) > 1)
2613 audioinput->setName(
"AudioInput");
2626 vbidev->setName(
"VBIDevice");
2644 setLabel(QObject::tr(
"Capture Card Setup"));
2646 auto* cardtype =
new CardType(parent);
2661 new HDHomeRunConfigurationGroup(parent, *cardtype));
2671 new SatIPConfigurationGroup(parent, *cardtype));
2675 FirewireConfigurationGroup(parent, *cardtype);
2679 CetonSetting::CetonConfigurationGroup(parent, *cardtype);
2710 new ExternalConfigurationGroup(parent,
2736 "SELECT cardid, videodevice, cardtype, displayname "
2738 "WHERE hostname = :HOSTNAME AND parentid = 0 "
2752 while (query.
next())
2755 QString videodevice = query.
value(1).toString();
2756 QString cardtype = query.
value(2).toString();
2757 QString displayname = query.
value(3).toString();
2759 QString label = QString(
"%1 (%2)")
2763 card->loadByID(cardid);
2764 card->setLabel(label);
2801 if (dev != init_dev)
2803 if (!init_dev.isEmpty())
2822 for (
uint clone : clones)
2839 setLabel(QObject::tr(
"Card type"));
2840 setHelpText(QObject::tr(
"Change the cardtype to the appropriate type for "
2841 "the capture card you are configuring."));
2849 QObject::tr(
"DVB-T/S/C, ATSC or ISDB-T tuner card"),
"DVB");
2854 QObject::tr(
"V4L2 encoder"),
"V4L2ENC");
2856 QObject::tr(
"HD-PVR H.264 encoder"),
"HDPVR");
2861 QObject::tr(
"HDHomeRun networked tuner"),
"HDHOMERUN");
2866 QObject::tr(
"Sat>IP networked tuner"),
"SATIP");
2871 QObject::tr(
"V@Box TV Gateway networked tuner"),
"VBOX");
2876 QObject::tr(
"FireWire cable box"),
"FIREWIRE");
2881 QObject::tr(
"Ceton Cablecard tuner"),
"CETON");
2885 setting->
addSelection(QObject::tr(
"IPTV recorder"),
"FREEBOX");
2890 QObject::tr(
"Analog to MPEG-2 encoder card (PVR-150/250/350, etc)"),
"MPEG");
2892 QObject::tr(
"Analog to MJPEG encoder card (Matrox G200, DC10, etc)"),
"MJPEG");
2894 QObject::tr(
"Analog to MPEG-4 encoder (Plextor ConvertX USB, etc)"),
2897 QObject::tr(
"Analog capture card"),
"V4L");
2901 setting->
addSelection(QObject::tr(
"DVEO ASI recorder"),
"ASI");
2904 setting->
addSelection(QObject::tr(
"Import test recorder"),
"IMPORT");
2905 setting->
addSelection(QObject::tr(
"Demo test recorder"),
"DEMO");
2907 setting->
addSelection(QObject::tr(
"External (black box) recorder"),
2930 setLabel(QObject::tr(
"Input name"));
2946 addSelection(QObject::tr(
"(None)"),
"None");
2948 if (storage ==
nullptr)
2955 while (!inputs.isEmpty())
2957 addSelection(inputs.front());
2968 setLabel(QObject::tr(
"Delivery system"));
2970 "This shows the delivery system (modulation), for instance DVB-T2, "
2971 "that you have selected when you configured the capture card. "
2972 "This must be the same as the modulation used by the video source. "));
2984 setLabel(QObject::tr(
"Display name"));
2986 "This name is displayed on screen when Live TV begins "
2987 "and in various other places. Make sure the last two "
2988 "characters are unique for each input or use a "
2989 "slash ('/') to designate the unique portion."));
3025 setLabel(QObject::tr(
"Video source"));
3026 addSelection(QObject::tr(
"(None)"),
"0");
3037 addSelection(QObject::tr(
"(None)"),
"0");
3046 m_cardInput(parent),
3047 m_groupNum(group_num)
3049 setLabel(QObject::tr(
"Input group") +
3050 QString(
" %1").arg(m_groupNum + 1));
3052 "Leave as 'Generic' unless this input is shared with "
3053 "another device. Only one of the inputs in an input "
3054 "group will be allowed to record at any given time."));
3057 void Load(
void)
override;
3061 uint inputid = m_cardInput.getInputID();
3064 if (m_groupId && (m_groupId != new_groupid))
3082 LOG(VB_GENERAL, LOG_DEBUG, QString(
"InputGroup::Load() %1 %2")
3083 .arg(m_groupNum).arg(m_cardInput.getInputID()));
3086 uint inputid = m_cardInput.getInputID();
3087 QMap<uint, uint> grpcnt;
3088 std::vector<QString> names;
3089 std::vector<uint> grpid;
3090 std::vector<uint> selected_groupids;
3092 names.push_back(QObject::tr(
"Generic"));
3098 "SELECT cardinputid, inputgroupid, inputgroupname "
3100 "WHERE inputgroupname LIKE 'user:%' "
3101 "ORDER BY inputgroupid, cardinputid, inputgroupname");
3109 while (query.
next())
3112 if ((inputid != 0U) && (query.
value(0).toUInt() == inputid))
3113 selected_groupids.push_back(groupid);
3117 if (grpcnt[groupid] == 1)
3119 names.push_back(query.
value(2).toString().mid(5, -1));
3120 grpid.push_back(groupid);
3127 if (m_groupNum < selected_groupids.size())
3128 m_groupId = selected_groupids[m_groupNum];
3131 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group num: %1 id: %2")
3132 .arg(m_groupNum).arg(m_groupId));
3135 for (
uint i = 0; i < selected_groupids.size(); i++)
3136 msg += QString(
"%1 ").arg(selected_groupids[i]);
3137 LOG(VB_GENERAL, LOG_DEBUG, msg);
3144 for (
size_t i = 0; i < names.size(); i++)
3146 bool sel = (m_groupId == grpid[i]);
3147 index = (sel) ? i : index;
3150 LOG(VB_GENERAL, LOG_DEBUG, QString(
"grpid %1, name '%2', i %3, s %4")
3151 .arg(grpid[i]).arg(names[i]) .arg(index).arg(sel ?
"T" :
"F"));
3154 addSelection(names[i], QString::number(grpid[i]), sel);
3158 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Group index: %1").arg(index));
3173 setLabel(QObject::tr(
"Use quick tuning"));
3174 addSelection(QObject::tr(
"Never"),
"0",
true);
3175 addSelection(QObject::tr(
"Live TV only"),
"1",
false);
3176 addSelection(QObject::tr(
"Always"),
"2",
false);
3178 "If enabled, MythTV will tune using only the "
3179 "MPEG program number. The program numbers "
3180 "change more often than DVB or ATSC tuning "
3181 "parameters, so this is slightly less reliable. "
3182 "This will also inhibit EIT gathering during "
3183 "Live TV and recording."));
3193 setLabel(QObject::tr(
"External channel change command"));
3195 setHelpText(QObject::tr(
"If specified, this command will be run to "
3196 "change the channel for inputs which have an external "
3197 "tuner device such as a cable box. The first argument "
3198 "will be the channel number."));
3213 setLabel(QObject::tr(
"Preset tuner to channel"));
3215 setHelpText(QObject::tr(
"Leave this blank unless you have an external "
3216 "tuner that is connected to the tuner input of your card. "
3217 "If so, you will need to specify the preset channel for "
3218 "the signal (normally 3 or 4)."));
3230 if (sourceid.isEmpty() || !sourceid.toUInt())
3235 if (storage ==
nullptr)
3242 if (channels.empty())
3244 addSelection(tr(
"Please add channels to this source"),
3245 startChan.isEmpty() ?
"0" : startChan);
3253 bool has_visible =
false;
3254 for (
size_t i = 0; i < channels.size() && !has_visible; i++)
3257 for (
auto & channel : channels)
3259 const QString channum = channel.m_chanNum;
3260 bool sel = channum == startChan;
3261 if (!has_visible || channel.m_visible || sel)
3263 addSelection(channum, channum, sel);
3275 setLabel(QObject::tr(
"Input priority"));
3277 setHelpText(QObject::tr(
"If the input priority is not equal for "
3278 "all inputs, the scheduler may choose to record a show "
3279 "at a later time so that it can record on an input with "
3280 "a higher value."));
3296 setLabel(QObject::tr(
"Schedule order"));
3298 setHelpText(QObject::tr(
"If priorities and other factors are equal "
3299 "the scheduler will choose the available "
3300 "input with the lowest, non-zero value. "
3301 "Setting this value to zero will make the "
3302 "input unavailable to the scheduler."));
3318 setLabel(QObject::tr(
"Live TV order"));
3320 setHelpText(QObject::tr(
"When entering Live TV, the available, local "
3321 "input with the lowest, non-zero value will "
3322 "be used. If no local inputs are available, "
3323 "the available, remote input with the lowest, "
3324 "non-zero value will be used. "
3325 "Setting this value to zero will make the "
3326 "input unavailable to live TV."));
3342 setLabel(QObject::tr(
"Use DishNet long-term EIT data"));
3346 "If you point your satellite dish toward DishNet's birds, "
3347 "you may wish to enable this feature. For best results, "
3348 "enable general EIT collection as well."));
3379 if (
"DVB" == cardtype)
3401 if (
"DVB" == cardtype)
3406 tr(
"Use channel scanner to find channels for this input."));
3409 tr(
"This uses the listings data source to "
3410 "provide the channels for this input.") +
" " +
3411 tr(
"This can take a long time to run."));
3420 interact->setLabel(QObject::tr(
"Interactions between inputs"));
3430 interact->addChild(
new LiveTVOrder(*
this, _cardid));
3434 ingrpbtn->setHelpText(
3435 QObject::tr(
"Input groups are only needed when two or more cards "
3436 "share the same resource such as a FireWire card and "
3437 "an analog card input controlling the same set top box."));
3438 interact->addChild(ingrpbtn);
3444 setObjectName(
"CardInput");
3470 bool enable = (sourceid.toInt() > 0);
3487 auto *settingdialog =
3490 if (settingdialog->Create())
3498 delete settingdialog;
3506 ShowOkPopup(tr(
"Sorry, this Input Group name cannot be blank."));
3510 QString new_name = QString(
"user:") + name;
3513 query.
prepare(
"SELECT inputgroupname "
3515 "WHERE inputgroupname = :GROUPNAME");
3516 query.
bindValue(
":GROUPNAME", new_name);
3526 ShowOkPopup(tr(
"Sorry, this Input Group name is already in use."));
3561 LOG(VB_GENERAL, LOG_ERR,
3562 QString(
"Sorry, %1 cards do not yet support scanning.")
3574 [srcid,
this, num_channels_before]()
3578 if (num_channels_before)
3592 LOG(VB_GENERAL, LOG_ERR,
"You must compile the backend "
3593 "to be able to scan for channels");
3613 cardtype !=
"HDHOMERUN" &&
3614 !num_channels_before)
3616 LOG(VB_GENERAL, LOG_ERR,
"Skipping channel fetch, you need to "
3617 "scan for channels first.");
3626 if (num_channels_before)
3635 QString cardinputidTag(
":WHERECARDID");
3637 QString query(
"cardid = " + cardinputidTag);
3646 QString cardinputidTag(
":SETCARDID");
3649 QString query(
"cardid = " + cardinputidTag +
", " +
3668 query.
prepare(
"SELECT cardid FROM capturecard "
3669 "WHERE cardid = :CARDID AND inputname = :INPUTNAME");
3671 query.
bindValue(
":INPUTNAME", _inputname);
3724 tr(
"Are you sure you want to delete "
3733 tr(
"Are you sure you want to delete "
3734 "ALL capture cards?"),
3742 card->setLabel(tr(
"New capture card"));
3768 "WHERE hostname = :HOSTNAME");
3774 tr(
"Error getting list of cards for this host. "
3775 "Unable to delete capturecards for %1")
3782 while (cards.
next())
3798 AddSelection(QObject::tr(
"(Delete all capture cards on %1)")
3801 AddSelection(QObject::tr(
"(Delete all capture cards)"),
3815 AddSelection(QObject::tr(
"(Delete all video sources)"),
3838 tr(
"Are you sure you want to delete "
3839 "ALL video sources?"),
3857 source->setLabel(tr(
"New video source"));
3879 "SELECT cardid, videodevice, cardtype, displayname "
3881 "WHERE hostname = :HOSTNAME "
3882 " AND parentid = 0 "
3892 while (query.
next())
3895 QString videodevice = query.
value(1).toString();
3896 QString cardtype = query.
value(2).toString();
3897 QString displayname = query.
value(3).toString();
3899 auto *cardinput =
new CardInput(cardtype, videodevice, cardid);
3900 cardinput->loadByID(cardid);
3901 QString inputlabel = QString(
"%1 (%2) -> %3")
3903 displayname, cardinput->getSourceName());
3905 cardinput->setLabel(inputlabel);
3913static QString remove_chaff(
const QString &name)
3916 QString short_name = name;
3917 if (short_name.startsWith(
"LG Electronics"))
3918 short_name = short_name.right(short_name.length() - 15);
3919 if (short_name.startsWith(
"Oren"))
3920 short_name = short_name.right(short_name.length() - 5);
3921 if (short_name.startsWith(
"Nextwave"))
3922 short_name = short_name.right(short_name.length() - 9);
3923 if (short_name.startsWith(
"frontend", Qt::CaseInsensitive))
3924 short_name = short_name.left(short_name.length() - 9);
3925 if (short_name.endsWith(
"VSB/QAM"))
3926 short_name = short_name.left(short_name.length() - 8);
3927 if (short_name.endsWith(
"VSB"))
3928 short_name = short_name.left(short_name.length() - 4);
3929 if (short_name.endsWith(
"DVB-T"))
3930 short_name = short_name.left(short_name.length() - 6);
3936 short_name = short_name.simplified();
3937 if (short_name.startsWith(
"or51211", Qt::CaseInsensitive))
3938 short_name =
"pcHDTV HD-2000";
3939 else if (short_name.startsWith(
"or51132", Qt::CaseInsensitive))
3940 short_name =
"pcHDTV HD-3000";
3941 else if (short_name.startsWith(
"bcm3510", Qt::CaseInsensitive))
3942 short_name =
"Air2PC v1";
3943 else if (short_name.startsWith(
"nxt2002", Qt::CaseInsensitive) ||
3944 short_name.startsWith(
"nxt200x", Qt::CaseInsensitive))
3945 short_name =
"Air2PC v2";
3946 else if (short_name.startsWith(
"lgdt3302", Qt::CaseInsensitive))
3947 short_name =
"DViCO HDTV3";
3948 else if (short_name.startsWith(
"lgdt3303", Qt::CaseInsensitive))
3949 short_name =
"DViCO v2 or Air2PC v3 or pcHDTV HD-5500";
3974 if (videodevice.isEmpty())
3992 QString err_open = tr(
"Could not open card %1").arg(videodevice);
3993 QString err_other = tr(
"Could not get card info for card %1").arg(videodevice);
4039 if (frontend_name.toLower().indexOf(
"usb") >= 0)
4046 if ((frontend_name ==
"DiBcom 3000P/M-C DVB-T") ||
4048 "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"))
4054 QString short_name = remove_chaff(frontend_name);
4055 m_buttonAnalog->setVisible(
4056 short_name.startsWith(
"zarlink zl10353",
4057 Qt::CaseInsensitive) ||
4058 short_name.startsWith(
"wintv hvr 900 m/r: 65008/a1c0",
4059 Qt::CaseInsensitive) ||
4060 short_name.startsWith(
"philips tda10046h",
4061 Qt::CaseInsensitive));
4067 QString short_name = remove_chaff(frontend_name);
4075 if (frontend_name ==
"Nextwave NXT200X VSB/QAM frontend")
4082 if (frontend_name.toLower().indexOf(
"usb") < 0)
4084 m_buttonAnalog->setVisible(
4085 short_name.startsWith(
"pchdtv", Qt::CaseInsensitive) ||
4086 short_name.startsWith(
"dvico", Qt::CaseInsensitive) ||
4087 short_name.startsWith(
"nextwave", Qt::CaseInsensitive));
4100 for (
const auto & item : std::as_const(delsyslist))
4102 LOG(VB_GENERAL, LOG_DEBUG, QString(
"DVBCardType: add deliverysystem:%1")
4110 if (!delsys.isEmpty())
4122 QString dev, QString
type) :
4124 m_lastDevice(
std::move(dev)), m_lastCardType(
std::move(
type))
4126 setLabel(QObject::tr(
"Audio input"));
4127 setHelpText(QObject::tr(
"If there is more than one audio input, "
4128 "select which one to use."));
4141 if (device.isEmpty())
4145 QStringList inputs =
4148 for (
uint i = 0; i < (
uint)inputs.size(); i++)
4153 return inputs.size();
4236 explicit DiSEqCPosition(
const CaptureCard &parent,
int value,
int min_val) :
4240 setLabel(QObject::tr(
"DiSEqC position"));
4241 setHelpText(QObject::tr(
"Position of the LNB on the DiSEqC switch. "
4242 "Leave at 1 if there is no DiSEqC switch "
4243 "and the LNB is directly connected to the SatIP server. "
4244 "This value is used as signal source (attribute src) in "
4245 "the SatIP tune command."));
4249 ~DiSEqCPosition()
override
4255SatIPConfigurationGroup::SatIPConfigurationGroup
4258 m_deviceId(new SatIPDeviceID(a_parent))
4264 m_friendlyName =
new SatIPDeviceAttribute(tr(
"Friendly name"), tr(
"Friendly name of the Sat>IP server"));
4265 m_tunerType =
new SatIPDeviceAttribute(tr(
"Tuner type"), tr(
"Type of the selected tuner"));
4266 m_tunerIndex =
new SatIPDeviceAttribute(tr(
"Tuner index"), tr(
"Index of the tuner on the Sat>IP server"));
4268 m_deviceIdList =
new SatIPDeviceIDList(
4269 m_deviceId, m_friendlyName, m_tunerType, m_tunerIndex, &m_deviceList,
m_parent);
4281 connect(m_deviceIdList, &SatIPDeviceIDList::NewTuner,
4282 m_deviceId, &SatIPDeviceID::SetTuner);
4285void SatIPConfigurationGroup::FillDeviceList(
void)
4287 m_deviceList.clear();
4293 for (
const auto & dev : std::as_const(devs))
4295 QStringList devparts = dev.split(
" ");
4296 const QString&
id = devparts.value(0);
4297 const QString& name = devparts.value(1);
4298 const QString& ip = devparts.value(2);
4299 const QString& tunerno = devparts.value(3);
4300 const QString& tunertype = devparts.value(4);
4303 device.m_deviceId = id;
4304 device.m_cardIP = ip;
4305 device.m_inUse =
false;
4306 device.m_friendlyName = name;
4307 device.m_tunerNo = tunerno;
4308 device.m_tunerType = tunertype;
4309 device.m_mythDeviceId = QString(
"%1:%2:%3").arg(
id, tunertype, tunerno);
4311 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3").arg(name, tunertype, tunerno);
4313 m_deviceList[device.m_mythDeviceId] = device;
4315 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"SatIP: Add %1 '%2' '%3'")
4316 .arg(device.m_mythDeviceId, device.m_friendlyName, friendlyIdentifier));
4322 for (
const auto& dev : std::as_const(db))
4324 auto dit = m_deviceList.find(dev);
4325 if (dit != m_deviceList.end())
4327 (*dit).m_inUse =
true;
4332SatIPDeviceIDList::SatIPDeviceIDList(
4333 SatIPDeviceID *deviceId,
4334 SatIPDeviceAttribute *friendlyName,
4335 SatIPDeviceAttribute *tunerType,
4336 SatIPDeviceAttribute *tunerIndex,
4337 SatIPDeviceList *deviceList,
4339 m_deviceId(deviceId),
4340 m_friendlyName(friendlyName),
4341 m_tunerType(tunerType),
4342 m_tunerIndex(tunerIndex),
4343 m_deviceList(deviceList),
4347 setHelpText(tr(
"Device IP or ID, tuner number and tuner type of available Sat>IP device"));
4350 this, &SatIPDeviceIDList::UpdateDevices);
4353void SatIPDeviceIDList::Load(
void)
4357 int cardid = m_parent.getCardID();
4360 fillSelections(device);
4363void SatIPDeviceIDList::UpdateDevices(
const QString &v)
4365 SatIPDevice dev = (*m_deviceList)[v];
4366 m_deviceId->setValue(dev.m_mythDeviceId);
4367 m_friendlyName->setValue(dev.m_friendlyName);
4368 m_tunerType->setValue(dev.m_tunerType);
4369 m_tunerIndex->setValue(dev.m_tunerNo);
4372void SatIPDeviceIDList::fillSelections(
const QString &cur)
4376 std::vector<QString> names;
4377 std::vector<QString> devs;
4378 QMap<QString, bool> in_use;
4383 SatIPDeviceList::iterator it = m_deviceList->begin();
4384 for(; it != m_deviceList->end(); ++it)
4386 QString friendlyIdentifier = QString(
"%1, %2, Tuner #%3")
4387 .arg((*it).m_friendlyName, (*it).m_tunerType, (*it).m_tunerNo);
4388 names.push_back(friendlyIdentifier);
4390 devs.push_back(it.key());
4391 in_use[it.key()] = (*it).m_inUse;
4394 for (
const auto& it2s : devs)
4396 sel = (
current == it2s) ? it2s : sel;
4399 QString usestr = QString(
" -- ");
4400 usestr += tr(
"Warning: already in use");
4402 for (
uint i = 0; i < devs.size(); ++i)
4404 const QString& dev = devs[i];
4405 const QString& name = names[i];
4406 bool dev_in_use = (dev == sel) ?
false : in_use[devs[i]];
4407 QString desc = name + (dev_in_use ? usestr :
"");
4408 addSelection(desc, dev, dev == sel);
4412SatIPDeviceID::SatIPDeviceID(
const CaptureCard &parent) :
4422SatIPDeviceID::~SatIPDeviceID()
4424 delete GetStorage();
4427void SatIPDeviceID::Load(
void)
4432void SatIPDeviceID::SetTuner(
const QString &tuner)
4437SatIPDeviceAttribute::SatIPDeviceAttribute(
const QString& label,
const QString& helptext)
4440 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)