diff options
author | hschang <chang@dev3> | 2018-02-28 06:53:32 (GMT) |
---|---|---|
committer | hschang <chang@dev3> | 2018-02-28 06:53:32 (GMT) |
commit | faaf85f037e9d29dd9f5178016caf7c80776d55b (patch) | |
tree | 0158b405cbd0b3d8d13a95dd7e7465c1eb4271c9 /lib/dvb | |
parent | 1d557af556c71a9c658deea9cec783a66903c136 (diff) |
Support DVB-S2X.
Diffstat (limited to 'lib/dvb')
-rwxr-xr-x | lib/dvb/db.cpp | 64 | ||||
-rw-r--r-- | lib/dvb/dvb.cpp | 18 | ||||
-rw-r--r-- | lib/dvb/dvb.h | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | lib/dvb/frontend.cpp | 262 | ||||
-rw-r--r-- | lib/dvb/frontend.h | 2 | ||||
-rw-r--r-- | lib/dvb/frontendparms.h | 16 | ||||
-rw-r--r-- | lib/dvb/scan.cpp | 30 |
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, |