40#include <sys/select.h>
64 DTVTunerType tuner_type,
const dvb_frontend_parameters& params);
67 uint intermediate_freq,
bool can_fec_auto,
bool do_tune =
true);
72#define LOC QString("DVBChan[%1](%2): ").arg(m_inputId).arg(DVBChannel::GetDevice())
75#define DTV_STAT_FULL_DEBUG 0
88 m_key += QString(
":%1")
98 else if (master !=
nullptr)
122 QMutexLocker master_locker(&(master->m_hwLock));
123 QMutexLocker new_master_locker(&(new_master->
m_hwLock));
124 new_master->
m_isOpen = master->m_isOpen;
148 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Closing DVB channel");
152 IsOpenMap::iterator it =
m_isOpen.find(who);
159 if (master !=
nullptr && master !=
this)
193 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Opening DVB channel");
198 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Use legacy DVBv3 API");
212 if (!master->
Open(who))
250 QByteArray devn = dvbdev.toLatin1();
252 for (
int tries = 1; ; ++tries)
259 LOG(VB_GENERAL, LOG_WARNING,
LOC +
260 "Opening DVB frontend device failed." +
ENO);
262 if (tries >= 5 || (errno != EBUSY && errno != EAGAIN))
264 LOG(VB_GENERAL, LOG_ERR,
LOC +
265 QString(
"Failed to open DVB frontend device due to "
266 "fatal error or too many attempts."));
269 std::this_thread::sleep_for(50ms);
274 dvb_frontend_info
info {};
277 LOG(VB_GENERAL, LOG_ERR,
LOC +
278 "Failed to get frontend information." +
ENO);
292 LOG(VB_CHANNEL, LOG_INFO,
LOC +
296 LOG(VB_CHANNEL, LOG_INFO, QString(
" %1").arg(capstr));
301 std::array<struct dtv_property,2> prop = {};
302 struct dtv_properties cmd = {};
304 prop[0].cmd = DTV_API_VERSION;
305 prop[1].cmd = DTV_DELIVERY_SYSTEM;
308 cmd.props = prop.data();
312 prop[0].u.data = 0x300;
313 prop[1].u.data = SYS_UNDEFINED;
339 if (
info.caps & FE_CAN_2G_MODULATION)
344 if (
info.caps & FE_CAN_TURBO_FEC)
359 if (
info.caps & FE_CAN_2G_MODULATION)
366 if (
info.caps & (FE_CAN_8VSB | FE_CAN_16VSB))
371 if (
info.caps & (FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO))
373 delsys = SYS_DVBC_ANNEX_B;
381 LOG(VB_GENERAL, LOG_ERR,
LOC +
382 QString(
"Frontend '%1' delivery system not detected.").arg(
m_frontendName));
391 std::array<struct dtv_property,1> prop = {};
392 struct dtv_properties cmd = {};
394 prop[0].cmd = DTV_ENUM_DELSYS;
397 cmd.props = prop.data();
401 LOG(VB_GENERAL, LOG_ERR,
LOC +
402 QString(
"Frontend '%1' FE_GET_PROPERTY failed.").arg(
m_frontendName));
407 int p_num_systems = prop[0].u.buffer.len;
408 for (
int i = 0; i < p_num_systems; i++)
414 if (p_num_systems == 0) {
415 LOG(VB_GENERAL, LOG_ERR,
LOC +
416 QString(
"Frontend '%1' returned 0 supported delivery systems!").arg(
m_frontendName));
426 LOG(VB_CHANNEL, LOG_INFO,
LOC +
428 LOG(VB_CHANNEL, LOG_INFO,
LOC +
429 QString(
"DVB version:0x%1 ").arg(
m_version,3,16,QChar(
'0')) +
434 LOG(VB_CHANNEL, LOG_INFO,
"Supported delivery systems: ");
439 LOG(VB_CHANNEL, LOG_INFO, QString(
" [%1]")
440 .arg(delsys.toString()));
444 LOG(VB_CHANNEL, LOG_INFO, QString(
" %1")
445 .arg(delsys.toString()));
449 uint32_t frq_min =
info.frequency_min;
450 uint32_t frq_max =
info.frequency_max;
451 uint32_t frq_stp =
info.frequency_stepsize;
453 if (
info.type == FE_QPSK)
461 LOG(VB_CHANNEL, LOG_INFO, QString(
"Frequency range for the current standard:"));
462 LOG(VB_CHANNEL, LOG_INFO, QString(
" From: %1 Hz").arg(frq_min,11));
463 LOG(VB_CHANNEL, LOG_INFO, QString(
" To: %1 Hz").arg(frq_max,11));
464 LOG(VB_CHANNEL, LOG_INFO, QString(
" Step: %1 Hz").arg(frq_stp,11));
466 if (
info.type == FE_QPSK ||
info.type == FE_QAM)
468 LOG(VB_CHANNEL, LOG_INFO, QString(
"Symbol rate ranges for the current standard:"));
469 LOG(VB_CHANNEL, LOG_INFO, QString(
" From: %1 Baud").arg(
info.symbol_rate_min,11));
470 LOG(VB_CHANNEL, LOG_INFO, QString(
" To: %1 Baud").arg(
info.symbol_rate_max,11));
483 LOG(VB_CHANNEL, LOG_INFO,
LOC +
484 QString(
"Change delivery system from %1 to %2.")
493 LOG(VB_CHANNEL, LOG_INFO,
LOC +
494 QString(
"Delivery system in database and in card equal, leave at %1.")
500 LOG(VB_CHANNEL, LOG_INFO,
LOC +
518 LOG(VB_CHANNEL, LOG_INFO,
LOC +
519 QString(
"Requested %1 channel is on SCR system")
524 LOG(VB_CHANNEL, LOG_INFO,
LOC +
525 QString(
"Requested %1 channel is on non-SCR system")
550 IsOpenMap::const_iterator it =
m_isOpen.find(
this);
571 LOG(VB_GENERAL, LOG_WARNING,
LOC +
572 QString(
"Frequency setting (%1) is out of range (min/max:%2/%3)")
582 LOG(VB_GENERAL, LOG_WARNING,
LOC +
583 "'Auto' inversion parameter unsupported by this driver, "
584 "falling back to 'off'.");
603 LOG(VB_GENERAL, LOG_WARNING,
LOC +
604 QString(
"Symbol Rate setting (%1) is out of range (min/max:%2/%3)")
611 LOG(VB_GENERAL, LOG_WARNING,
LOC +
612 "Selected fec_inner parameter unsupported by this driver.");
617 LOG(VB_GENERAL, LOG_WARNING,
LOC +
618 "Selected modulation parameter unsupported by this driver.");
634 LOG(VB_GENERAL, LOG_WARNING,
LOC +
635 "Selected code_rate_hp parameter unsupported by this driver.");
640 LOG(VB_GENERAL, LOG_WARNING,
LOC +
641 "Selected code_rate_lp parameter unsupported by this driver.");
647 LOG(VB_GENERAL, LOG_WARNING,
LOC +
648 "'Auto' bandwidth parameter unsupported by this driver.");
654 LOG(VB_GENERAL, LOG_WARNING,
LOC +
655 "'Auto' transmission_mode parameter unsupported by this driver.");
661 LOG(VB_GENERAL, LOG_WARNING,
LOC +
662 "'Auto' guard_interval parameter unsupported by this driver.");
668 LOG(VB_GENERAL, LOG_WARNING,
LOC +
669 "'Auto' hierarchy parameter unsupported by this driver. ");
674 LOG(VB_GENERAL, LOG_WARNING,
LOC +
675 "Selected modulation parameter unsupported by this driver.");
748 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Tune(): Invalid input."));
751 return Tune(tuning,
false,
false);
780 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tuning on slave channel");
782 bool ok = master->
Tune(tuning, force_reset,
false);
789 uint intermediate_freq = 0;
790 bool can_fec_auto =
false;
795 LOG(VB_GENERAL, LOG_ERR,
LOC +
796 "DVB-S/S2 needs device tree for LNB handling");
804 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Tune(): Card not open!");
812 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tuning parameters:");
814 LOG(VB_CHANNEL, LOG_INFO,
" New: " + tuning.
toString());
819 int freq_mult = (is_dvbs) ? 1 : 1000;
820 QString suffix = (is_dvbs) ?
"kHz" :
"Hz";
824 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Tune(): Tuning to %1%2")
825 .arg(intermediate_freq ? intermediate_freq : tuning.
m_frequency)
832 if (tuning_delay > 0ms)
834 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Next tuning after less than %1ms, delaying by %2ms")
836 std::this_thread::sleep_for(tuning_delay);
852 LOG(VB_GENERAL, LOG_ERR,
LOC +
853 "Tune(): Failed to setup DiSEqC devices");
861 LOG(VB_GENERAL, LOG_ERR,
LOC +
862 "Tune(): No LNB for this configuration");
896 struct dtv_property p_clear = {};
897 struct dtv_properties cmdseq_clear = {};
899 p_clear.cmd = DTV_CLEAR;
900 cmdseq_clear.num = 1;
901 cmdseq_clear.props = &p_clear;
903 if ((ioctl(
m_fdFrontend, FE_SET_PROPERTY, &cmdseq_clear)) < 0)
905 LOG(VB_GENERAL, LOG_ERR,
LOC +
906 "Tune(): Clearing DTV properties cache failed." +
ENO);
914 LOG(VB_GENERAL, LOG_ERR,
LOC +
915 "Failed to convert DTVMultiplex to DTV_PROPERTY sequence");
921 for (
uint i = 0; i < cmds->num; i++)
923 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
924 QString(
"prop %1: cmd = %2, data %3")
925 .arg(i).arg(cmds->props[i].cmd)
926 .arg(cmds->props[i].u.data));
937 LOG(VB_GENERAL, LOG_ERR,
LOC +
938 "Tune(): Setting Frontend tuning parameters failed." +
ENO);
946 m_tunerType, tuning, intermediate_freq, can_fec_auto);
950 LOG(VB_GENERAL, LOG_ERR,
LOC +
951 "Tune(): Setting Frontend tuning parameters failed." +
ENO);
967 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Tune(): Tuning to %1%2 skipped, already tuned")
968 .arg(intermediate_freq ? intermediate_freq : tuning.
m_frequency)
975 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tune(): Frequency tuning successful");
994 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Card not open!");
1016 dvb_frontend_parameters params {};
1018 int res = ioctl(
m_fdFrontend, FE_GET_FRONTEND, ¶ms);
1021 LOG(VB_CHANNEL, LOG_ERR,
LOC +
"FE_GET_FRONTEND failed." +
ENO);
1040 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Card not open!");
1070 dvb_frontend_parameters params {};
1073 LOG(VB_GENERAL, LOG_ERR,
LOC +
1074 "Getting Frontend tuning parameters failed." +
ENO);
1101 query.
prepare(
"SELECT chanid, visible "
1102 "FROM channel, capturecard "
1103 "WHERE channel.deleted IS NULL AND "
1104 " capturecard.sourceid = channel.sourceid AND "
1105 " channel.channum = :CHANNUM AND "
1106 " capturecard.cardid = :INPUTID");
1117 while (query.
next())
1119 bool visible = query.
value(1).toInt() > 0;
1122 int chanid = query.
value(0).toInt();
1123 idlist.append(chanid);
1127 if (idlist.isEmpty())
1129 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1130 QString(
"No visible channel ID for %1")
1135 id = idlist.value(0);
1136 if (idlist.count() > 1)
1139 for (
auto chanid : idlist)
1141 sl.append(QString::number(chanid));
1143 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1144 QString(
"Found for '%1' multiple visible channel IDs: %2")
1149 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1150 QString(
"Found visible channel ID %1 for '%2'")
1171 bool haslock = master->
HasLock(ok);
1177#if ((DVB_API_VERSION > 5) || ((DVB_API_VERSION == 5) && (DVB_API_VERSION_MINOR > 10)))
1178 fe_status_t status = FE_NONE;
1180 fe_status_t status = (fe_status_t)0;
1183 int ret = ioctl(
m_fdFrontend, FE_READ_STATUS, &status);
1186 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FE_READ_STATUS failed" +
ENO);
1190 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"%1 status: 0x%2 %3")
1191 .arg(__func__).arg(status,2,16,QChar(
'0')).arg(
toString(status)));
1197 return (status & FE_HAS_LOCK) != 0;
1202 struct dtv_property prop = {};
1203 struct dtv_properties cmd = {};
1205 prop.cmd = DTV_STAT_SIGNAL_STRENGTH;
1211 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_SIGNAL_STRENGTH failed" +
ENO);
1215#if DTV_STAT_FULL_DEBUG
1216 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_SIGNAL_STRENGTH " +
1217 QString(
"res=%1 len=%2 scale=%3 val=%4")
1218 .arg(cmd.props->result)
1219 .arg(cmd.props->u.st.len)
1220 .arg(cmd.props->u.st.stat[0].scale)
1221 .arg(cmd.props->u.st.stat[0].svalue));
1225 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1232 if (cmd.props->u.st.stat[0].scale == FE_SCALE_DECIBEL)
1238 int64_t svalue = cmd.props->u.st.stat[0].svalue;
1239 if (svalue >= -100000 && svalue <= 0)
1242 value = svalue + 100000;
1243 value = value / 100000.0;
1244 value = std::min(value, 1.0);
1247 else if (cmd.props->u.st.stat[0].scale == FE_SCALE_RELATIVE)
1250 value = cmd.props->u.st.stat[0].uvalue / 65535.0;
1282 int ret = ioctl(
m_fdFrontend, FE_READ_SIGNAL_STRENGTH, &sig);
1286 return sig * (1.0 / 65535.0);
1291 struct dtv_property prop = {};
1292 struct dtv_properties cmd = {};
1294 prop.cmd = DTV_STAT_CNR;
1300 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_CNR failed" +
ENO);
1304#if DTV_STAT_FULL_DEBUG
1305 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_CNR " +
1306 QString(
"res=%1 len=%2 scale=%3 val=%4")
1307 .arg(cmd.props->result)
1308 .arg(cmd.props->u.st.len)
1309 .arg(cmd.props->u.st.stat[0].scale)
1310 .arg(cmd.props->u.st.stat[0].svalue));
1314 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1320 if (cmd.props->u.st.stat[0].scale == FE_SCALE_DECIBEL)
1325 value = cmd.props->u.st.stat[0].svalue;
1326 value = value / 50000.0;
1332 else if (cmd.props->u.st.stat[0].scale == FE_SCALE_RELATIVE)
1335 value = cmd.props->u.st.stat[0].uvalue / 65535.0;
1346 double val = master->
GetSNR(ok);
1371 return snr * (1.0 / 65535.0);
1376 std::array<struct dtv_property,2> prop {};
1377 struct dtv_properties cmd = {};
1379 prop[0].cmd = DTV_STAT_POST_ERROR_BIT_COUNT;
1380 prop[1].cmd = DTV_STAT_POST_TOTAL_BIT_COUNT;
1381 cmd.num = prop.size();
1382 cmd.props = prop.data();
1386 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_POST_ERROR_BIT_COUNT failed" +
ENO);
1390#if DTV_STAT_FULL_DEBUG
1391 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_POST_ERROR_BIT_COUNT " +
1392 QString(
"res=%1 len=%2 scale=%3 val=%4 res=%5 len=%6 scale=%7 val=%8")
1393 .arg(cmd.props[0].result)
1394 .arg(cmd.props[0].u.st.len)
1395 .arg(cmd.props[0].u.st.stat[0].scale)
1396 .arg(cmd.props[0].u.st.stat[0].uvalue)
1397 .arg(cmd.props[1].result)
1398 .arg(cmd.props[1].u.st.len)
1399 .arg(cmd.props[1].u.st.stat[0].scale)
1400 .arg(cmd.props[1].u.st.stat[0].uvalue));
1404 bool tmpOk = (ret == 0) &&
1405 (cmd.props[0].u.st.len > 0) &&
1406 (cmd.props[1].u.st.len > 0);
1412 if ((cmd.props[0].u.st.stat[0].scale == FE_SCALE_COUNTER) &&
1413 (cmd.props[1].u.st.stat[0].scale == FE_SCALE_COUNTER) &&
1414 (cmd.props[1].u.st.stat[0].uvalue != 0))
1416 value =
static_cast<double>(
1417 static_cast<long double>(cmd.props[0].u.st.stat[0].uvalue) /
1418 cmd.props[1].u.st.stat[0].uvalue);
1452 return (
double) ber;
1457 struct dtv_property prop = {};
1458 struct dtv_properties cmd = {};
1460 prop.cmd = DTV_STAT_ERROR_BLOCK_COUNT;
1466 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_ERROR_BLOCK_COUNT failed" +
ENO);
1470#if DTV_STAT_FULL_DEBUG
1471 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_ERROR_BLOCK_COUNT " +
1472 QString(
"res=%1 len=%2 scale=%3 val=%4")
1473 .arg(cmd.props[0].result)
1474 .arg(cmd.props[0].u.st.len)
1475 .arg(cmd.props[0].u.st.stat[0].scale)
1476 .arg(cmd.props[0].u.st.stat[0].svalue));
1480 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1486 if (cmd.props->u.st.stat[0].scale == FE_SCALE_COUNTER)
1487 value = cmd.props->u.st.stat[0].uvalue;
1515 uint32_t ublocks = 0;
1516 int ret = ioctl(
m_fdFrontend, FE_READ_UNCORRECTED_BLOCKS, &ublocks);
1520 return static_cast<double>(ublocks);
1533 auto *dvbm =
dynamic_cast<DVBChannel*
>(master);
1534 if (master && !dvbm)
1542 bool is_master = (master ==
this);
1554 struct dvb_frontend_event event {};
1556 while ((ret = ioctl(fd, FE_GET_EVENT, &event)) == 0);
1557 if ((ret < 0) && (EAGAIN != errno) && (EWOULDBLOCK != errno) && (EOVERFLOW != errno))
1559 LOG(VB_CHANNEL, LOG_ERR,
LOC +
1560 QString(
"%1 FE_GET_EVENT failed: ").arg(__func__) +
logStrerror(errno));
1589 auto seconds = duration_cast<std::chrono::seconds>(timeout_ms);
1590 auto usecs = duration_cast<std::chrono::microseconds>(timeout_ms) - seconds;
1591 struct timeval select_timeout = {
1592 static_cast<typeof(select_timeout.tv_sec)
>(seconds.count()),
1593 static_cast<typeof(select_timeout.tv_usec)
>(usecs.count())};
1594 fd_set fd_select_set;
1595 FD_ZERO( &fd_select_set);
1596 FD_SET (fd, &fd_select_set);
1601 do ret = select(fd+1, &fd_select_set,
nullptr,
nullptr, &select_timeout);
1602 while ((-1 == ret) && (EINTR == errno));
1606 LOG(VB_GENERAL, LOG_ERR,
LOC +
1607 QString(
"%1: Failed to wait on output.").arg(__func__) +
ENO);
1613#if ((DVB_API_VERSION > 5) || ((DVB_API_VERSION == 5) && (DVB_API_VERSION_MINOR > 10)))
1614 fe_status_t status = FE_NONE;
1616 fe_status_t status = (fe_status_t)0;
1619 if (ioctl(fd, FE_READ_STATUS, &status) < 0)
1621 LOG(VB_GENERAL, LOG_ERR,
LOC +
1622 QString(
"%1: FE_READ_STATUS failed.").arg(__func__) +
ENO);
1627 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1628 QString(
"%1: status: 0x%2 %3") .arg(__func__)
1629 .arg(status,2,16,QChar(
'0')).arg(
toString(status)));
1638 uint intermediate_freq,
bool can_fec_auto)
1640 dvb_frontend_parameters params {};
1642 params.frequency = tuning.m_frequency;
1643 params.inversion = (fe_spectral_inversion_t) (
int) tuning.m_inversion;
1649 LOG(VB_GENERAL, LOG_ERR,
1650 "DVBChan: Cannot tune to DVB-S2 transport with DVB-S card.");
1653 params.frequency = intermediate_freq;
1654 params.u.qpsk.symbol_rate = tuning.m_symbolRate;
1655 params.u.qpsk.fec_inner = can_fec_auto ? FEC_AUTO
1656 : (fe_code_rate_t) (
int) tuning.m_fec;
1661 LOG(VB_GENERAL, LOG_ERR,
1662 "DVBChan: Cannot tune DVB-S2 card with DVBv3 API.");
1667 params.u.qam.symbol_rate = tuning.m_symbolRate;
1668 params.u.qam.fec_inner = (fe_code_rate_t) (
int) tuning.m_fec;
1669 params.u.qam.modulation = (fe_modulation_t) (
int) tuning.m_modulation;
1675 params.u.ofdm.bandwidth = (fe_bandwidth_t) (
int) tuning.m_bandwidth;
1676 params.u.ofdm.code_rate_HP = (fe_code_rate_t) (
int) tuning.m_hpCodeRate;
1677 params.u.ofdm.code_rate_LP = (fe_code_rate_t) (
int) tuning.m_lpCodeRate;
1678 params.u.ofdm.constellation = (fe_modulation_t) (
int) tuning.m_modulation;
1679 params.u.ofdm.transmission_mode = (fe_transmit_mode_t) (
int) tuning.m_transMode;
1680 params.u.ofdm.guard_interval = (fe_guard_interval_t) (
int) tuning.m_guardInterval;
1681 params.u.ofdm.hierarchy_information = (fe_hierarchy_t) (
int) tuning.m_hierarchy;
1686 params.u.vsb.modulation = (fe_modulation_t) (
int) tuning.m_modulation;
1695 DTVTunerType tuner_type,
const dvb_frontend_parameters ¶ms)
1706 tuning.
m_fec = params.u.qpsk.fec_inner;
1712 tuning.
m_fec = params.u.qam.fec_inner;
1723 tuning.
m_transMode = params.u.ofdm.transmission_mode;
1725 tuning.
m_hierarchy = params.u.ofdm.hierarchy_information;
1740 uint intermediate_freq,
bool can_fec_auto,
bool do_tune)
1745 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]: m_modsys:%2 current_sys:%3")
1746 .arg(QString::number(inputId),
1750 auto *cmdseq = (
struct dtv_properties*) calloc(1,
sizeof(
struct dtv_properties));
1754 cmdseq->props = (
struct dtv_property*) calloc(20,
sizeof(*(cmdseq->props)));
1755 if (!(cmdseq->props))
1766 can_fec_auto =
false;
1776 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1777 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1781 delivery_system = current_sys;
1782 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1783 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1788 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1789 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1794 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1795 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1800 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1801 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1806 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1807 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1812 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1813 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1818 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1819 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1822 LOG(VB_CHANNEL, LOG_INFO, QString(
"DVBChan[%1]: Delivery system: %2")
1823 .arg(inputId).arg(delivery_system.
toString()));
1827 cmdseq->props[c].cmd = DTV_DELIVERY_SYSTEM;
1828 cmdseq->props[c++].u.data = delivery_system;
1832 LOG(VB_GENERAL, LOG_ERR, QString(
"DVBChan[%1]: Delivery system: %2")
1833 .arg(inputId).arg(delivery_system.
toString()));
1837 cmdseq->props[c].cmd = DTV_FREQUENCY;
1838 cmdseq->props[c++].u.data = intermediate_freq ? intermediate_freq : tuning.
m_frequency;
1839 cmdseq->props[c].cmd = DTV_MODULATION;
1841 cmdseq->props[c].cmd = DTV_INVERSION;
1849 cmdseq->props[c].cmd = DTV_SYMBOL_RATE;
1856 cmdseq->props[c].cmd = DTV_INNER_FEC;
1857 cmdseq->props[c++].u.data = can_fec_auto ? FEC_AUTO
1858 : (fe_code_rate_t) (
int) tuning.
m_fec;
1865 cmdseq->props[c].cmd = DTV_BANDWIDTH_HZ;
1866 cmdseq->props[c++].u.data = (8-tuning.
m_bandwidth) * 1000000;
1867 cmdseq->props[c].cmd = DTV_CODE_RATE_HP;
1869 cmdseq->props[c].cmd = DTV_CODE_RATE_LP;
1871 cmdseq->props[c].cmd = DTV_TRANSMISSION_MODE;
1873 cmdseq->props[c].cmd = DTV_GUARD_INTERVAL;
1875 cmdseq->props[c].cmd = DTV_HIERARCHY;
1882 cmdseq->props[c].cmd = DTV_ROLLOFF;
1889 cmdseq->props[c].cmd = DTV_PILOT;
1890 cmdseq->props[c++].u.data = PILOT_AUTO;
1891 cmdseq->props[c].cmd = DTV_ROLLOFF;
1892 cmdseq->props[c++].u.data = tuning.
m_rolloff;
1896 cmdseq->props[c++].cmd = DTV_TUNE;
static DTVModulationSystem GetDeliverySystem(uint inputid)
static int SetDeliverySystem(uint inputid)
static bool HasDVBCRCBug(const QString &device)
Returns true if and only if the device munges PAT/PMT tables, and then doesn't fix the CRC.
static std::chrono::milliseconds GetMinSignalMonitoringDelay(const QString &device)
static uint GetSourceID(uint inputid)
static QString GetDeviceName(dvb_dev_type_t type, const QString &device)
static QStringList CapabilitiesToString(uint64_t capabilities)
static DTVTunerType ConvertToTunerType(DTVModulationSystem delsys)
virtual bool Init(QString &startchannel, bool setchan)
virtual bool InitializeInput(void)
Fills in input map from DB.
Class providing a generic interface to digital tuning hardware.
static void ReturnMasterLock(DTVChannelP &chan)
void SetSIStandard(const QString &si_std)
Sets PSIP table standard: MPEG, DVB, ATSC, or OpenCable.
static DTVChannel * GetMasterLock(const QString &key)
static MasterMap s_master_map
static QReadWriteLock s_master_map_lock
@ kModulationSystem_DVBS2
@ kModulationSystem_DVBT2
@ kModulationSystem_DVBC_ANNEX_A
@ kModulationSystem_UNDEFINED
bool IsEqual(DTVTunerType type, const DTVMultiplex &other, uint freq_range=0, bool fuzzy=false) const
DTVTransmitMode m_transMode
DTVModulation m_modulation
DTVModulationSystem m_modSys
DTVGuardInterval m_guardInterval
bool IsFECVariable(void) const
bool IsDiSEqCSupported(void) const
static const int kTunerTypeDVBS2
static const int kTunerTypeDVBT
static const int kTunerTypeDVBC
bool IsModulationVariable(void) const
static const int kTunerTypeDVBS1
static const int kTunerTypeDVBT2
static const int kTunerTypeATSC
void SetPMT(const ChannelBase *chan, const ProgramMapTable *pmt)
bool IsRunning(void) const
void SetTimeOffset(double offset_in_seconds)
Provides interface to the tuning hardware when using DVB drivers.
void CheckOptions(DTVMultiplex &t) const override
Checks tuning for problems, and tries to fix them.
bool Open(void) override
Opens the channel changing hardware for use.
bool CheckModulation(DTVModulation modulation) const
Return true iff modulation is supported modulation on the frontend.
DTVMultiplex m_desiredTuning
bool Retune(void) override
bool IsTuningParamsProbeSupported(void) const
Returns true iff tuning info probing is working.
std::chrono::milliseconds m_sigMonDelay
DTVModulationSystem m_currentSys
QList< DTVModulationSystem > m_sysList
const DiSEqCDevRotor * GetRotor(void) const
Returns rotor object if it exists, nullptr otherwise.
uint64_t m_frequencyMaximum
uint64_t m_extModulations
void DrainDVBEvents(void)
bool Init(QString &startchannel, bool setchan) override
int GetChanID(void) const override
Returns Channel ID.
void SetPMT(const ProgramMapTable *pmt)
Tells the Conditional Access Module which streams we wish to decode.
bool WaitForBackend(std::chrono::milliseconds timeout_ms)
Waits for backend to get tune message.
DVBChannel(QString device, TVRec *parent=nullptr)
uint64_t m_frequencyMinimum
void SetTimeOffset(double offset)
Tells the Conditional Access Module the offset from the computers utc time to dvb time.
bool IsMaster(void) const override
Returns true if this is the first of a number of multi-rec devs.
double GetUncorrectedBlockCount(bool *ok=nullptr) const
Returns # of uncorrected blocks since last call. First call undefined.
static std::chrono::milliseconds s_lastTuning
bool HasLock(bool *ok=nullptr) const
Returns true iff we have a signal carrier lock.
double GetBitErrorRate(bool *ok=nullptr) const
Returns # of corrected bits since last call. First call undefined.
void CheckFrequency(uint64_t frequency) const
Checks tuning frequency.
void Close(void) override
Closes the channel changing hardware to use.
double GetSNR(bool *ok=nullptr) const
Returns signal/noise in the range [0..1.0].
DiSEqCDevTree * m_diseqcTree
DTVMultiplex m_prevTuning
bool ProbeTuningParams(DTVMultiplex &tuning) const
Fetches DTVMultiplex params from driver.
DVBChannel * GetMasterLock(void) const
double GetSignalStrengthDVBv5(bool *ok) const
Get Signal strength from the DVBv5 interface [0-1.0] It is transformed to a linear relative scale if ...
double GetUncorrectedBlockCountDVBv5(bool *ok) const
Get Uncorrected Block Count from the DVBv5 interface.
bool CheckCodeRate(DTVCodeRate rate) const
Return true iff rate is supported rate on the frontend.
bool Tune(const DTVMultiplex &tuning) override
This performs the actual frequency tuning and in some cases input switching.
double GetSignalStrength(bool *ok=nullptr) const
Returns signal strength in the range [0.0..1.0] (non-calibrated).
DiSEqCDevSettings m_diseqcSettings
bool IsOpen(void) const override
Reports whether channel is already open.
double GetSNRDVBv5(bool *ok) const
Get SNR from the DVBv5 interface [0-1.0] It is transformed to a linear relative scale if provided in ...
static void ReturnMasterLock(DVBChannel *&dvbm)
std::chrono::milliseconds m_tuningDelay
double GetBitErrorRateDVBv5(bool *ok) const
Get Bit Error Rate from the DVBv5 interface.
uint GetDeviceID(void) const
uint32_t GetIntermediateFrequency(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning) const
Calculate proper intermediate frequency for the given settings and tuning parameters.
uint32_t GetIntermediateFrequency(uint32_t frequency) const
bool Load(uint card_input_id)
Loads configuration chain from DB for specified card input id.
bool Execute(const DiSEqCDevSettings &settings, const DTVMultiplex &tuning)
Applies settings to the entire tree.
DiSEqCDevSCR * FindSCR(const DiSEqCDevSettings &settings)
Returns the SCR device object selected by the configuration chain.
DiSEqCDevLNB * FindLNB(const DiSEqCDevSettings &settings)
Returns the LNB device object selected by the configuration chain.
DiSEqCDevRotor * FindRotor(const DiSEqCDevSettings &settings, uint index=0)
Returns the nth rotor device object in the tree.
void Open(int fd_frontend, bool is_SCR)
Retrieve device tree.
static DiSEqCDevTree * FindTree(uint cardid)
Retrieve device tree.
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.
bool GetDVBv3(void) const
static void DBError(const QString &where, const MSqlQuery &query)
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
This is the coordinating class of the Recorder Subsystem.
uint GetInputId(void) const
Returns the inputid.
static constexpr std::chrono::milliseconds concurrent_tunings_delay
static struct dtv_properties * dtvmultiplex_to_dtvproperties(uint inputId, DTVTunerType tuner_type, DTVModulationSystem current_sys, const DTVMultiplex &tuning, uint intermediate_freq, bool can_fec_auto, bool do_tune=true)
static struct dvb_frontend_parameters dtvmultiplex_to_dvbparams(DTVTunerType tuner_type, const DTVMultiplex &tuning, uint intermediate_freq, bool can_fec_auto)
static DTVMultiplex dvbparams_to_dtvmultiplex(DTVTunerType tuner_type, const dvb_frontend_parameters ¶ms)
QString logStrerror(int errnum)
Verbose helper function for ENO macro.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
std::chrono::milliseconds currentMSecsSinceEpochAsDuration(void)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
VERBOSE_PREAMBLE Most true