Skip to content

Commit

Permalink
DVB-S2/T2 multistream support.
Browse files Browse the repository at this point in the history
  • Loading branch information
crazycat69 authored and perexg committed Feb 2, 2015
1 parent 0bc1987 commit 412df6d
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 13 deletions.
11 changes: 11 additions & 0 deletions src/input/mpegts/dvb.h
Expand Up @@ -410,6 +410,12 @@ typedef enum dvb_fe_rolloff {
DVB_ROLLOFF_35 = 350,
} dvb_fe_rolloff_t;

typedef enum dvb_fe_pls_mode {
DVB_PLS_ROOT = 0,
DVB_PLS_GOLD,
DVB_PLS_COMBO,
} dvb_fe_pls_mode_t;

typedef enum dvb_polarisation {
DVB_POLARISATION_HORIZONTAL = 0x00,
DVB_POLARISATION_VERTICAL = 0x01,
Expand Down Expand Up @@ -449,6 +455,9 @@ typedef struct dvb_mux_conf
dvb_fe_spectral_inversion_t dmc_fe_inversion;
dvb_fe_rolloff_t dmc_fe_rolloff;
dvb_fe_pilot_t dmc_fe_pilot;
int32_t dmc_fe_stream_id;
dvb_fe_pls_mode_t dmc_fe_pls_mode;
uint32_t dmc_fe_pls_code;
union {
dvb_qpsk_config_t dmc_fe_qpsk;
dvb_qam_config_t dmc_fe_qam;
Expand All @@ -473,6 +482,7 @@ const char *dvb_hier2str ( int hier );
const char *dvb_pol2str ( int pol );
const char *dvb_type2str ( int type );
const char *dvb_pilot2str ( int pilot );
const char *dvb_plsmode2str ( int pls_mode );
#define dvb_feclo2str dvb_fec2str
#define dvb_fechi2str dvb_fec2str

Expand All @@ -488,6 +498,7 @@ int dvb_str2hier ( const char *str );
int dvb_str2pol ( const char *str );
int dvb_str2type ( const char *str );
int dvb_str2pilot ( const char *str );
int dvb_str2plsmode ( const char *str );
#define dvb_str2feclo dvb_str2fec
#define dvb_str2fechi dvb_str2fec

Expand Down
21 changes: 17 additions & 4 deletions src/input/mpegts/dvb_support.c
Expand Up @@ -758,14 +758,23 @@ const static struct strtab pilottab[] = {
{"OFF", DVB_PILOT_OFF}
};
dvb_str2val(pilot);

const static struct strtab plsmodetab[] = {
{"ROOT", DVB_PLS_ROOT},
{"GOLD", DVB_PLS_GOLD},
{"COMBO", DVB_PLS_COMBO},
};
dvb_str2val(plsmode);
#undef dvb_str2val



static int
dvb_mux_conf_str_dvbt ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize )
{
return
snprintf(buf, bufsize,
"%s freq %d bw %s cons %s hier %s code_rate %s:%s guard %s trans %s",
"%s freq %d bw %s cons %s hier %s code_rate %s:%s guard %s trans %s plp_id %d",
dvb_delsys2str(dmc->dmc_fe_delsys),
dmc->dmc_fe_freq,
dvb_bw2str(dmc->u.dmc_fe_ofdm.bandwidth),
Expand All @@ -774,7 +783,8 @@ dvb_mux_conf_str_dvbt ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize )
dvb_fec2str(dmc->u.dmc_fe_ofdm.code_rate_HP),
dvb_fec2str(dmc->u.dmc_fe_ofdm.code_rate_LP),
dvb_guard2str(dmc->u.dmc_fe_ofdm.guard_interval),
dvb_mode2str(dmc->u.dmc_fe_ofdm.transmission_mode));
dvb_mode2str(dmc->u.dmc_fe_ofdm.transmission_mode),
dmc->dmc_fe_stream_id);
}

static int
Expand All @@ -797,7 +807,7 @@ dvb_mux_conf_str_dvbs ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize )
const char dir = dmc->u.dmc_fe_qpsk.orbital_dir;
return
snprintf(buf, bufsize,
"%s pos %d.%d%c freq %d %c sym %d fec %s mod %s roff %s",
"%s pos %d.%d%c freq %d %c sym %d fec %s mod %s roff %s is_id %d pls_mode %s pls_code %d",
dvb_delsys2str(dmc->dmc_fe_delsys),
dmc->u.dmc_fe_qpsk.orbital_pos / 10,
dmc->u.dmc_fe_qpsk.orbital_pos % 10,
Expand All @@ -807,7 +817,10 @@ dvb_mux_conf_str_dvbs ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize )
dmc->u.dmc_fe_qpsk.symbol_rate,
dvb_fec2str(dmc->u.dmc_fe_qpsk.fec_inner),
dvb_qam2str(dmc->dmc_fe_modulation),
dvb_rolloff2str(dmc->dmc_fe_rolloff));
dvb_rolloff2str(dmc->dmc_fe_rolloff),
dmc->dmc_fe_stream_id,
dvb_plsmode2str(dmc->dmc_fe_pls_mode),
dmc->dmc_fe_pls_code);
}

static int
Expand Down
16 changes: 15 additions & 1 deletion src/input/mpegts/linuxdvb/linuxdvb_frontend.c
Expand Up @@ -1297,6 +1297,13 @@ linuxdvb_frontend_tune0
S2CMD(DTV_GUARD_INTERVAL, p.u.ofdm.guard_interval);
S2CMD(DTV_HIERARCHY, p.u.ofdm.hierarchy_information);
#endif
if (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBT2) {
#if DVB_VER_ATLEAST(5,9)
S2CMD(DTV_STREAM_ID, dmc->dmc_fe_stream_id);
#elif DVB_VER_ATLEAST(5,3)
S2CMD(DTV_DVBT2_PLP_ID, dmc->dmc_fe_stream_id);
#endif
}

/* DVB-C */
} else if (lfe->lfe_type == DVB_TYPE_C) {
Expand All @@ -1308,12 +1315,19 @@ linuxdvb_frontend_tune0
} else if (lfe->lfe_type == DVB_TYPE_S) {
S2CMD(DTV_SYMBOL_RATE, p.u.qpsk.symbol_rate);
S2CMD(DTV_INNER_FEC, p.u.qpsk.fec_inner);
S2CMD(DTV_PILOT, TR(pilot, pilot_tbl, PILOT_AUTO));
S2CMD(DTV_MODULATION, TR(modulation, mod_tbl, QPSK));
if (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBS) {
S2CMD(DTV_ROLLOFF, ROLLOFF_35);
} else {
S2CMD(DTV_PILOT, TR(pilot, pilot_tbl, PILOT_AUTO));
S2CMD(DTV_ROLLOFF, TR(rolloff, rolloff_tbl, ROLLOFF_AUTO));
r = dmc->dmc_fe_stream_id != -1 ? (dmc->dmc_fe_stream_id & 0xFF) |
((dmc->dmc_fe_pls_code & 0x3FFFF)<<8) | ((dmc->dmc_fe_pls_mode & 0x3)<<26) : r;
#if DVB_VER_ATLEAST(5,9)
S2CMD(DTV_STREAM_ID, r );
#elif DVB_VER_ATLEAST(5,3)
S2CMD(DTV_DVBT2_PLP_ID, r);
#endif
}

/* ATSC */
Expand Down
57 changes: 57 additions & 0 deletions src/input/mpegts/mpegts_mux_dvb.c
Expand Up @@ -218,6 +218,13 @@ const idclass_t dvb_mux_dvbt_class =
{
MUX_PROP_STR("fec_lo", "FEC Low", dvbt, feclo, "AUTO"),
},
{
.type = PT_INT,
.id = "plp_id",
.name = "PLP ID",
.off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id),
.def.i = 0,
},
{}
}
};
Expand Down Expand Up @@ -401,6 +408,33 @@ dvb_mux_dvbs_class_pilot_list ( void *o )
return list;
}

static const void *
dvb_mux_dvbs_class_pls_mode_get ( void *o )
{
static const char *s;
dvb_mux_t *lm = o;
s = dvb_plsmode2str(lm->lm_tuning.dmc_fe_pls_mode);
return &s;
}

static int
dvb_mux_dvbs_class_pls_mode_set ( void *o, const void *s )
{
dvb_mux_t *lm = o;
lm->lm_tuning.dmc_fe_pls_mode = dvb_str2plsmode(s);
return 1;
}

static htsmsg_t *
dvb_mux_dvbs_class_pls_mode_list ( void *o )
{
htsmsg_t *list = htsmsg_create_list();
htsmsg_add_str(list, NULL, dvb_plsmode2str(DVB_PLS_ROOT));
htsmsg_add_str(list, NULL, dvb_plsmode2str(DVB_PLS_GOLD));
htsmsg_add_str(list, NULL, dvb_plsmode2str(DVB_PLS_COMBO));
return list;
}

#define dvb_mux_dvbs_class_delsys_get dvb_mux_class_delsys_get
#define dvb_mux_dvbs_class_delsys_set dvb_mux_class_delsys_set

Expand Down Expand Up @@ -505,6 +539,29 @@ const idclass_t dvb_mux_dvbs_class =
.get = dvb_mux_dvbs_class_pilot_get,
.list = dvb_mux_dvbs_class_pilot_list,
},
{
.type = PT_INT,
.id = "stream_id",
.name = "ISI",
.off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id),
.def.i = -1,
},
{
.type = PT_STR,
.id = "pls_mode",
.name = "PLS MODE",
.set = dvb_mux_dvbs_class_pls_mode_set,
.get = dvb_mux_dvbs_class_pls_mode_get,
.list = dvb_mux_dvbs_class_pls_mode_list,
.def.s = "ROOT",
},
{
.type = PT_U32,
.id = "pls_code",
.name = "PLS CODE",
.off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_pls_code),
.def.u32 = 1,
},
{
.type = PT_STR,
.id = "orbital",
Expand Down
8 changes: 8 additions & 0 deletions src/input/mpegts/mpegts_network_dvb.c
Expand Up @@ -304,6 +304,7 @@ dvb_network_find_mux
/* Reject if not same symbol rate (some tolerance due to changes and diff in NIT) */
if (dvb_network_check_symbol_rate(lm, dmc, deltar)) continue;


/* DVB-S extra checks */
if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_S) {

Expand All @@ -314,6 +315,9 @@ dvb_network_find_mux
if (dvb_network_check_orbital_pos(lm, dmc)) continue;
}

/* Same PLP/ISI */
if (lm->lm_tuning.dmc_fe_stream_id != dmc->dmc_fe_stream_id) continue;

mm_alt = mm;

/* Reject if not same ID */
Expand Down Expand Up @@ -453,6 +457,7 @@ dvb_network_create_mux
save |= COMPAREN(dmc_fe_pilot);
switch (dmc->dmc_fe_type) {
case DVB_TYPE_T:
save |= COMPARE(dmc_fe_stream_id);
save |= COMPAREN(u.dmc_fe_ofdm.bandwidth);
save |= COMPAREN(u.dmc_fe_ofdm.code_rate_HP);
save |= COMPAREN(u.dmc_fe_ofdm.code_rate_LP);
Expand All @@ -463,6 +468,9 @@ dvb_network_create_mux
case DVB_TYPE_S:
save |= COMPARE(u.dmc_fe_qpsk.polarisation);
save |= COMPARE(u.dmc_fe_qpsk.symbol_rate);
save |= COMPARE(dmc_fe_stream_id);
save |= COMPAREN(dmc_fe_pls_mode);
save |= COMPAREN(dmc_fe_pls_code);
save |= COMPAREN(u.dmc_fe_qpsk.fec_inner);
break;
case DVB_TYPE_C:
Expand Down
32 changes: 24 additions & 8 deletions src/input/mpegts/scanfile.c
Expand Up @@ -131,18 +131,18 @@ scanfile_load_dvbt ( dvb_mux_conf_t *mux, const char *line )
int r;

if (*line == '2') {
unsigned int plp_id, system_id;
r = sscanf(line+1, "%u %s", &plp_id, bw);
if (r == 2 && plp_id < 1000 && strstr(bw, "MHz") == 0) {
unsigned int system_id;
r = sscanf(line+1, "%u %s", &mux->dmc_fe_stream_id, bw);
if (r == 2 && mux->dmc_fe_stream_id < 1000 && strstr(bw, "MHz") == 0) {
r = sscanf(line+1, "%u %u %u %10s %10s %10s %10s %10s %10s %10s",
&plp_id, &system_id, &mux->dmc_fe_freq, bw, fec, fec2, qam,
&mux->dmc_fe_stream_id, &system_id, &mux->dmc_fe_freq, bw, fec, fec2, qam,
mode, guard, hier);
if(r != 10) return 1;
} else {
r = sscanf(line+1, "%u %10s %10s %10s %10s %10s %10s %10s %u",
&mux->dmc_fe_freq, bw, fec, fec2, qam,
mode, guard, hier, &plp_id);
if(r == 8) plp_id = 0; /* auto? */ else
mode, guard, hier, &mux->dmc_fe_stream_id);
if(r == 8) mux->dmc_fe_stream_id = -1; else
if(r != 9) return 1;
}
mux->dmc_fe_delsys = DVB_SYS_DVBT2;
Expand Down Expand Up @@ -176,9 +176,9 @@ scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line )
line++;
}

r = sscanf(line, "%u %s %u %s %s %s",
r = sscanf(line, "%u %s %u %s %s %s %d %d %d",
&mux->dmc_fe_freq, pol, &mux->u.dmc_fe_qpsk.symbol_rate,
fec, rolloff, qam);
fec, rolloff, qam, &mux->dmc_fe_stream_id, &mux->dmc_fe_pls_code, (int*)&mux->dmc_fe_pls_mode);
if (r < (4+v2)) return 1;

mux->dmc_fe_type = DVB_TYPE_S;
Expand All @@ -188,6 +188,9 @@ scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line )
mux->dmc_fe_delsys = DVB_SYS_DVBS2;
if ((mux->dmc_fe_rolloff = dvb_str2rolloff(rolloff)) == -1) return 1;
if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1;
if (r < (4+v2+1)) mux->dmc_fe_stream_id = -1;
if (r < (4+v2+2)) mux->dmc_fe_pls_code = 1;
if (r < (4+v2+3)) mux->dmc_fe_pls_mode = 0;
} else {
mux->dmc_fe_delsys = DVB_SYS_DVBS;
mux->dmc_fe_rolloff = DVB_ROLLOFF_35;
Expand Down Expand Up @@ -454,6 +457,8 @@ scanfile_load_dvbv5 ( scanfile_network_t *net, char *line, fb_file *fp )
if ((x = htsmsg_get_str(l, "INVERSION")))
if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1)
mux_fail(r, "wrong inversion '%s'", x);
if (htsmsg_get_s32(l, "STREAM_ID", &mux->dmc_fe_stream_id))
mux->dmc_fe_stream_id = -1;

} else if (mux->dmc_fe_delsys == DVB_SYS_DVBS ||
mux->dmc_fe_delsys == DVB_SYS_DVBS2) {
Expand Down Expand Up @@ -481,6 +486,17 @@ scanfile_load_dvbv5 ( scanfile_network_t *net, char *line, fb_file *fp )
if ((x = htsmsg_get_str(l, "PILOT")))
if ((mux->dmc_fe_pilot = dvb_str2rolloff(x)) == -1)
mux_fail(r, "wrong pilot '%s'", x);
if (htsmsg_get_s32(l, "STREAM_ID", &r)) {
mux->dmc_fe_stream_id = -1;
mux->dmc_fe_pls_mode = 0;
mux->dmc_fe_pls_code = 1;
}
else {
mux->dmc_fe_stream_id = r&0xff;
mux->dmc_fe_pls_mode = (r>>26)&0x3;
mux->dmc_fe_pls_code = (r>>8)&0x3FFFF;
}

if ((x = htsmsg_get_str(l, "POLARIZATION"))) {
char pol[2];
pol[0] = x[0]; pol[1] = '\0';
Expand Down

0 comments on commit 412df6d

Please sign in to comment.