40#include <sys/select.h>
49#include "libmythbase/mythconfig.h"
65 DTVTunerType tuner_type,
const dvb_frontend_parameters& params);
68 uint intermediate_freq,
bool can_fec_auto,
bool do_tune =
true);
73#define LOC QString("DVBChan[%1](%2): ").arg(m_inputId).arg(DVBChannel::GetDevice())
76#define DTV_STAT_FULL_DEBUG 0
89 m_key += QString(
":%1")
99 else if (master !=
nullptr)
123 QMutexLocker master_locker(&(master->m_hwLock));
124 QMutexLocker new_master_locker(&(new_master->
m_hwLock));
125 new_master->
m_isOpen = master->m_isOpen;
149 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Closing DVB channel");
153 IsOpenMap::iterator it =
m_isOpen.find(who);
160 if (master !=
nullptr && master !=
this)
194 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Opening DVB channel");
199 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Use legacy DVBv3 API");
213 if (!master->
Open(who))
251 QByteArray devn = dvbdev.toLatin1();
253 for (
int tries = 1; ; ++tries)
260 LOG(VB_GENERAL, LOG_WARNING,
LOC +
261 "Opening DVB frontend device failed." +
ENO);
263 if (tries >= 5 || (errno != EBUSY && errno != EAGAIN))
265 LOG(VB_GENERAL, LOG_ERR,
LOC +
266 QString(
"Failed to open DVB frontend device due to "
267 "fatal error or too many attempts."));
270 std::this_thread::sleep_for(50ms);
275 dvb_frontend_info
info {};
278 LOG(VB_GENERAL, LOG_ERR,
LOC +
279 "Failed to get frontend information." +
ENO);
293 LOG(VB_CHANNEL, LOG_INFO,
LOC +
297 LOG(VB_CHANNEL, LOG_INFO, QString(
" %1").arg(capstr));
302 std::array<struct dtv_property,2> prop = {};
303 struct dtv_properties cmd = {};
305 prop[0].cmd = DTV_API_VERSION;
306 prop[1].cmd = DTV_DELIVERY_SYSTEM;
309 cmd.props = prop.data();
313 prop[0].u.data = 0x300;
314 prop[1].u.data = SYS_UNDEFINED;
340 if (
info.caps & FE_CAN_2G_MODULATION)
345 if (
info.caps & FE_CAN_TURBO_FEC)
360 if (
info.caps & FE_CAN_2G_MODULATION)
367 if (
info.caps & (FE_CAN_8VSB | FE_CAN_16VSB))
372 if (
info.caps & (FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO))
374 delsys = SYS_DVBC_ANNEX_B;
382 LOG(VB_GENERAL, LOG_ERR,
LOC +
383 QString(
"Frontend '%1' delivery system not detected.").arg(
m_frontendName));
392 std::array<struct dtv_property,1> prop = {};
393 struct dtv_properties cmd = {};
395 prop[0].cmd = DTV_ENUM_DELSYS;
398 cmd.props = prop.data();
402 LOG(VB_GENERAL, LOG_ERR,
LOC +
403 QString(
"Frontend '%1' FE_GET_PROPERTY failed.").arg(
m_frontendName));
408 int p_num_systems = prop[0].u.buffer.len;
409 for (
int i = 0; i < p_num_systems; i++)
415 if (p_num_systems == 0) {
416 LOG(VB_GENERAL, LOG_ERR,
LOC +
417 QString(
"Frontend '%1' returned 0 supported delivery systems!").arg(
m_frontendName));
427 LOG(VB_CHANNEL, LOG_INFO,
LOC +
429 LOG(VB_CHANNEL, LOG_INFO,
LOC +
430 QString(
"DVB version:0x%1 ").arg(
m_version,3,16,QChar(
'0')) +
435 LOG(VB_CHANNEL, LOG_INFO,
"Supported delivery systems: ");
440 LOG(VB_CHANNEL, LOG_INFO, QString(
" [%1]")
441 .arg(delsys.toString()));
445 LOG(VB_CHANNEL, LOG_INFO, QString(
" %1")
446 .arg(delsys.toString()));
450 uint32_t frq_min =
info.frequency_min;
451 uint32_t frq_max =
info.frequency_max;
452 uint32_t frq_stp =
info.frequency_stepsize;
454 if (
info.type == FE_QPSK)
462 LOG(VB_CHANNEL, LOG_INFO, QString(
"Frequency range for the current standard:"));
463 LOG(VB_CHANNEL, LOG_INFO, QString(
" From: %1 Hz").arg(frq_min,11));
464 LOG(VB_CHANNEL, LOG_INFO, QString(
" To: %1 Hz").arg(frq_max,11));
465 LOG(VB_CHANNEL, LOG_INFO, QString(
" Step: %1 Hz").arg(frq_stp,11));
467 if (
info.type == FE_QPSK ||
info.type == FE_QAM)
469 LOG(VB_CHANNEL, LOG_INFO, QString(
"Symbol rate ranges for the current standard:"));
470 LOG(VB_CHANNEL, LOG_INFO, QString(
" From: %1 Baud").arg(
info.symbol_rate_min,11));
471 LOG(VB_CHANNEL, LOG_INFO, QString(
" To: %1 Baud").arg(
info.symbol_rate_max,11));
484 LOG(VB_CHANNEL, LOG_INFO,
LOC +
485 QString(
"Change delivery system from %1 to %2.")
494 LOG(VB_CHANNEL, LOG_INFO,
LOC +
495 QString(
"Delivery system in database and in card equal, leave at %1.")
501 LOG(VB_CHANNEL, LOG_INFO,
LOC +
519 LOG(VB_CHANNEL, LOG_INFO,
LOC +
520 QString(
"Requested %1 channel is on SCR system")
525 LOG(VB_CHANNEL, LOG_INFO,
LOC +
526 QString(
"Requested %1 channel is on non-SCR system")
551 IsOpenMap::const_iterator it =
m_isOpen.find(
this);
572 LOG(VB_GENERAL, LOG_WARNING,
LOC +
573 QString(
"Frequency setting (%1) is out of range (min/max:%2/%3)")
583 LOG(VB_GENERAL, LOG_WARNING,
LOC +
584 "'Auto' inversion parameter unsupported by this driver, "
585 "falling back to 'off'.");
604 LOG(VB_GENERAL, LOG_WARNING,
LOC +
605 QString(
"Symbol Rate setting (%1) is out of range (min/max:%2/%3)")
612 LOG(VB_GENERAL, LOG_WARNING,
LOC +
613 "Selected fec_inner parameter unsupported by this driver.");
618 LOG(VB_GENERAL, LOG_WARNING,
LOC +
619 "Selected modulation parameter unsupported by this driver.");
635 LOG(VB_GENERAL, LOG_WARNING,
LOC +
636 "Selected code_rate_hp parameter unsupported by this driver.");
641 LOG(VB_GENERAL, LOG_WARNING,
LOC +
642 "Selected code_rate_lp parameter unsupported by this driver.");
648 LOG(VB_GENERAL, LOG_WARNING,
LOC +
649 "'Auto' bandwidth parameter unsupported by this driver.");
655 LOG(VB_GENERAL, LOG_WARNING,
LOC +
656 "'Auto' transmission_mode parameter unsupported by this driver.");
662 LOG(VB_GENERAL, LOG_WARNING,
LOC +
663 "'Auto' guard_interval parameter unsupported by this driver.");
669 LOG(VB_GENERAL, LOG_WARNING,
LOC +
670 "'Auto' hierarchy parameter unsupported by this driver. ");
675 LOG(VB_GENERAL, LOG_WARNING,
LOC +
676 "Selected modulation parameter unsupported by this driver.");
749 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Tune(): Invalid input."));
752 return Tune(tuning,
false,
false);
781 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tuning on slave channel");
783 bool ok = master->
Tune(tuning, force_reset,
false);
790 uint intermediate_freq = 0;
791 bool can_fec_auto =
false;
796 LOG(VB_GENERAL, LOG_ERR,
LOC +
797 "DVB-S/S2 needs device tree for LNB handling");
805 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Tune(): Card not open!");
813 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tuning parameters:");
815 LOG(VB_CHANNEL, LOG_INFO,
" New: " + tuning.
toString());
820 int freq_mult = (is_dvbs) ? 1 : 1000;
821 QString suffix = (is_dvbs) ?
"kHz" :
"Hz";
825 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Tune(): Tuning to %1%2")
826 .arg(intermediate_freq ? intermediate_freq : tuning.
m_frequency)
833 if (tuning_delay > 0ms)
835 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Next tuning after less than %1ms, delaying by %2ms")
837 std::this_thread::sleep_for(tuning_delay);
853 LOG(VB_GENERAL, LOG_ERR,
LOC +
854 "Tune(): Failed to setup DiSEqC devices");
862 LOG(VB_GENERAL, LOG_ERR,
LOC +
863 "Tune(): No LNB for this configuration");
897 struct dtv_property p_clear = {};
898 struct dtv_properties cmdseq_clear = {};
900 p_clear.cmd = DTV_CLEAR;
901 cmdseq_clear.num = 1;
902 cmdseq_clear.props = &p_clear;
904 if ((ioctl(
m_fdFrontend, FE_SET_PROPERTY, &cmdseq_clear)) < 0)
906 LOG(VB_GENERAL, LOG_ERR,
LOC +
907 "Tune(): Clearing DTV properties cache failed." +
ENO);
915 LOG(VB_GENERAL, LOG_ERR,
LOC +
916 "Failed to convert DTVMultiplex to DTV_PROPERTY sequence");
922 for (
uint i = 0; i < cmds->num; i++)
924 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
925 QString(
"prop %1: cmd = %2, data %3")
926 .arg(i).arg(cmds->props[i].cmd)
927 .arg(cmds->props[i].u.data));
938 LOG(VB_GENERAL, LOG_ERR,
LOC +
939 "Tune(): Setting Frontend tuning parameters failed." +
ENO);
947 m_tunerType, tuning, intermediate_freq, can_fec_auto);
951 LOG(VB_GENERAL, LOG_ERR,
LOC +
952 "Tune(): Setting Frontend tuning parameters failed." +
ENO);
968 LOG(VB_CHANNEL, LOG_INFO,
LOC + QString(
"Tune(): Tuning to %1%2 skipped, already tuned")
969 .arg(intermediate_freq ? intermediate_freq : tuning.
m_frequency)
976 LOG(VB_CHANNEL, LOG_INFO,
LOC +
"Tune(): Frequency tuning successful");
995 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Card not open!");
1017 dvb_frontend_parameters params {};
1019 int res = ioctl(
m_fdFrontend, FE_GET_FRONTEND, ¶ms);
1022 LOG(VB_CHANNEL, LOG_ERR,
LOC +
"FE_GET_FRONTEND failed." +
ENO);
1041 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Card not open!");
1071 dvb_frontend_parameters params {};
1074 LOG(VB_GENERAL, LOG_ERR,
LOC +
1075 "Getting Frontend tuning parameters failed." +
ENO);
1102 query.
prepare(
"SELECT chanid, visible "
1103 "FROM channel, capturecard "
1104 "WHERE channel.deleted IS NULL AND "
1105 " capturecard.sourceid = channel.sourceid AND "
1106 " channel.channum = :CHANNUM AND "
1107 " capturecard.cardid = :INPUTID");
1118 while (query.
next())
1120 bool visible = query.
value(1).toInt() > 0;
1123 int chanid = query.
value(0).toInt();
1124 idlist.append(chanid);
1128 if (idlist.isEmpty())
1130 LOG(VB_GENERAL, LOG_WARNING,
LOC +
1131 QString(
"No visible channel ID for %1")
1136 id = idlist.value(0);
1137 if (idlist.count() > 1)
1140 for (
auto chanid : idlist)
1142 sl.append(QString::number(chanid));
1144 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1145 QString(
"Found for '%1' multiple visible channel IDs: %2")
1150 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1151 QString(
"Found visible channel ID %1 for '%2'")
1172 bool haslock = master->
HasLock(ok);
1178#if ((DVB_API_VERSION > 5) || ((DVB_API_VERSION == 5) && (DVB_API_VERSION_MINOR > 10)))
1179 fe_status_t status = FE_NONE;
1181 fe_status_t status = (fe_status_t)0;
1184 int ret = ioctl(
m_fdFrontend, FE_READ_STATUS, &status);
1187 LOG(VB_GENERAL, LOG_ERR,
LOC +
"FE_READ_STATUS failed" +
ENO);
1191 LOG(VB_CHANNEL, LOG_DEBUG,
LOC + QString(
"%1 status: 0x%2 %3")
1192 .arg(__func__).arg(status,2,16,QChar(
'0')).arg(
toString(status)));
1198 return (status & FE_HAS_LOCK) != 0;
1203 struct dtv_property prop = {};
1204 struct dtv_properties cmd = {};
1206 prop.cmd = DTV_STAT_SIGNAL_STRENGTH;
1212 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_SIGNAL_STRENGTH failed" +
ENO);
1216#if DTV_STAT_FULL_DEBUG
1217 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_SIGNAL_STRENGTH " +
1218 QString(
"res=%1 len=%2 scale=%3 val=%4")
1219 .arg(cmd.props->result)
1220 .arg(cmd.props->u.st.len)
1221 .arg(cmd.props->u.st.stat[0].scale)
1222 .arg(cmd.props->u.st.stat[0].svalue));
1226 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1233 if (cmd.props->u.st.stat[0].scale == FE_SCALE_DECIBEL)
1239 int64_t svalue = cmd.props->u.st.stat[0].svalue;
1240 if (svalue >= -100000 && svalue <= 0)
1243 value = svalue + 100000;
1244 value = value / 100000.0;
1245 value = std::min(value, 1.0);
1248 else if (cmd.props->u.st.stat[0].scale == FE_SCALE_RELATIVE)
1251 value = cmd.props->u.st.stat[0].uvalue / 65535.0;
1283 int ret = ioctl(
m_fdFrontend, FE_READ_SIGNAL_STRENGTH, &sig);
1287 return sig * (1.0 / 65535.0);
1292 struct dtv_property prop = {};
1293 struct dtv_properties cmd = {};
1295 prop.cmd = DTV_STAT_CNR;
1301 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_CNR failed" +
ENO);
1305#if DTV_STAT_FULL_DEBUG
1306 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_CNR " +
1307 QString(
"res=%1 len=%2 scale=%3 val=%4")
1308 .arg(cmd.props->result)
1309 .arg(cmd.props->u.st.len)
1310 .arg(cmd.props->u.st.stat[0].scale)
1311 .arg(cmd.props->u.st.stat[0].svalue));
1315 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1321 if (cmd.props->u.st.stat[0].scale == FE_SCALE_DECIBEL)
1326 value = cmd.props->u.st.stat[0].svalue;
1327 value = value / 50000.0;
1333 else if (cmd.props->u.st.stat[0].scale == FE_SCALE_RELATIVE)
1336 value = cmd.props->u.st.stat[0].uvalue / 65535.0;
1347 double val = master->
GetSNR(ok);
1372 return snr * (1.0 / 65535.0);
1377 std::array<struct dtv_property,2> prop {};
1378 struct dtv_properties cmd = {};
1380 prop[0].cmd = DTV_STAT_POST_ERROR_BIT_COUNT;
1381 prop[1].cmd = DTV_STAT_POST_TOTAL_BIT_COUNT;
1382 cmd.num = prop.size();
1383 cmd.props = prop.data();
1387 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_POST_ERROR_BIT_COUNT failed" +
ENO);
1391#if DTV_STAT_FULL_DEBUG
1392 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_POST_ERROR_BIT_COUNT " +
1393 QString(
"res=%1 len=%2 scale=%3 val=%4 res=%5 len=%6 scale=%7 val=%8")
1394 .arg(cmd.props[0].result)
1395 .arg(cmd.props[0].u.st.len)
1396 .arg(cmd.props[0].u.st.stat[0].scale)
1397 .arg(cmd.props[0].u.st.stat[0].uvalue)
1398 .arg(cmd.props[1].result)
1399 .arg(cmd.props[1].u.st.len)
1400 .arg(cmd.props[1].u.st.stat[0].scale)
1401 .arg(cmd.props[1].u.st.stat[0].uvalue));
1405 bool tmpOk = (ret == 0) &&
1406 (cmd.props[0].u.st.len > 0) &&
1407 (cmd.props[1].u.st.len > 0);
1413 if ((cmd.props[0].u.st.stat[0].scale == FE_SCALE_COUNTER) &&
1414 (cmd.props[1].u.st.stat[0].scale == FE_SCALE_COUNTER) &&
1415 (cmd.props[1].u.st.stat[0].uvalue != 0))
1417 value =
static_cast<double>(
1418 static_cast<long double>(cmd.props[0].u.st.stat[0].uvalue) /
1419 cmd.props[1].u.st.stat[0].uvalue);
1453 return (
double) ber;
1458 struct dtv_property prop = {};
1459 struct dtv_properties cmd = {};
1461 prop.cmd = DTV_STAT_ERROR_BLOCK_COUNT;
1467 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"FE_GET_PROPERTY DTV_STAT_ERROR_BLOCK_COUNT failed" +
ENO);
1471#if DTV_STAT_FULL_DEBUG
1472 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
"DTV_STAT_ERROR_BLOCK_COUNT " +
1473 QString(
"res=%1 len=%2 scale=%3 val=%4")
1474 .arg(cmd.props[0].result)
1475 .arg(cmd.props[0].u.st.len)
1476 .arg(cmd.props[0].u.st.stat[0].scale)
1477 .arg(cmd.props[0].u.st.stat[0].svalue));
1481 bool tmpOk = (ret == 0) && (cmd.props->u.st.len > 0);
1487 if (cmd.props->u.st.stat[0].scale == FE_SCALE_COUNTER)
1488 value = cmd.props->u.st.stat[0].uvalue;
1516 uint32_t ublocks = 0;
1517 int ret = ioctl(
m_fdFrontend, FE_READ_UNCORRECTED_BLOCKS, &ublocks);
1521 return static_cast<double>(ublocks);
1534 auto *dvbm =
dynamic_cast<DVBChannel*
>(master);
1535 if (master && !dvbm)
1543 bool is_master = (master ==
this);
1555 struct dvb_frontend_event event {};
1557 while ((ret = ioctl(fd, FE_GET_EVENT, &event)) == 0);
1558 if ((ret < 0) && (EAGAIN != errno) && (EWOULDBLOCK != errno) && (EOVERFLOW != errno))
1560 LOG(VB_CHANNEL, LOG_ERR,
LOC +
1561 QString(
"%1 FE_GET_EVENT failed: ").arg(__func__) +
logStrerror(errno));
1590 auto seconds = duration_cast<std::chrono::seconds>(timeout_ms);
1591 auto usecs = duration_cast<std::chrono::microseconds>(timeout_ms) - seconds;
1592 struct timeval select_timeout = {
1593 static_cast<typeof(select_timeout.tv_sec)
>(seconds.count()),
1594 static_cast<typeof(select_timeout.tv_usec)
>(usecs.count())};
1595 fd_set fd_select_set;
1596 FD_ZERO( &fd_select_set);
1597 FD_SET (fd, &fd_select_set);
1602 do ret = select(fd+1, &fd_select_set,
nullptr,
nullptr, &select_timeout);
1603 while ((-1 == ret) && (EINTR == errno));
1607 LOG(VB_GENERAL, LOG_ERR,
LOC +
1608 QString(
"%1: Failed to wait on output.").arg(__func__) +
ENO);
1614#if ((DVB_API_VERSION > 5) || ((DVB_API_VERSION == 5) && (DVB_API_VERSION_MINOR > 10)))
1615 fe_status_t status = FE_NONE;
1617 fe_status_t status = (fe_status_t)0;
1620 if (ioctl(fd, FE_READ_STATUS, &status) < 0)
1622 LOG(VB_GENERAL, LOG_ERR,
LOC +
1623 QString(
"%1: FE_READ_STATUS failed.").arg(__func__) +
ENO);
1628 LOG(VB_CHANNEL, LOG_DEBUG,
LOC +
1629 QString(
"%1: status: 0x%2 %3") .arg(__func__)
1630 .arg(status,2,16,QChar(
'0')).arg(
toString(status)));
1639 uint intermediate_freq,
bool can_fec_auto)
1641 dvb_frontend_parameters params {};
1643 params.frequency = tuning.m_frequency;
1644 params.inversion = (fe_spectral_inversion_t) (
int) tuning.m_inversion;
1650 LOG(VB_GENERAL, LOG_ERR,
1651 "DVBChan: Cannot tune to DVB-S2 transport with DVB-S card.");
1654 params.frequency = intermediate_freq;
1655 params.u.qpsk.symbol_rate = tuning.m_symbolRate;
1656 params.u.qpsk.fec_inner = can_fec_auto ? FEC_AUTO
1657 : (fe_code_rate_t) (
int) tuning.m_fec;
1662 LOG(VB_GENERAL, LOG_ERR,
1663 "DVBChan: Cannot tune DVB-S2 card with DVBv3 API.");
1668 params.u.qam.symbol_rate = tuning.m_symbolRate;
1669 params.u.qam.fec_inner = (fe_code_rate_t) (
int) tuning.m_fec;
1670 params.u.qam.modulation = (fe_modulation_t) (
int) tuning.m_modulation;
1676 params.u.ofdm.bandwidth = (fe_bandwidth_t) (
int) tuning.m_bandwidth;
1677 params.u.ofdm.code_rate_HP = (fe_code_rate_t) (
int) tuning.m_hpCodeRate;
1678 params.u.ofdm.code_rate_LP = (fe_code_rate_t) (
int) tuning.m_lpCodeRate;
1679 params.u.ofdm.constellation = (fe_modulation_t) (
int) tuning.m_modulation;
1680 params.u.ofdm.transmission_mode = (fe_transmit_mode_t) (
int) tuning.m_transMode;
1681 params.u.ofdm.guard_interval = (fe_guard_interval_t) (
int) tuning.m_guardInterval;
1682 params.u.ofdm.hierarchy_information = (fe_hierarchy_t) (
int) tuning.m_hierarchy;
1687 params.u.vsb.modulation = (fe_modulation_t) (
int) tuning.m_modulation;
1696 DTVTunerType tuner_type,
const dvb_frontend_parameters ¶ms)
1707 tuning.
m_fec = params.u.qpsk.fec_inner;
1713 tuning.
m_fec = params.u.qam.fec_inner;
1724 tuning.
m_transMode = params.u.ofdm.transmission_mode;
1726 tuning.
m_hierarchy = params.u.ofdm.hierarchy_information;
1741 uint intermediate_freq,
bool can_fec_auto,
bool do_tune)
1746 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]: m_modsys:%2 current_sys:%3")
1747 .arg(QString::number(inputId),
1751 auto *cmdseq = (
struct dtv_properties*) calloc(1,
sizeof(
struct dtv_properties));
1755 cmdseq->props = (
struct dtv_property*) calloc(20,
sizeof(*(cmdseq->props)));
1756 if (!(cmdseq->props))
1767 can_fec_auto =
false;
1777 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1778 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1782 delivery_system = current_sys;
1783 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1784 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1789 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1790 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1795 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1796 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1801 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1802 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1807 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1808 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1813 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1814 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1819 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"DVBChan[%1]:%2 set delivery_system to %3")
1820 .arg(inputId).arg(__LINE__).arg(delivery_system.
toString()));
1823 LOG(VB_CHANNEL, LOG_INFO, QString(
"DVBChan[%1]: Delivery system: %2")
1824 .arg(inputId).arg(delivery_system.
toString()));
1828 cmdseq->props[c].cmd = DTV_DELIVERY_SYSTEM;
1829 cmdseq->props[c++].u.data = delivery_system;
1833 LOG(VB_GENERAL, LOG_ERR, QString(
"DVBChan[%1]: Delivery system: %2")
1834 .arg(inputId).arg(delivery_system.
toString()));
1838 cmdseq->props[c].cmd = DTV_FREQUENCY;
1839 cmdseq->props[c++].u.data = intermediate_freq ? intermediate_freq : tuning.
m_frequency;
1840 cmdseq->props[c].cmd = DTV_MODULATION;
1842 cmdseq->props[c].cmd = DTV_INVERSION;
1850 cmdseq->props[c].cmd = DTV_SYMBOL_RATE;
1857 cmdseq->props[c].cmd = DTV_INNER_FEC;
1858 cmdseq->props[c++].u.data = can_fec_auto ? FEC_AUTO
1859 : (fe_code_rate_t) (
int) tuning.
m_fec;
1866 cmdseq->props[c].cmd = DTV_BANDWIDTH_HZ;
1867 cmdseq->props[c++].u.data = (8-tuning.
m_bandwidth) * 1000000;
1868 cmdseq->props[c].cmd = DTV_CODE_RATE_HP;
1870 cmdseq->props[c].cmd = DTV_CODE_RATE_LP;
1872 cmdseq->props[c].cmd = DTV_TRANSMISSION_MODE;
1874 cmdseq->props[c].cmd = DTV_GUARD_INTERVAL;
1876 cmdseq->props[c].cmd = DTV_HIERARCHY;
1883 cmdseq->props[c].cmd = DTV_ROLLOFF;
1890 cmdseq->props[c].cmd = DTV_PILOT;
1891 cmdseq->props[c++].u.data = PILOT_AUTO;
1892 cmdseq->props[c].cmd = DTV_ROLLOFF;
1893 cmdseq->props[c++].u.data = tuning.
m_rolloff;
1897 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