diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index 2b5f4a80f7..bdd5509eb5 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -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, @@ -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; @@ -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 @@ -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 diff --git a/src/input/mpegts/dvb_support.c b/src/input/mpegts/dvb_support.c index 3a6ad44351..912a90252f 100644 --- a/src/input/mpegts/dvb_support.c +++ b/src/input/mpegts/dvb_support.c @@ -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), @@ -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 @@ -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, @@ -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 diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 84a83ec094..f56bad69f9 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -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) { @@ -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 */ diff --git a/src/input/mpegts/mpegts_mux_dvb.c b/src/input/mpegts/mpegts_mux_dvb.c index 7d81f6e91f..9decd58b21 100644 --- a/src/input/mpegts/mpegts_mux_dvb.c +++ b/src/input/mpegts/mpegts_mux_dvb.c @@ -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, + }, {} } }; @@ -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 @@ -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", diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index 601b1e1230..6404dc3b12 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -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) { @@ -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 */ @@ -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); @@ -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: diff --git a/src/input/mpegts/scanfile.c b/src/input/mpegts/scanfile.c index cd6c2c96b0..64df1d0395 100644 --- a/src/input/mpegts/scanfile.c +++ b/src/input/mpegts/scanfile.c @@ -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; @@ -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; @@ -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; @@ -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) { @@ -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';