Skip to content

Commit

Permalink
Support Multistream (#879)
Browse files Browse the repository at this point in the history
Add support for MIS/PLS in Enigma2 since new boxes with S2X now include it.

Based on original work by @crazycat69 on Enigma2PC.

Closes #421
  • Loading branch information
athoik authored and littlesat committed Apr 10, 2017
1 parent 11eb3ac commit 4535bc8
Show file tree
Hide file tree
Showing 16 changed files with 236 additions and 46 deletions.
44 changes: 36 additions & 8 deletions lib/dvb/db.cpp
Expand Up @@ -408,10 +408,14 @@ static ePtr<eDVBFrontendParameters> parseFrontendData(char* line, int version)
system=eDVBFrontendParametersSatellite::System_DVB_S,
modulation=eDVBFrontendParametersSatellite::Modulation_QPSK,
rolloff=eDVBFrontendParametersSatellite::RollOff_alpha_0_35,
pilot=eDVBFrontendParametersSatellite::Pilot_Unknown;
sscanf(line+2, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
pilot=eDVBFrontendParametersSatellite::Pilot_Unknown,
is_id = NO_STREAM_ID_FILTER,
pls_code = 1,
pls_mode = eDVBFrontendParametersSatellite::PLS_Root;
sscanf(line+2, "%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);
&inversion, &flags, &system, &modulation, &rolloff, &pilot,
&is_id, &pls_code, &pls_mode);
sat.frequency = frequency;
sat.symbol_rate = symbol_rate;
sat.polarisation = polarisation;
Expand All @@ -434,8 +438,13 @@ static ePtr<eDVBFrontendParameters> parseFrontendData(char* line, int version)
// sat.parm3 = parm3;
//}
//else ...
if (strncmp(options, "MIS/PLS:", 8) == 0)
sscanf(options+8, "%d:%d:%d", &is_id, &pls_code, &pls_mode);
options = next;
}
sat.is_id = is_id;
sat.pls_mode = pls_mode & 3;
sat.pls_code = pls_code & 0x3FFFF;
feparm->setDVBS(sat);
feparm->setFlags(flags);
break;
Expand Down Expand Up @@ -711,7 +720,7 @@ void eDVBDB::saveServicelist(const char *file)
fprintf(g, "eDVB services /5/\n");
fprintf(g, "# Transponders: t:dvb_namespace:transport_stream_id:original_network_id,FEPARMS\n");
fprintf(g, "# DVBS FEPARMS: s:frequency:symbol_rate:polarisation:fec:orbital_position:inversion:flags\n");
fprintf(g, "# DVBS2 FEPARMS: s:frequency:symbol_rate:polarisation:fec:orbital_position:inversion:flags:system:modulation:rolloff:pilot\n");
fprintf(g, "# DVBS2 FEPARMS: s:frequency:symbol_rate:polarisation:fec:orbital_position:inversion:flags:system:modulation:rolloff:pilot[,MIS/PLS:is_id:pls_code:pls_mode]\n");
fprintf(g, "# DVBT FEPARMS: t:frequency:bandwidth:code_rate_HP:code_rate_LP:modulation:transmission_mode:guard_interval:hierarchy:inversion:flags:system:plp_id\n");
fprintf(g, "# DVBC FEPARMS: c:frequency:symbol_rate:inversion:modulation:fec_inner:flags:system\n");
fprintf(g, "# ATSC FEPARMS: a:frequency:inversion:modulation:flags:system\n");
Expand Down Expand Up @@ -752,6 +761,16 @@ void eDVBDB::saveServicelist(const char *file)
fprintf(f, ":%d:%d:%d:%d", sat.system, sat.modulation, sat.rolloff, sat.pilot);
if (g)
fprintf(g, ":%d:%d:%d:%d", sat.system, sat.modulation, sat.rolloff, sat.pilot);

if (sat.is_id != NO_STREAM_ID_FILTER ||
(sat.pls_code & 0x3FFFF) != 1 ||
(sat.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Root)
{
fprintf(f, ":%d:%d:%d", sat.is_id, sat.pls_code & 0x3FFFF, sat.pls_mode & 3);
if (g)
fprintf(g, ",MIS/PLS:%d:%d:%d", sat.is_id, sat.pls_code & 0x3FFFF, sat.pls_mode & 3);
}

}
fprintf(f, "\n");
if (g)
Expand Down Expand Up @@ -1230,7 +1249,7 @@ PyObject *eDVBDB::readSatellites(ePyObject sat_list, ePyObject sat_dict, ePyObje
}

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;

xmlNode *root_element = xmlDocGetRootElement(doc);
Expand Down Expand Up @@ -1294,6 +1313,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 = 1;
pls_mode = eDVBFrontendParametersSatellite::PLS_Root;
tsid = -1;
onid = -1;

Expand All @@ -1309,6 +1331,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;
Expand All @@ -1325,7 +1350,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));
Expand All @@ -1336,8 +1361,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);
}
Expand Down
39 changes: 34 additions & 5 deletions lib/dvb/frontend.cpp
Expand Up @@ -109,15 +109,21 @@ void eDVBFrontendParametersSatellite::set(const SatelliteDeliverySystemDescripto
modulation = Modulation_QPSK;
}
rolloff = descriptor.getRollOff();
is_id = NO_STREAM_ID_FILTER;
pls_mode = eDVBFrontendParametersSatellite::PLS_Root;
pls_code = 1;
if (system == System_DVB_S2)
{
eDebug("[eDVBFrontendParametersSatellite] SAT DVB-S2 freq %d, %s, pos %d, sr %d, fec %d, modulation %d, rolloff %d",
eDebug("[eDVBFrontendParametersSatellite] 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,
modulation,
rolloff);
rolloff,
is_id,
pls_mode,
pls_code);
}
else
{
Expand Down Expand Up @@ -340,6 +346,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)
Expand Down Expand Up @@ -1368,6 +1380,7 @@ void eDVBFrontend::getTransponderData(ePtr<iDVBTransponderData> &dest, bool orig
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)
{
Expand All @@ -1382,6 +1395,7 @@ void eDVBFrontend::getTransponderData(ePtr<iDVBTransponderData> &dest, bool orig
p[cmdseq.num++].cmd = DTV_TRANSMISSION_MODE;
p[cmdseq.num++].cmd = DTV_GUARD_INTERVAL;
p[cmdseq.num++].cmd = DTV_HIERARCHY;
p[cmdseq.num++].cmd = DTV_STREAM_ID;
}
else if (type == feATSC)
{
Expand Down Expand Up @@ -1885,7 +1899,7 @@ void eDVBFrontend::setFrontend(bool recvEvents)
if (recvEvents)
m_sn->start();
feEvent(-1); // flush events
struct dtv_property p[16];
struct dtv_property p[17];
struct dtv_properties cmdseq;
cmdseq.props = p;
cmdseq.num = 0;
Expand Down Expand Up @@ -1966,6 +1980,7 @@ void eDVBFrontend::setFrontend(bool recvEvents)
{
p[cmdseq.num].cmd = DTV_ROLLOFF, p[cmdseq.num].u.data = rolloff, cmdseq.num++;
p[cmdseq.num].cmd = DTV_PILOT, p[cmdseq.num].u.data = pilot, cmdseq.num++;
p[cmdseq.num].cmd = DTV_STREAM_ID, p[cmdseq.num].u.data = parm.is_id | (parm.pls_code << 8) | (parm.pls_mode << 26), cmdseq.num++;
}
}
else if (type == iDVBFrontend::feCable)
Expand Down Expand Up @@ -2224,7 +2239,7 @@ RESULT eDVBFrontend::prepare_sat(const eDVBFrontendParametersSatellite &feparm,
res = m_sec->prepare(*this, feparm, satfrequency, 1 << m_slotid, tunetimeout);
if (!res)
{
eDebugNoSimulate("[eDVBFrontend] prepare_sat System %d Freq %d Pol %d SR %d INV %d FEC %d orbpos %d system %d modulation %d pilot %d, rolloff %d",
eDebugNoSimulate("[eDVBFrontend] prepare_sat System %d 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.system,
feparm.frequency,
feparm.polarisation,
Expand All @@ -2235,7 +2250,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);
if ((unsigned int)satfrequency < fe_info.frequency_min || (unsigned int)satfrequency > fe_info.frequency_max)
{
eDebugNoSimulate("[eDVBFrontend] %d mhz out of tuner range.. dont tune", satfrequency / 1000);
Expand Down Expand Up @@ -2592,12 +2610,23 @@ int eDVBFrontend::isCompatibleWith(ePtr<iDVBFrontendParameters> &feparm)
{
return 0;
}
bool multistream = (parm.is_id != NO_STREAM_ID_FILTER || (parm.pls_code & 0x3FFFF) != 1 ||
(parm.pls_mode & 3) != eDVBFrontendParametersSatellite::PLS_Root);
if (parm.system == eDVBFrontendParametersSatellite::System_DVB_S2 && multistream && !is_multistream())
{
return 0;
}
score = m_sec ? m_sec->canTune(parm, this, 1 << m_slotid) : 0;
if (score > 1 && parm.system == eDVBFrontendParametersSatellite::System_DVB_S && can_handle_dvbs2)
{
/* prefer to use an S tuner, try to keep S2 free for S2 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)
{
Expand Down
36 changes: 36 additions & 0 deletions lib/dvb/frontendparms.cpp
Expand Up @@ -158,6 +158,21 @@ int eDVBTransponderData::getSystem() const
return -1;
}

int eDVBTransponderData::getIsId() const
{
return -1;
}

int eDVBTransponderData::getPLSMode() const
{
return -1;
}

int eDVBTransponderData::getPLSCode() const
{
return -1;
}

int eDVBTransponderData::getBandwidth() const
{
return -1;
Expand Down Expand Up @@ -322,6 +337,27 @@ int eDVBSatelliteTransponderData::getSystem() const
}
}

int eDVBSatelliteTransponderData::getIsId() const
{
if (originalValues) return transponderParameters.is_id;

return getProperty(DTV_STREAM_ID) & 0xFF;
}

int eDVBSatelliteTransponderData::getPLSMode() const
{
if (originalValues) return transponderParameters.pls_mode;

return (getProperty(DTV_STREAM_ID) >> 26) & 0x3;
}

int eDVBSatelliteTransponderData::getPLSCode() const
{
if (originalValues) return transponderParameters.pls_code;

return (getProperty(DTV_STREAM_ID) >> 8) & 0x3FFFF;
}

DEFINE_REF(eDVBCableTransponderData);

eDVBCableTransponderData::eDVBCableTransponderData(struct dtv_property *dtvproperties, unsigned int propertycount, eDVBFrontendParametersCable &transponderparms, bool original)
Expand Down
12 changes: 11 additions & 1 deletion lib/dvb/frontendparms.h
Expand Up @@ -48,9 +48,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);

Expand Down Expand Up @@ -202,6 +206,9 @@ class eDVBTransponderData : public iDVBTransponderData
int getRolloff() const;
int getPilot() const;
int getSystem() const;
int getIsId() const;
int getPLSMode() const;
int getPLSCode() const;
int getBandwidth() const;
int getCodeRateLp() const;
int getCodeRateHp() const;
Expand Down Expand Up @@ -233,6 +240,9 @@ class eDVBSatelliteTransponderData : public eDVBTransponderData
int getRolloff() const;
int getPilot() const;
int getSystem() const;
int getIsId() const;
int getPLSMode() const;
int getPLSCode() const;
};

class eDVBCableTransponderData : public eDVBTransponderData
Expand Down
3 changes: 3 additions & 0 deletions lib/dvb/idvb.h
Expand Up @@ -490,6 +490,9 @@ class iDVBTransponderData: public iObject
virtual int getRolloff() const = 0;
virtual int getPilot() const = 0;
virtual int getSystem() const = 0;
virtual int getIsId() const = 0;
virtual int getPLSMode() const = 0;
virtual int getPLSCode() const = 0;
virtual int getBandwidth() const = 0;
virtual int getCodeRateLp() const = 0;
virtual int getCodeRateHp() const = 0;
Expand Down
2 changes: 1 addition & 1 deletion lib/python/Components/NimManager.py
Expand Up @@ -596,7 +596,7 @@ def isSupported(self):
return (self.frontend_id is not None) or self.__is_empty

def isMultistream(self):
multistream = self.frontend_id and eDVBResourceManager.getInstance().frontendIsMultistream(self.frontend_id) or False
multistream = self.frontend_id is not None and eDVBResourceManager.getInstance().frontendIsMultistream(self.frontend_id) or False
# HACK due to poor support for VTUNER_SET_FE_INFO
# When vtuner does not accept fe_info we have to fallback to detection using tuner name
# More tuner names will be added when confirmed as multistream (FE_CAN_MULTISTREAM)
Expand Down
2 changes: 2 additions & 0 deletions lib/python/Components/ServiceScan.py
Expand Up @@ -79,6 +79,8 @@ def scanStatusChanged(self):
tp.FEC_3_4 : "3/4", tp.FEC_5_6 : "5/6", tp.FEC_7_8 : "7/8",
tp.FEC_8_9 : "8/9", tp.FEC_3_5 : "3/5", tp.FEC_4_5 : "4/5",
tp.FEC_9_10 : "9/10", tp.FEC_None : "NONE" }.get(tp.fec, ""))
if tp.is_id > -1 and tp.system == tp.System_DVB_S2:
tp_text = ("%s IS %d") % (tp_text, tp.is_id)
elif tp_type == iDVBFrontend.feCable:
network = _("Cable")
tp = transponder.getDVBC()
Expand Down

0 comments on commit 4535bc8

Please sign in to comment.