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
83 :
DTVChannel(parent), m_device(std::move(aDevice))
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));
939 LOG(VB_GENERAL, LOG_ERR,
LOC +
940 "Tune(): Setting Frontend tuning parameters failed." +
ENO);
948 m_tunerType, tuning, intermediate_freq, can_fec_auto);
952 LOG(VB_GENERAL, LOG_ERR,
LOC +
953 "Tune(): Setting Frontend tuning parameters failed." +
ENO);
969 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Tune(): Tuning to %1%2 skipped, already tuned")
970 .arg(intermediate_freq ? intermediate_freq : tuning.
m_frequency)
977 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tune(): Frequency tuning successful");
996 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Card not open!");
1018 dvb_frontend_parameters params {};
1020 int res = ioctl(
m_fdFrontend, FE_GET_FRONTEND, ¶ms);
1023 LOG(VB_CHANNEL, LOG_ERR,
LOC +
"FE_GET_FRONTEND failed." +
ENO);
1042 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Card not open!");
1072 dvb_frontend_parameters params {};
1075 LOG(VB_GENERAL, LOG_ERR,
LOC +
1076 "Getting Frontend tuning parameters failed." +
ENO);
1103 query.
prepare(
"SELECT chanid, visible "
1104 "FROM channel, capturecard "
1105 "WHERE channel.deleted IS NULL AND "
1106 " capturecard.sourceid = channel.sourceid AND "
1107 " channel.channum = :CHANNUM AND "
1108 " capturecard.cardid = :INPUTID");
1119 while (query.
next())
1121 bool visible = query.
value(1).toInt() > 0;
1124 int chanid = query.
value(0).toInt();
1125 idlist.append(chanid);
1129 if (idlist.isEmpty())
1131 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1132 QString(
"No visible channel ID for %1")
1137 id = idlist.value(0);
1138 if (idlist.count() > 1)
1141 sl.reserve(idlist.size());
1142 for (
auto chanid : idlist)
1144 sl.append(QString::number(chanid));
1146 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1147 QString(
"Found for '%1' multiple visible channel IDs: %2")
1152 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1153 QString(
"Found visible channel ID %1 for '%2'")
1174 bool haslock = master->
HasLock(ok);
1180#if ((DVB_API_VERSION > 5) || ((DVB_API_VERSION == 5) && (DVB_API_VERSION_MINOR > 10)))
1181 fe_status_t status = FE_NONE;
1183 fe_status_t status = (fe_status_t)0;
1186 int ret = ioctl(
m_fdFrontend, FE_READ_STATUS, &status);
1189 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FE_READ_STATUS failed" +
ENO);
1193 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"%1 status: 0x%2 %3")
1194 .arg(__func__).arg(status,2,16,QChar(
'0')).arg(
toString(status)));
1200 return (status & FE_HAS_LOCK) != 0;
1205 struct dtv_property prop = {};
1206 struct dtv_properties cmd = {};
1208 prop.cmd = DTV_STAT_SIGNAL_STRENGTH;
1214 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_SIGNAL_STRENGTH failed" +
ENO);
1218#if DTV_STAT_FULL_DEBUG
1219 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_SIGNAL_STRENGTH " +
1220 QString(
"res=%1 len=%2 scale=%3 val=%4")
1221 .arg(cmd.props->result)
1222 .arg(cmd.props->u.st.len)
1223 .arg(cmd.props->u.st.stat[0].scale)
1224 .arg(cmd.props->u.st.stat[0].svalue));
1228 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1235 if (cmd.props->u.st.stat[0].scale == FE_SCALE_DECIBEL)
1241 int64_t svalue = cmd.props->u.st.stat[0].svalue;
1242 if (svalue >= -100000 && svalue <= 0)
1245 value = svalue + 100000;
1246 value = value / 100000.0;
1247 value = std::min(value, 1.0);
1250 else if (cmd.props->u.st.stat[0].scale == FE_SCALE_RELATIVE)
1253 value = cmd.props->u.st.stat[0].uvalue / 65535.0;
1285 int ret = ioctl(
m_fdFrontend, FE_READ_SIGNAL_STRENGTH, &sig);
1289 return sig * (1.0 / 65535.0);
1294 struct dtv_property prop = {};
1295 struct dtv_properties cmd = {};
1297 prop.cmd = DTV_STAT_CNR;
1303 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_CNR failed" +
ENO);
1307#if DTV_STAT_FULL_DEBUG
1308 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_CNR " +
1309 QString(
"res=%1 len=%2 scale=%3 val=%4")
1310 .arg(cmd.props->result)
1311 .arg(cmd.props->u.st.len)
1312 .arg(cmd.props->u.st.stat[0].scale)
1313 .arg(cmd.props->u.st.stat[0].svalue));
1317 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1323 if (cmd.props->u.st.stat[0].scale == FE_SCALE_DECIBEL)
1328 value = cmd.props->u.st.stat[0].svalue;
1329 value = value / 50000.0;
1335 else if (cmd.props->u.st.stat[0].scale == FE_SCALE_RELATIVE)
1338 value = cmd.props->u.st.stat[0].uvalue / 65535.0;
1349 double val = master->
GetSNR(ok);
1374 return snr * (1.0 / 65535.0);
1379 std::array<struct dtv_property,2> prop {};
1380 struct dtv_properties cmd = {};
1382 prop[0].cmd = DTV_STAT_POST_ERROR_BIT_COUNT;
1383 prop[1].cmd = DTV_STAT_POST_TOTAL_BIT_COUNT;
1384 cmd.num = prop.size();
1385 cmd.props = prop.data();
1389 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_POST_ERROR_BIT_COUNT failed" +
ENO);
1393#if DTV_STAT_FULL_DEBUG
1394 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_POST_ERROR_BIT_COUNT " +
1395 QString(
"res=%1 len=%2 scale=%3 val=%4 res=%5 len=%6 scale=%7 val=%8")
1396 .arg(cmd.props[0].result)
1397 .arg(cmd.props[0].u.st.len)
1398 .arg(cmd.props[0].u.st.stat[0].scale)
1399 .arg(cmd.props[0].u.st.stat[0].uvalue)
1400 .arg(cmd.props[1].result)
1401 .arg(cmd.props[1].u.st.len)
1402 .arg(cmd.props[1].u.st.stat[0].scale)
1403 .arg(cmd.props[1].u.st.stat[0].uvalue));
1407 bool tmpOk = (ret == 0) &&
1408 (cmd.props[0].u.st.len > 0) &&
1409 (cmd.props[1].u.st.len > 0);
1415 if ((cmd.props[0].u.st.stat[0].scale == FE_SCALE_COUNTER) &&
1416 (cmd.props[1].u.st.stat[0].scale == FE_SCALE_COUNTER) &&
1417 (cmd.props[1].u.st.stat[0].uvalue != 0))
1419 value =
static_cast<double>(
1420 static_cast<long double>(cmd.props[0].u.st.stat[0].uvalue) /
1421 cmd.props[1].u.st.stat[0].uvalue);
1455 return (
double) ber;
1460 struct dtv_property prop = {};
1461 struct dtv_properties cmd = {};
1463 prop.cmd = DTV_STAT_ERROR_BLOCK_COUNT;
1469 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_ERROR_BLOCK_COUNT failed" +
ENO);
1473#if DTV_STAT_FULL_DEBUG
1474 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_ERROR_BLOCK_COUNT " +
1475 QString(
"res=%1 len=%2 scale=%3 val=%4")
1476 .arg(cmd.props[0].result)
1477 .arg(cmd.props[0].u.st.len)
1478 .arg(cmd.props[0].u.st.stat[0].scale)
1479 .arg(cmd.props[0].u.st.stat[0].svalue));
1483 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1489 if (cmd.props->u.st.stat[0].scale == FE_SCALE_COUNTER)
1490 value = cmd.props->u.st.stat[0].uvalue;
1518 uint32_t ublocks = 0;
1519 int ret = ioctl(
m_fdFrontend, FE_READ_UNCORRECTED_BLOCKS, &ublocks);
1523 return static_cast<double>(ublocks);
1536 auto *dvbm =
dynamic_cast<DVBChannel*
>(master);
1537 if (master && !dvbm)
1545 bool is_master = (master ==
this);
1557 struct dvb_frontend_event event {};
1559 while ((ret = ioctl(fd, FE_GET_EVENT, &event)) == 0);
1560 if ((ret < 0) && (EAGAIN != errno) && (EWOULDBLOCK != errno) && (EOVERFLOW != errno))
1562 LOG(VB_CHANNEL, LOG_ERR,
LOC +
1563 QString(
"%1 FE_GET_EVENT failed: ").arg(__func__) +
logStrerror(errno));
1592 auto seconds = duration_cast<std::chrono::seconds>(timeout_ms);
1593 auto usecs = duration_cast<std::chrono::microseconds>(timeout_ms) - seconds;
1594 struct timeval select_timeout = {
1595 .tv_sec=
static_cast<time_t
>(seconds.count()),
1596 .tv_usec=
static_cast<suseconds_t
>(usecs.count())};
1597 fd_set fd_select_set;
1598 FD_ZERO( &fd_select_set);
1599 FD_SET (fd, &fd_select_set);
1603 int ret = select(fd+1, &fd_select_set,
nullptr,
nullptr, &select_timeout);
1604 while ((-1 == ret) && (EINTR == errno))
1605 ret = select(fd+1, &fd_select_set,
nullptr,
nullptr, &select_timeout);
1609 LOG(VB_GENERAL, LOG_ERR,
LOC +
1610 QString(
"%1: Failed to wait on output.").arg(__func__) +
ENO);
1616#if ((DVB_API_VERSION > 5) || ((DVB_API_VERSION == 5) && (DVB_API_VERSION_MINOR > 10)))
1617 fe_status_t status = FE_NONE;
1619 fe_status_t status = (fe_status_t)0;
1622 if (ioctl(fd, FE_READ_STATUS, &status) < 0)
1624 LOG(VB_GENERAL, LOG_ERR,
LOC +
1625 QString(
"%1: FE_READ_STATUS failed.").arg(__func__) +
ENO);
1630 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1631 QString(
"%1: status: 0x%2 %3") .arg(__func__)
1632 .arg(status,2,16,QChar(
'0')).arg(
toString(status)));
1641 uint intermediate_freq,
bool can_fec_auto)
1643 dvb_frontend_parameters params {};
1645 params.frequency = tuning.m_frequency;
1646 params.inversion = (fe_spectral_inversion_t) (
int) tuning.m_inversion;
1652 LOG(VB_GENERAL, LOG_ERR,
1653 "DVBChan: Cannot tune to DVB-S2 transport with DVB-S card.");
1656 params.frequency = intermediate_freq;
1657 params.u.qpsk.symbol_rate = tuning.m_symbolRate;
1658 params.u.qpsk.fec_inner = can_fec_auto ? FEC_AUTO
1659 : (fe_code_rate_t) (
int) tuning.m_fec;
1664 LOG(VB_GENERAL, LOG_ERR,
1665 "DVBChan: Cannot tune DVB-S2 card with DVBv3 API.");
1670 params.u.qam.symbol_rate = tuning.m_symbolRate;
1671 params.u.qam.fec_inner = (fe_code_rate_t) (
int) tuning.m_fec;
1672 params.u.qam.modulation = (fe_modulation_t) (
int) tuning.m_modulation;
1678 params.u.ofdm.bandwidth = (fe_bandwidth_t) (
int) tuning.m_bandwidth;
1679 params.u.ofdm.code_rate_HP = (fe_code_rate_t) (
int) tuning.m_hpCodeRate;
1680 params.u.ofdm.code_rate_LP = (fe_code_rate_t) (
int) tuning.m_lpCodeRate;
1681 params.u.ofdm.constellation = (fe_modulation_t) (
int) tuning.m_modulation;
1682 params.u.ofdm.transmission_mode = (fe_transmit_mode_t) (
int) tuning.m_transMode;
1683 params.u.ofdm.guard_interval = (fe_guard_interval_t) (
int) tuning.m_guardInterval;
1684 params.u.ofdm.hierarchy_information = (fe_hierarchy_t) (
int) tuning.m_hierarchy;
1689 params.u.vsb.modulation = (fe_modulation_t) (
int) tuning.m_modulation;
1698 DTVTunerType tuner_type,
const dvb_frontend_parameters ¶ms)
1709 tuning.
m_fec = params.u.qpsk.fec_inner;
1715 tuning.
m_fec = params.u.qam.fec_inner;
1726 tuning.
m_transMode = params.u.ofdm.transmission_mode;
1728 tuning.
m_hierarchy = params.u.ofdm.hierarchy_information;
1743 uint intermediate_freq,
bool can_fec_auto,
bool do_tune)
1748 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]: m_modsys:%2 current_sys:%3")
1749 .arg(QString::number(inputId),
1754 auto *cmdseq = (
struct dtv_properties*) calloc(1,
sizeof(
struct dtv_properties));
1758 cmdseq->props = (
struct dtv_property*) calloc(20,
sizeof(*(cmdseq->props)));
1759 if (!(cmdseq->props))
1771 can_fec_auto =
false;
1781 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1782 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1786 delivery_system = current_sys;
1787 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1788 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1793 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1794 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1799 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1800 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1805 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1806 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1811 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1812 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1817 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1818 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1823 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1824 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1827 LOG(VB_CHANNEL, LOG_INFO, QString(
"DVBChan[%1]: Delivery system: %2")
1828 .arg(inputId).arg(delivery_system.
toString()));
1832 cmdseq->props[c].cmd = DTV_DELIVERY_SYSTEM;
1833 cmdseq->props[c++].u.data = delivery_system;
1837 LOG(VB_GENERAL, LOG_ERR, QString(
"DVBChan[%1]: Delivery system: %2")
1838 .arg(inputId).arg(delivery_system.
toString()));
1842 cmdseq->props[c].cmd = DTV_FREQUENCY;
1843 cmdseq->props[c++].u.data = intermediate_freq ? intermediate_freq : tuning.
m_frequency;
1844 cmdseq->props[c].cmd = DTV_MODULATION;
1846 cmdseq->props[c].cmd = DTV_INVERSION;
1854 cmdseq->props[c].cmd = DTV_SYMBOL_RATE;
1861 cmdseq->props[c].cmd = DTV_INNER_FEC;
1862 cmdseq->props[c++].u.data = can_fec_auto ? FEC_AUTO
1863 : (fe_code_rate_t) (
int) tuning.
m_fec;
1870 cmdseq->props[c].cmd = DTV_BANDWIDTH_HZ;
1871 cmdseq->props[c++].u.data = (8-tuning.
m_bandwidth) * 1000000;
1872 cmdseq->props[c].cmd = DTV_CODE_RATE_HP;
1874 cmdseq->props[c].cmd = DTV_CODE_RATE_LP;
1876 cmdseq->props[c].cmd = DTV_TRANSMISSION_MODE;
1878 cmdseq->props[c].cmd = DTV_GUARD_INTERVAL;
1880 cmdseq->props[c].cmd = DTV_HIERARCHY;
1887 cmdseq->props[c].cmd = DTV_ROLLOFF;
1894 cmdseq->props[c].cmd = DTV_PILOT;
1895 cmdseq->props[c++].u.data = PILOT_AUTO;
1896 cmdseq->props[c].cmd = DTV_ROLLOFF;
1897 cmdseq->props[c++].u.data = tuning.
m_rolloff;
1901 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