summaryrefslogtreecommitdiff
path: root/lib/dvb
diff options
context:
space:
mode:
authorhschang <chang@dev3>2018-02-28 06:53:32 (GMT)
committerhschang <chang@dev3>2018-02-28 06:53:32 (GMT)
commitfaaf85f037e9d29dd9f5178016caf7c80776d55b (patch)
tree0158b405cbd0b3d8d13a95dd7e7465c1eb4271c9 /lib/dvb
parent1d557af556c71a9c658deea9cec783a66903c136 (diff)
Support DVB-S2X.
Diffstat (limited to 'lib/dvb')
-rwxr-xr-xlib/dvb/db.cpp64
-rw-r--r--lib/dvb/dvb.cpp18
-rw-r--r--lib/dvb/dvb.h1
-rw-r--r--[-rwxr-xr-x]lib/dvb/frontend.cpp262
-rw-r--r--lib/dvb/frontend.h2
-rw-r--r--lib/dvb/frontendparms.h16
-rw-r--r--lib/dvb/scan.cpp30
7 files changed, 297 insertions, 96 deletions
diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp
index 0f367be..b2d21f4 100755
--- a/lib/dvb/db.cpp
+++ b/lib/dvb/db.cpp
@@ -378,11 +378,17 @@ void eDVBDB::loadServicelist(const char *file)
system=eDVBFrontendParametersSatellite::System_DVB_S,
modulation=eDVBFrontendParametersSatellite::Modulation_QPSK,
rolloff=eDVBFrontendParametersSatellite::RollOff_alpha_0_35,
- pilot=eDVBFrontendParametersSatellite::Pilot_Unknown;
+ pilot=eDVBFrontendParametersSatellite::Pilot_Unknown,
+ is_id = NO_STREAM_ID_FILTER,
+ pls_code = 0,
+ pls_mode = eDVBFrontendParametersSatellite::PLS_Unknown;
if (version == 3)
sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &system, &modulation, &rolloff, &pilot);
else
- sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", &frequency, &symbol_rate, &polarisation, &fec, &orbital_position, &inversion, &flags, &system, &modulation, &rolloff, &pilot);
+ sscanf(line+3, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ &frequency, &symbol_rate, &polarisation, &fec, &orbital_position,
+ &inversion, &flags, &system, &modulation, &rolloff, &pilot,
+ &is_id, &pls_code, &pls_mode);
sat.frequency = frequency;
sat.symbol_rate = symbol_rate;
sat.polarisation = polarisation;
@@ -394,6 +400,9 @@ void eDVBDB::loadServicelist(const char *file)
sat.modulation = modulation;
sat.rolloff = rolloff;
sat.pilot = pilot;
+ sat.is_id = is_id;
+ sat.pls_mode = pls_mode & 3;
+ sat.pls_code = pls_code & 0x3FFFF;
feparm->setDVBS(sat);
feparm->setFlags(flags);
} else if (line[1]=='t')
@@ -512,27 +521,23 @@ void eDVBDB::saveServicelist(const char *file)
ch.m_frontendParameters->getFlags(flags);
if (!ch.m_frontendParameters->getDVBS(sat))
{
- if (sat.system == eDVBFrontendParametersSatellite::System_DVB_S2)
- {
- fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
- sat.frequency, sat.symbol_rate,
- sat.polarisation, sat.fec,
- sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
- sat.inversion,
- flags,
- sat.system,
- sat.modulation,
- sat.rolloff,
- sat.pilot);
- }
- else
+ fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d",
+ sat.frequency, sat.symbol_rate, sat.polarisation, sat.fec,
+ sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
+ sat.inversion, flags);
+
+ if ((sat.system == eDVBFrontendParametersSatellite::System_DVB_S2) || (sat.system == eDVBFrontendParametersSatellite::System_DVB_S2X))
{
- fprintf(f, "\ts %d:%d:%d:%d:%d:%d:%d\n",
- sat.frequency, sat.symbol_rate,
- sat.polarisation, sat.fec,
- sat.orbital_position > 1800 ? sat.orbital_position - 3600 : sat.orbital_position,
- sat.inversion, flags);
+ fprintf(f, ":%d:%d:%d:%d", sat.system, sat.modulation, sat.rolloff, sat.pilot);
+
+ if (static_cast<unsigned int>(sat.is_id) != NO_STREAM_ID_FILTER ||
+ (sat.pls_code & 0x3FFFF) != 0 ||
+ (sat.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Unknown)
+ {
+ fprintf(f, ":%d:%d:%d", sat.is_id, sat.pls_code & 0x3FFFF, sat.pls_mode & 3);
+ }
}
+ fprintf(f, "\n");
}
else if (!ch.m_frontendParameters->getDVBT(ter))
{
@@ -792,7 +797,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
return Py_False;
}
int tmp, *dest = NULL,
- modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, tsid, onid;
+ modulation, system, freq, sr, pol, fec, inv, pilot, rolloff, is_id, pls_code, pls_mode, tsid, onid;
char *end_ptr;
const Attribute *at;
std::string name;
@@ -857,6 +862,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
inv = eDVBFrontendParametersSatellite::Inversion_Unknown;
pilot = eDVBFrontendParametersSatellite::Pilot_Unknown;
rolloff = eDVBFrontendParametersSatellite::RollOff_alpha_0_35;
+ is_id = NO_STREAM_ID_FILTER;
+ pls_code = 0;
+ pls_mode = eDVBFrontendParametersSatellite::PLS_Unknown;
tsid = -1;
onid = -1;
@@ -874,6 +882,9 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
else if (name == "inversion") dest = &inv;
else if (name == "rolloff") dest = &rolloff;
else if (name == "pilot") dest = &pilot;
+ else if (name == "is_id") dest = &is_id;
+ else if (name == "pls_code") dest = &pls_code;
+ else if (name == "pls_mode") dest = &pls_mode;
else if (name == "tsid") dest = &tsid;
else if (name == "onid") dest = &onid;
else continue;
@@ -887,7 +898,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
}
if (freq && sr && pol != -1)
{
- tuple = PyTuple_New(12);
+ tuple = PyTuple_New(15);
PyTuple_SET_ITEM(tuple, 0, PyInt_FromLong(0));
PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(freq));
PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(sr));
@@ -898,8 +909,11 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
PyTuple_SET_ITEM(tuple, 7, PyInt_FromLong(inv));
PyTuple_SET_ITEM(tuple, 8, PyInt_FromLong(rolloff));
PyTuple_SET_ITEM(tuple, 9, PyInt_FromLong(pilot));
- PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(tsid));
- PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(onid));
+ PyTuple_SET_ITEM(tuple, 10, PyInt_FromLong(is_id));
+ PyTuple_SET_ITEM(tuple, 11, PyInt_FromLong(pls_mode & 3));
+ PyTuple_SET_ITEM(tuple, 12, PyInt_FromLong(pls_code & 0x3FFFF));
+ PyTuple_SET_ITEM(tuple, 13, PyInt_FromLong(tsid));
+ PyTuple_SET_ITEM(tuple, 14, PyInt_FromLong(onid));
PyList_Append(tplist, tuple);
Py_DECREF(tuple);
}
diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp
index 852c403..5ebf10c 100644
--- a/lib/dvb/dvb.cpp
+++ b/lib/dvb/dvb.cpp
@@ -414,6 +414,10 @@ bool eDVBResourceManager::frontendIsCompatible(int index, const char *type)
{
if (i->m_frontend->getSlotID() == index)
{
+ if (!strcmp(type, "DVB-S2X"))
+ {
+ return i->m_frontend->supportsDeliverySystem(SYS_DVBS2X, false);
+ }
if (!strcmp(type, "DVB-S2"))
{
return i->m_frontend->supportsDeliverySystem(SYS_DVBS2, false);
@@ -443,6 +447,18 @@ bool eDVBResourceManager::frontendIsCompatible(int index, const char *type)
return false;
}
+bool eDVBResourceManager::frontendIsMultistream(int index)
+{
+ for (eSmartPtrList<eDVBRegisteredFrontend>::iterator i(m_frontend.begin()); i != m_frontend.end(); ++i)
+ {
+ if (i->m_frontend->getSlotID() == index)
+ {
+ return i->m_frontend->is_multistream();
+ }
+ }
+ return false;
+}
+
void eDVBResourceManager::setFrontendType(int index, const char *type)
{
eDebug("[eDVBResourceManager::setFrontendType] index : %d, type : %s", index, type);
@@ -456,6 +472,8 @@ void eDVBResourceManager::setFrontendType(int index, const char *type)
{
whitelist.push_back(SYS_DVBS);
whitelist.push_back(SYS_DVBS2);
+ if (!strcmp(type, "DVB-S2X"))
+ whitelist.push_back(SYS_DVBS2X);
}
else if (!strcmp(type, "DVB-T2") || !strcmp(type, "DVB-T"))
{
diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h
index 3e9fc7f..f470fe1 100644
--- a/lib/dvb/dvb.h
+++ b/lib/dvb/dvb.h
@@ -224,6 +224,7 @@ public:
SWIG_VOID(RESULT) allocateRawChannel(eUsePtr<iDVBChannel> &SWIG_OUTPUT, int slot_index);
PyObject *setFrontendSlotInformations(SWIG_PYOBJECT(ePyObject) list);
bool frontendIsCompatible(int index, const char *type);
+ bool frontendIsMultistream(int index);
void setFrontendType(int index, const char *type);
};
SWIG_TEMPLATE_TYPEDEF(ePtr<eDVBResourceManager>, eDVBResourceManager);
diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp
index ceecb6d..9d87118 100755..100644
--- a/lib/dvb/frontend.cpp
+++ b/lib/dvb/frontend.cpp
@@ -38,6 +38,9 @@
#define FEC_S2_QPSK_4_5 (fe_code_rate_t)(FEC_4_5)
#define FEC_S2_QPSK_9_10 (fe_code_rate_t)(FEC_9_10)
+/* DVB-S2X */
+#define FEC_S2_QPSK_13_45 (fe_code_rate_t)(FEC_13_45)
+
#include <dvbsi++/satellite_delivery_system_descriptor.h>
#include <dvbsi++/cable_delivery_system_descriptor.h>
#include <dvbsi++/terrestrial_delivery_system_descriptor.h>
@@ -126,29 +129,35 @@ void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescripto
orbital_position = 3600 - orbital_position;
system = descriptor.getModulationSystem();
modulation = descriptor.getModulation();
- if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
+ if (system == eDVBFrontendParametersSatellite::System_DVB_S && modulation != eDVBFrontendParametersSatellite::Modulation_QPSK)
{
eDebug("satellite_delivery_descriptor non valid modulation type.. force QPSK");
modulation=eDVBFrontendParametersSatellite::Modulation_QPSK;
}
rolloff = descriptor.getRollOff();
- if (system == eDVBFrontendParametersSatellite::System_DVB_S2)
+ is_id = NO_STREAM_ID_FILTER;
+ pls_mode = eDVBFrontendParametersSatellite::PLS_Unknown;
+ pls_code = 0;
+ if (system == eDVBFrontendParametersSatellite::System_DVB_S)
{
- eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
+ eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
frequency,
polarisation ? "hor" : "vert",
orbital_position,
- symbol_rate, fec,
- modulation,
- rolloff);
+ symbol_rate, fec);
}
- else
+ else // System_DVB_S2 or System_DVB_S2X
{
- eDebug("SAT DVB-S freq %d, %s, pos %d, sr %d, fec %d",
+ eDebug("SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d, is_id %d, pls_mode %d, pls_code %d",
frequency,
polarisation ? "hor" : "vert",
orbital_position,
- symbol_rate, fec);
+ symbol_rate, fec,
+ modulation,
+ rolloff,
+ is_id,
+ pls_mode,
+ pls_code);
}
}
@@ -356,6 +365,12 @@ RESULT eDVBFrontendParameters::calculateDifference(const iDVBFrontendParameters
diff = 1<<29;
else if (sat.polarisation != osat.polarisation)
diff = 1<<28;
+ else if (sat.is_id != osat.is_id)
+ diff = 1<<27;
+ else if (sat.pls_mode != osat.pls_mode)
+ diff = 1<<27;
+ else if (sat.pls_code != osat.pls_code)
+ diff = 1<<27;
else if (exact && sat.fec != osat.fec && sat.fec != eDVBFrontendParametersSatellite::FEC_Auto && osat.fec != eDVBFrontendParametersSatellite::FEC_Auto)
diff = 1<<27;
else if (exact && sat.modulation != osat.modulation && sat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto && osat.modulation != eDVBFrontendParametersSatellite::Modulation_Auto)
@@ -527,7 +542,6 @@ int eDVBFrontend::openFrontend()
m_state=stateIdle;
m_tuning=0;
- dvb_frontend_info fe_info;
if (!m_simulate)
{
eDebug("opening frontend %d", m_dvbid);
@@ -545,6 +559,13 @@ int eDVBFrontend::openFrontend()
if (m_delsys.empty())
{
+ if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
+ {
+ eWarning("ioctl FE_GET_INFO failed");
+ ::close(m_fd);
+ m_fd = -1;
+ return -1;
+ }
#ifdef DTV_ENUM_DELSYS
struct dtv_property p[1];
p[0].cmd = DTV_ENUM_DELSYS;
@@ -561,48 +582,46 @@ int eDVBFrontend::openFrontend()
m_delsys[delsys] = true;
}
}
+ else
#else
- if (::ioctl(m_fd, FE_GET_INFO, &fe_info) < 0)
+ /* no DTV_ENUM_DELSYS support */
+ if (1)
+#endif
{
- eWarning("ioctl FE_GET_INFO failed");
- ::close(m_fd);
- m_fd = -1;
- return -1;
- }
/* old DVB API, fill delsys map with some defaults */
- switch (fe_info.type)
- {
- case FE_QPSK:
+ switch (fe_info.type)
{
- m_delsys[SYS_DVBS] = true;
+ case FE_QPSK:
+ {
+ m_delsys[SYS_DVBS] = true;
#if DVB_API_VERSION >= 5
- if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
+ if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBS2] = true;
#endif
- break;
- }
- case FE_QAM:
- {
+ break;
+ }
+ case FE_QAM:
+ {
#if defined SYS_DVBC_ANNEX_A
- m_delsys[SYS_DVBC_ANNEX_A] = true;
+ m_delsys[SYS_DVBC_ANNEX_A] = true;
#else
- m_delsys[SYS_DVBC_ANNEX_AC] = true;
+ m_delsys[SYS_DVBC_ANNEX_AC] = true;
#endif
- break;
- }
- case FE_OFDM:
- {
- m_delsys[SYS_DVBT] = true;
+ break;
+ }
+ case FE_OFDM:
+ {
+ m_delsys[SYS_DVBT] = true;
#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 3
- if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
+ if (fe_info.caps & FE_CAN_2G_MODULATION) m_delsys[SYS_DVBT2] = true;
#endif
- break;
- }
- case FE_ATSC: // placeholder to prevent warning
- {
- break;
+ break;
+ }
+ case FE_ATSC: // placeholder to prevent warning
+ {
+ break;
+ }
}
}
-#endif
}
if (m_simulate_fe)
@@ -613,6 +632,26 @@ int eDVBFrontend::openFrontend()
m_sn = eSocketNotifier::create(eApp, m_fd, eSocketNotifier::Read, false);
CONNECT(m_sn->activated, eDVBFrontend::feEvent);
}
+ else
+ {
+ fe_info.frequency_min = 900000;
+ fe_info.frequency_max = 2200000;
+
+ eDebug("[eDVBFrontend] opening frontend %d", m_dvbid);
+ int tmp_fd = ::open(m_filename, O_RDONLY | O_NONBLOCK);
+ if (tmp_fd < 0)
+ {
+ eWarning("[eDVBFrontend] opening %s failed: %m", m_filename);
+ }
+ else
+ {
+ if (::ioctl(tmp_fd, FE_GET_INFO, &fe_info) < 0)
+ {
+ eWarning("[eDVBFrontend] ioctl FE_GET_INFO on frontend %s failed: %m", m_filename);
+ }
+ ::close(tmp_fd);
+ }
+ }
setTone(iDVBFrontend::toneOff);
setVoltage(iDVBFrontend::voltageOff);
@@ -1054,10 +1093,13 @@ void PutSatelliteDataToDict(ePyObject &dict, eDVBFrontendParametersSatellite &fe
PutToDict(dict, "fec_inner", feparm.fec);
PutToDict(dict, "modulation", feparm.modulation);
PutToDict(dict, "polarization", feparm.polarisation);
- if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
+ if ((feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2) || (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2X))
{
PutToDict(dict, "rolloff", feparm.rolloff);
PutToDict(dict, "pilot", feparm.pilot);
+ PutToDict(dict, "is_id", feparm.is_id);
+ PutToDict(dict, "pls_mode", feparm.pls_mode);
+ PutToDict(dict, "pls_code", feparm.pls_code);
}
PutToDict(dict, "system", feparm.system);
}
@@ -1091,7 +1133,7 @@ void PutCableDataToDict(ePyObject &dict, eDVBFrontendParametersCable &feparm)
PutToDict(dict, "fec_inner", feparm.fec_inner);
}
-static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, int orbital_position, int polarization)
+static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, long freq_offset, eDVBFrontendParametersSatellite &feparm)
{
long tmp=0;
int p_system = p[0].u.data;
@@ -1102,12 +1144,13 @@ static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, lo
int p_inner_fec = p[5].u.data;
int p_rolloff = p[6].u.data;
int p_pilot = p[7].u.data;
+ int p_stream_id = p[8].u.data;
int frequency = p_frequency + freq_offset;
PutToDict(dict, "frequency", frequency);
PutToDict(dict, "symbol_rate", p_symbolrate);
- PutToDict(dict, "orbital_position", orbital_position);
- PutToDict(dict, "polarization", polarization);
+ PutToDict(dict, "orbital_position", feparm.orbital_position);
+ PutToDict(dict, "polarization", feparm.polarisation);
switch(p_inner_fec)
{
@@ -1120,6 +1163,7 @@ static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, lo
case FEC_7_8: tmp = eDVBFrontendParametersSatellite::FEC_7_8; break;
case FEC_8_9: tmp = eDVBFrontendParametersSatellite::FEC_8_9; break;
case FEC_9_10: tmp = eDVBFrontendParametersSatellite::FEC_9_10; break;
+ case FEC_13_45 ... FEC_26_45_L: tmp = eDVBFrontendParametersSatellite::FEC_13_45 + (long)(p_inner_fec - FEC_13_45); break;
case FEC_NONE: tmp = eDVBFrontendParametersSatellite::FEC_None; break;
case FEC_AUTO: tmp = eDVBFrontendParametersSatellite::FEC_Auto; break;
default: eDebug("got unsupported FEC from frontend! report as FEC_AUTO!\n");
@@ -1130,7 +1174,12 @@ static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, lo
{
default: eDebug("got unsupported system from frontend! report as DVBS!");
case SYS_DVBS: tmp = eDVBFrontendParametersSatellite::System_DVB_S; break;
- case SYS_DVBS2:
+ case SYS_DVBS2: tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
+ case SYS_DVBS2X: tmp = eDVBFrontendParametersSatellite::System_DVB_S2X; break;
+ }
+ PutToDict(dict, "system", tmp);
+
+ if ((p_system == SYS_DVBS2) || (p_system == SYS_DVBS2X))
{
switch (p_rolloff)
{
@@ -1149,16 +1198,19 @@ static void fillDictWithSatelliteData(ePyObject dict, struct dtv_property *p, lo
}
PutToDict(dict, "pilot", tmp);
- tmp = eDVBFrontendParametersSatellite::System_DVB_S2; break;
+ PutToDict(dict, "is_id", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.is_id : (p_stream_id & 0xFF));
+ PutToDict(dict, "pls_mode", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.pls_mode : ((p_stream_id >> 26) & 0x3));
+ PutToDict(dict, "pls_code", ((unsigned int)p_stream_id == NO_STREAM_ID_FILTER) ? feparm.pls_code : ((p_stream_id >> 8) & 0x3FFFF));
}
- }
- PutToDict(dict, "system", tmp);
switch (p_modulation)
{
default: eDebug("got unsupported modulation from frontend! report as QPSK!");
case QPSK: tmp = eDVBFrontendParametersSatellite::Modulation_QPSK; break;
case PSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8PSK; break;
+ case APSK_8: tmp = eDVBFrontendParametersSatellite::Modulation_8APSK; break;
+ case APSK_16: tmp = eDVBFrontendParametersSatellite::Modulation_16APSK; break;
+ case APSK_32: tmp = eDVBFrontendParametersSatellite::Modulation_32APSK; break;
}
PutToDict(dict, "modulation", tmp);
@@ -1426,6 +1478,7 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
p[cmdseq.num++].cmd = DTV_INNER_FEC;
p[cmdseq.num++].cmd = DTV_ROLLOFF;
p[cmdseq.num++].cmd = DTV_PILOT;
+ p[cmdseq.num++].cmd = DTV_STREAM_ID;
}
else if(type == feCable)
{
@@ -1485,13 +1538,12 @@ void eDVBFrontend::getTransponderData(ePyObject dest, bool original)
}
else
{
- FRONTENDPARAMETERS &parm = front;
switch(type)
{
case feSatellite:
eDVBFrontendParametersSatellite sparm;
oparm.getDVBS(sparm);
- fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm.orbital_position, sparm.polarisation);
+ fillDictWithSatelliteData(dest, p, m_data[FREQ_OFFSET], sparm);
break;
case feCable:
fillDictWithCableData(dest, p);
@@ -1511,7 +1563,7 @@ void eDVBFrontend::getFrontendData(ePyObject dest)
const char *tmp=0;
PutToDict(dest, "tuner_number", m_slotid);
- if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true))
+ if (supportsDeliverySystem(SYS_DVBS, true) || supportsDeliverySystem(SYS_DVBS2, true) || supportsDeliverySystem(SYS_DVBS2X, true))
{
tmp = "DVB-S";
}
@@ -2009,12 +2061,16 @@ void eDVBFrontend::setFrontend(bool recvEvents)
{
case eDVBFrontendParametersSatellite::System_DVB_S: system = SYS_DVBS; break;
case eDVBFrontendParametersSatellite::System_DVB_S2: system = SYS_DVBS2; break;
+ case eDVBFrontendParametersSatellite::System_DVB_S2X: system = SYS_DVBS2X; break;
};
switch(sparm.modulation)
{
case eDVBFrontendParametersSatellite::Modulation_QPSK: modulation = QPSK; break;
case eDVBFrontendParametersSatellite::Modulation_8PSK: modulation = PSK_8; break;
case eDVBFrontendParametersSatellite::Modulation_QAM16: modulation = QAM_16; break;
+ case eDVBFrontendParametersSatellite::Modulation_8APSK: modulation = APSK_8; break;
+ case eDVBFrontendParametersSatellite::Modulation_16APSK: modulation = APSK_16; break;
+ case eDVBFrontendParametersSatellite::Modulation_32APSK: modulation = APSK_32; break;
};
switch(sparm.pilot)
{
@@ -2028,7 +2084,7 @@ void eDVBFrontend::setFrontend(bool recvEvents)
case eDVBFrontendParametersSatellite::RollOff_alpha_0_25: rolloff = ROLLOFF_25; break;
case eDVBFrontendParametersSatellite::RollOff_alpha_0_35: rolloff = ROLLOFF_35; break;
};
- struct dtv_property p[10];
+ struct dtv_property p[11];
struct dtv_properties cmdseq;
cmdseq.props = p;
p[0].cmd = DTV_CLEAR;
@@ -2038,12 +2094,13 @@ void eDVBFrontend::setFrontend(bool recvEvents)
p[4].cmd = DTV_SYMBOL_RATE, p[4].u.data = parm_u_qpsk_symbol_rate;
p[5].cmd = DTV_INNER_FEC, p[5].u.data = parm_u_qpsk_fec_inner;
p[6].cmd = DTV_INVERSION, p[6].u.data = parm_inversion;
- if (system == SYS_DVBS2)
+ if ((system == SYS_DVBS2) || (system == SYS_DVBS2X))
{
p[7].cmd = DTV_ROLLOFF, p[7].u.data = rolloff;
p[8].cmd = DTV_PILOT, p[8].u.data = pilot;
- p[9].cmd = DTV_TUNE;
- cmdseq.num = 10;
+ p[9].cmd = DTV_STREAM_ID, p[9].u.data = sparm.is_id | (sparm.pls_code << 8) | (sparm.pls_mode << 26);
+ p[10].cmd = DTV_TUNE;
+ cmdseq.num = 11;
}
else
{
@@ -2152,8 +2209,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
res = m_sec->prepare(*this, parm, feparm, 1 << m_slotid, tunetimeout);
if (!res)
{
- eDebugNoSimulate("prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d",
- feparm.system,
+ eDebugNoSimulate("prepare_sat Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d, is_id %d, pls_mode %d, pls_code %d",
feparm.frequency,
feparm.polarisation,
feparm.symbol_rate,
@@ -2163,7 +2219,10 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
feparm.system,
feparm.modulation,
feparm.pilot,
- feparm.rolloff);
+ feparm.rolloff,
+ feparm.is_id,
+ feparm.pls_mode,
+ feparm.pls_code);
parm_u_qpsk_symbol_rate = feparm.symbol_rate;
switch (feparm.inversion)
{
@@ -2207,7 +2266,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
break;
}
}
- else // DVB_S2
+ else if (feparm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
{
switch (feparm.fec)
{
@@ -2243,6 +2302,45 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
return -EINVAL;
}
}
+ else // DVB_S2X
+ {
+ switch (feparm.fec)
+ {
+ case eDVBFrontendParametersSatellite::FEC_1_2:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_1_2;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_2_3:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_2_3;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_3_4:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_4;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_3_5:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_3_5;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_4_5:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_4_5;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_5_6:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_5_6;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_7_8:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_7_8;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_8_9:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_8_9;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_9_10:
+ parm_u_qpsk_fec_inner = FEC_S2_QPSK_9_10;
+ break;
+ case eDVBFrontendParametersSatellite::FEC_13_45 ... eDVBFrontendParametersSatellite::FEC_26_45_L:
+ parm_u_qpsk_fec_inner = (fe_code_rate_t)((int)FEC_S2_QPSK_13_45 + (feparm.fec-eDVBFrontendParametersSatellite::FEC_13_45));
+ break;
+ default:
+ eDebugNoSimulate("no valid fec for DVB-S2X set.. abort !!");
+ return -EINVAL;
+ }
+ }
// FIXME !!! get frequency range from tuner
if ( parm_frequency < 900000 || parm_frequency > 2200000 )
{
@@ -2827,13 +2925,18 @@ int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
if (type == eDVBFrontend::feSatellite)
{
eDVBFrontendParametersSatellite sat_parm;
- bool can_handle_dvbs, can_handle_dvbs2;
+ bool can_handle_dvbs, can_handle_dvbs2, can_handle_dvbs2x;
can_handle_dvbs = supportsDeliverySystem(SYS_DVBS, true);
can_handle_dvbs2 = supportsDeliverySystem(SYS_DVBS2, true);
+ can_handle_dvbs2x = supportsDeliverySystem(SYS_DVBS2X, true);
if (feparm->getDVBS(sat_parm) < 0)
{
return 0;
}
+ if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X && !can_handle_dvbs2x)
+ {
+ return 0;
+ }
if (sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && !can_handle_dvbs2)
{
return 0;
@@ -2842,12 +2945,29 @@ int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
{
return 0;
}
+ bool multistream = (static_cast<unsigned int>(sat_parm.is_id) != NO_STREAM_ID_FILTER || (sat_parm.pls_code & 0x3FFFF) != 0 ||
+ (sat_parm.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Unknown);
+
+ if (((sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2)||(sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X)) && multistream && !is_multistream())
+ {
+ return 0;
+ }
score = m_sec ? m_sec->canTune(sat_parm, this, 1 << m_slotid) : 0;
if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
{
/* prefer to use a S tuner, try to keep S2 free for S2 transponders */
score--;
}
+ if (score > 1 && sat_parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && can_handle_dvbs2x)
+ {
+ /* prefer to use a S2 tuner, try to keep S2X free for S2X transponders */
+ score--;
+ }
+ if (score > 1 && is_multistream() && !multistream)
+ {
+ /* prefer to use a non multistream tuner, try to keep multistream tuners free for multistream transponders */
+ score--;
+ }
}
else if (type == eDVBFrontend::feCable)
@@ -2933,17 +3053,18 @@ void eDVBFrontend::setDeliverySystemWhitelist(const std::vector<fe_delivery_syst
bool eDVBFrontend::setSlotInfo(ePyObject obj)
{
- ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, frontendId;
- if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 6)
+ ePyObject Id, Descr, Enabled, IsDVBS2, IsDVBT2, IsDVBS2X, frontendId;
+ if (!PyTuple_Check(obj) || PyTuple_Size(obj) != 7)
goto arg_error;
Id = PyTuple_GET_ITEM(obj, 0);
Descr = PyTuple_GET_ITEM(obj, 1);
Enabled = PyTuple_GET_ITEM(obj, 2);
IsDVBS2 = PyTuple_GET_ITEM(obj, 3);
IsDVBT2 = PyTuple_GET_ITEM(obj, 4);
- frontendId = PyTuple_GET_ITEM(obj, 5);
+ IsDVBS2X = PyTuple_GET_ITEM(obj, 5);
+ frontendId = PyTuple_GET_ITEM(obj, 6);
m_slotid = PyInt_AsLong(Id);
- if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyInt_Check(frontendId))
+ if (!PyInt_Check(Id) || !PyString_Check(Descr) || !PyBool_Check(Enabled) || !PyBool_Check(IsDVBS2) || !PyBool_Check(IsDVBT2) || !PyBool_Check(IsDVBS2X) || !PyInt_Check(frontendId))
goto arg_error;
strcpy(m_description, PyString_AS_STRING(Descr));
if (PyInt_AsLong(frontendId) == -1 || PyInt_AsLong(frontendId) != m_dvbid) {
@@ -2967,12 +3088,23 @@ bool eDVBFrontend::setSlotInfo(ePyObject obj)
/* HACK for legacy dvb api without DELSYS support */
m_delsys[SYS_DVBT2] = true;
}
+ if (IsDVBS2X == Py_True)
+ {
+ /* HACK for legacy dvb api without DELSYS support */
+ m_delsys[SYS_DVBS2X] = true;
+ }
- eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s",
- m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", Enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No" );
+ eDebugNoSimulate("setSlotInfo for dvb frontend %d to slotid %d, descr %s, need rotorworkaround %s, enabled %s, DVB-S2 %s, DVB-T2 %s, DVB-S2X %s",
+ m_dvbid, m_slotid, m_description, m_need_rotor_workaround ? "Yes" : "No", Enabled == Py_True ? "Yes" : "No", IsDVBS2 == Py_True ? "Yes" : "No", IsDVBT2 == Py_True ? "Yes" : "No", IsDVBS2X == Py_True ? "Yes" : "No");
return true;
arg_error:
PyErr_SetString(PyExc_StandardError,
"eDVBFrontend::setSlotInfo must get a tuple with first param slotid, second param slot description and third param enabled boolean");
return false;
}
+
+bool eDVBFrontend::is_multistream()
+{
+ return fe_info.caps & FE_CAN_MULTISTREAM;
+}
+
diff --git a/lib/dvb/frontend.h b/lib/dvb/frontend.h
index 6a8c39d..39d125a 100644
--- a/lib/dvb/frontend.h
+++ b/lib/dvb/frontend.h
@@ -87,6 +87,7 @@ private:
std::map<fe_delivery_system_t, bool> m_delsys, m_delsys_whitelist;
char m_filename[128];
char m_description[128];
+ dvb_frontend_info fe_info;
FRONTENDPARAMETERS parm;
eDVBFrontendParameters oparm;
@@ -163,6 +164,7 @@ public:
bool isLoopTimerActive() { return m_tuneTimer->isActive(); }
bool isScheduledSendDiseqc();
void setUSBTuner(bool yesno) { m_is_usbtuner = yesno; }
+ bool is_multistream();
};
#endif // SWIG
diff --git a/lib/dvb/frontendparms.h b/lib/dvb/frontendparms.h
index b2a2cd7..5895023 100644
--- a/lib/dvb/frontendparms.h
+++ b/lib/dvb/frontendparms.h
@@ -22,15 +22,19 @@ struct eDVBFrontendParametersSatellite
};
enum {
- FEC_Auto, FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_7_8, FEC_8_9, FEC_3_5, FEC_4_5, FEC_9_10, FEC_None=15
+ FEC_Auto=0, FEC_1_2=1, FEC_2_3=2, FEC_3_4=3, FEC_5_6=4, FEC_7_8=5, FEC_8_9=6, FEC_3_5=7, FEC_4_5=8, FEC_9_10=9, FEC_None=15,
+ FEC_13_45=16, FEC_9_20=17, FEC_11_20=18, FEC_23_36=19, FEC_25_36=20,
+ FEC_13_18=21, FEC_26_45=22, FEC_28_45=23, FEC_7_9=24, FEC_77_90=25,
+ FEC_32_45=26, FEC_11_15=27, FEC_1_2_L=28, FEC_8_15_L=29, FEC_3_5_L=30,
+ FEC_2_3_L=31, FEC_5_9_L=32, FEC_26_45_L=33
};
enum {
- System_DVB_S, System_DVB_S2
+ System_DVB_S, System_DVB_S2, System_DVB_S2X
};
enum {
- Modulation_Auto, Modulation_QPSK, Modulation_8PSK, Modulation_QAM16
+ Modulation_Auto, Modulation_QPSK, Modulation_8PSK, Modulation_QAM16, Modulation_16APSK, Modulation_32APSK, Modulation_8APSK
};
// dvb-s2
@@ -42,9 +46,13 @@ struct eDVBFrontendParametersSatellite
Pilot_Off, Pilot_On, Pilot_Unknown
};
+ enum {
+ PLS_Root, PLS_Gold, PLS_Combo, PLS_Unknown
+ };
+
bool no_rotor_command_on_tune;
unsigned int frequency, symbol_rate;
- int polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot;
+ int polarisation, fec, inversion, orbital_position, system, modulation, rolloff, pilot, is_id, pls_mode, pls_code;
};
SWIG_ALLOW_OUTPUT_SIMPLE(eDVBFrontendParametersSatellite);
diff --git a/lib/dvb/scan.cpp b/lib/dvb/scan.cpp
index 46236dd..1906c12 100644
--- a/lib/dvb/scan.cpp
+++ b/lib/dvb/scan.cpp
@@ -868,15 +868,41 @@ void eDVBScan::channelDone()
{
case iDVBFrontend::feSatellite:
{
+ char system_name[255];
+ char modulation_name[255];
+ memset(system_name, 0, sizeof(system_name));
+ memset(modulation_name, 0, sizeof(modulation_name));
+
eDVBFrontendParametersSatellite parm;
m_ch_current->getDVBS(parm);
+
+ if (parm.system == eDVBFrontendParametersSatellite::System_DVB_S2)
+ strcpy(system_name, "DVB-S2");
+ else if (parm.system == eDVBFrontendParametersSatellite::System_DVB_S2X)
+ strcpy(system_name, "DVB-S2X");
+ else
+ strcpy(system_name, "DVB-S");
+
+ if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_QPSK)
+ strcpy(modulation_name, "QPSK");
+ else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_8PSK)
+ strcpy(modulation_name, "8PSK");
+ else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_8APSK)
+ strcpy(modulation_name, "8APSK");
+ else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_16APSK)
+ strcpy(modulation_name, "16APSK");
+ else if (parm.modulation == eDVBFrontendParametersSatellite::Modulation_32APSK)
+ strcpy(modulation_name, "32APSK");
+ else
+ strcpy(modulation_name, "8PSK");
+
snprintf(sname, 255, "%d%c SID 0x%02x",
parm.frequency/1000,
parm.polarisation ? 'V' : 'H',
m_pmt_in_progress->first);
snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
- parm.system ? "DVB-S2" : "DVB-S",
- parm.modulation == 1 ? "QPSK" : "8PSK",
+ system_name,
+ modulation_name,
parm.frequency/1000,
parm.polarisation ? 'V' : 'H',
parm.orbital_position/10,