Do not rely on linux kernel's headers - preparing for network tuners (SAT-IP)

This is a complete migration to use the own mux configuration scheme without
the system limitations to allow write backends for the network tuners like
SAT-IP servers.
This commit is contained in:
Jaroslav Kysela 2014-03-27 11:27:17 +01:00
parent 6482d33ba9
commit f228fe45c3
14 changed files with 1021 additions and 737 deletions

View file

@ -197,48 +197,224 @@ void psi_tables_atsc_c ( struct mpegts_mux *mm );
*/
#if ENABLE_DVBAPI
#include <linux/dvb/version.h>
#include <linux/dvb/frontend.h>
typedef enum dvb_fe_type {
DVB_TYPE_NONE = 0,
DVB_TYPE_T = 1, /* terrestrial */
DVB_TYPE_C, /* cable */
DVB_TYPE_S, /* satellite */
DVB_TYPE_ATSC, /* terrestrial - north america */
DVB_TYPE_LAST = DVB_TYPE_ATSC
} dvb_fe_type_t;
#define DVB_VER_INT(maj,min) (((maj) << 16) + (min))
typedef enum dvb_fe_delivery_system {
DVB_SYS_NONE = 0,
DVB_SYS_DVBC_ANNEX_A = 100,
DVB_SYS_DVBC_ANNEX_B,
DVB_SYS_DVBC_ANNEX_C,
DVB_SYS_DVBT = 200,
DVB_SYS_DVBT2,
DVB_SYS_DVBS = 300,
DVB_SYS_DVBS2,
DVB_SYS_DVBH = 400,
DVB_SYS_DSS = 500,
DVB_SYS_ISDBT = 600,
DVB_SYS_ISDBS,
DVB_SYS_ISDBC,
DVB_SYS_ATSC = 700,
DVB_SYS_ATSCMH,
DVB_SYS_DTMB = 800,
DVB_SYS_CMMB = 900,
DVB_SYS_DAB = 1000,
DVB_SYS_TURBO = 1100,
} dvb_fe_delivery_system_t;
#define DVB_VER_ATLEAST(maj, min) \
(DVB_VER_INT(DVB_API_VERSION, DVB_API_VERSION_MINOR) >= DVB_VER_INT(maj, min))
typedef enum dvb_fe_spectral_inversion {
DVB_INVERSION_UNDEFINED,
DVB_INVERSION_AUTO,
DVB_INVERSION_OFF,
DVB_INVERSION_ON,
} dvb_fe_spectral_inversion_t;
typedef struct dvb_frontend_parameters dvb_frontend_parameters_t;
typedef enum dvb_fe_code_rate {
DVB_FEC_NONE = 0,
DVB_FEC_AUTO,
DVB_FEC_1_2 = 102,
DVB_FEC_1_3 = 103,
DVB_FEC_1_5 = 105,
DVB_FEC_2_3 = 203,
DVB_FEC_2_5 = 205,
DVB_FEC_2_9 = 209,
DVB_FEC_3_4 = 304,
DVB_FEC_3_5 = 305,
DVB_FEC_4_5 = 405,
DVB_FEC_4_15 = 415,
DVB_FEC_5_6 = 506,
DVB_FEC_5_9 = 509,
DVB_FEC_6_7 = 607,
DVB_FEC_7_8 = 708,
DVB_FEC_7_9 = 709,
DVB_FEC_7_15 = 715,
DVB_FEC_8_9 = 809,
DVB_FEC_8_15 = 815,
DVB_FEC_9_10 = 910,
DVB_FEC_9_20 = 920,
DVB_FEC_11_15 = 1115,
DVB_FEC_11_20 = 1120,
DVB_FEC_11_45 = 1145,
DVB_FEC_13_18 = 1318,
DVB_FEC_13_45 = 1345,
DVB_FEC_14_45 = 1445,
DVB_FEC_23_36 = 2336,
DVB_FEC_25_36 = 2536,
DVB_FEC_26_45 = 2645,
DVB_FEC_28_45 = 2845,
DVB_FEC_29_45 = 2945,
DVB_FEC_31_45 = 3145,
DVB_FEC_32_45 = 3245,
DVB_FEC_77_90 = 7790,
} dvb_fe_code_rate_t;
typedef enum polarisation {
POLARISATION_HORIZONTAL = 0x00,
POLARISATION_VERTICAL = 0x01,
POLARISATION_CIRCULAR_LEFT = 0x02,
POLARISATION_CIRCULAR_RIGHT = 0x03
} polarisation_t;
typedef enum dvb_fe_modulation {
DVB_MOD_NONE = 0,
DVB_MOD_AUTO,
DVB_MOD_QPSK = 1001,
DVB_MOD_QAM_4_NR = 2004,
DVB_MOD_QAM_AUTO = 3000,
DVB_MOD_QAM_16 = 3016,
DVB_MOD_QAM_32 = 3032,
DVB_MOD_QAM_64 = 3064,
DVB_MOD_QAM_128 = 3128,
DVB_MOD_QAM_256 = 3256,
DVB_MOD_VSB_8 = 4008,
DVB_MOD_VSB_16 = 4016,
DVB_MOD_PSK_8 = 5008,
DVB_MOD_DQPSK = 6001,
DVB_MOD_BPSK = 7001,
DVB_MOD_BPSK_S = 8001,
DVB_MOD_APSK_16 = 9016,
DVB_MOD_APSK_32 = 9032,
DVB_MOD_APSK_64 = 9064,
DVB_MOD_APSK_128 = 9128,
DVB_MOD_APSK_256 = 9256,
DVB_MOD_APSK_8_L = 10008,
DVB_MOD_APSK_16_L = 10016,
DVB_MOD_APSK_32_L = 10032,
DVB_MOD_APSK_64_L = 10064,
DVB_MOD_APSK_128_L = 10128,
DVB_MOD_APSK_256_L = 10256,
} dvb_fe_modulation_t;
typedef enum dvb_fe_transmit_mode {
DVB_TRANSMISSION_MODE_NONE = 0,
DVB_TRANSMISSION_MODE_AUTO,
DVB_TRANSMISSION_MODE_1K = 100,
DVB_TRANSMISSION_MODE_2K,
DVB_TRANSMISSION_MODE_4K,
DVB_TRANSMISSION_MODE_8K,
DVB_TRANSMISSION_MODE_16K,
DVB_TRANSMISSION_MODE_32K,
DVB_TRANSMISSION_MODE_C1 = 10001,
DVB_TRANSMISSION_MODE_C3780 = 13780,
} dvb_fe_transmit_mode_t;
typedef enum dvb_fe_bandwidth {
DVB_BANDWIDTH_NONE = 0,
DVB_BANDWIDTH_AUTO,
DVB_BANDWIDTH_1_712_MHZ = 1712,
DVB_BANDWIDTH_5_MHZ = 5000,
DVB_BANDWIDTH_6_MHZ = 6000,
DVB_BANDWIDTH_7_MHZ = 7000,
DVB_BANDWIDTH_8_MHZ = 8000,
DVB_BANDWIDTH_10_MHZ = 10000,
} dvb_fe_bandwidth_t;
typedef enum dvb_fe_guard_interval {
DVB_GUARD_INTERVAL_NONE = 0,
DVB_GUARD_INTERVAL_AUTO,
DVB_GUARD_INTERVAL_1_4 = 1004,
DVB_GUARD_INTERVAL_1_8 = 1008,
DVB_GUARD_INTERVAL_1_16 = 1016,
DVB_GUARD_INTERVAL_1_32 = 1032,
DVB_GUARD_INTERVAL_1_128 = 1128,
DVB_GUARD_INTERVAL_19_128 = 19128,
DVB_GUARD_INTERVAL_19_256 = 19256,
DVB_GUARD_INTERVAL_PN420 = 90420,
DVB_GUARD_INTERVAL_PN595 = 90595,
DVB_GUARD_INTERVAL_PN945 = 90945,
} dvb_fe_guard_interval_t;
typedef enum dvb_fe_hierarchy {
DVB_HIERARCHY_NONE = 0,
DVB_HIERARCHY_AUTO,
DVB_HIERARCHY_1 = 1001,
DVB_HIERARCHY_2 = 1002,
DVB_HIERARCHY_4 = 1004,
} dvb_fe_hierarchy_t;
typedef enum dvb_fe_pilot {
DVB_PILOT_NONE = 0,
DVB_PILOT_AUTO,
DVB_PILOT_ON,
DVB_PILOT_OFF,
} dvb_fe_pilot_t;
typedef enum dvb_fe_rolloff {
DVB_ROLLOFF_NONE = 0,
DVB_ROLLOFF_AUTO,
DVB_ROLLOFF_20 = 200,
DVB_ROLLOFF_25 = 250,
DVB_ROLLOFF_35 = 350,
} dvb_fe_rolloff_t;
typedef enum dvb_polarisation {
DVB_POLARISATION_HORIZONTAL = 0x00,
DVB_POLARISATION_VERTICAL = 0x01,
DVB_POLARISATION_CIRCULAR_LEFT = 0x02,
DVB_POLARISATION_CIRCULAR_RIGHT = 0x03
} dvb_polarisation_t;
typedef struct dvb_qpsk_config {
dvb_polarisation_t polarisation;
int orbital_pos;
char orbital_dir;
uint32_t symbol_rate;
dvb_fe_code_rate_t fec_inner;
} dvb_qpsk_config_t;
typedef struct dvb_qam_config {
uint32_t symbol_rate;
dvb_fe_code_rate_t fec_inner;
} dvb_qam_config_t;
typedef struct dvb_ofdm_config {
dvb_fe_bandwidth_t bandwidth;
dvb_fe_code_rate_t code_rate_HP;
dvb_fe_code_rate_t code_rate_LP;
dvb_fe_transmit_mode_t transmission_mode;
dvb_fe_guard_interval_t guard_interval;
dvb_fe_hierarchy_t hierarchy_information;
} dvb_ofdm_config_t;
typedef struct dvb_mux_conf
{
dvb_frontend_parameters_t dmc_fe_params;
// Additional DVB-S fields
polarisation_t dmc_fe_polarisation;
int dmc_fe_orbital_pos;
char dmc_fe_orbital_dir;
#if DVB_VER_ATLEAST(5,0)
fe_modulation_t dmc_fe_modulation;
fe_delivery_system_t dmc_fe_delsys;
fe_rolloff_t dmc_fe_rolloff;
fe_pilot_t dmc_fe_pilot;
#endif
dvb_fe_type_t dmc_fe_type;
dvb_fe_delivery_system_t dmc_fe_delsys;
dvb_fe_modulation_t dmc_fe_modulation;
uint32_t dmc_fe_freq;
dvb_fe_spectral_inversion_t dmc_fe_inversion;
dvb_fe_rolloff_t dmc_fe_rolloff;
dvb_fe_pilot_t dmc_fe_pilot;
union {
dvb_qpsk_config_t dmc_fe_qpsk;
dvb_qam_config_t dmc_fe_qam;
dvb_ofdm_config_t dmc_fe_ofdm;
} u;
// For scan file configurations
LIST_ENTRY(dvb_mux_conf) dmc_link;
LIST_ENTRY(dvb_mux_conf) dmc_link;
} dvb_mux_conf_t;
const char *dvb_mux_conf_load
( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m );
void dvb_mux_conf_save
( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m );
/* conversion routines */
const char *dvb_rolloff2str ( int rolloff );
const char *dvb_delsys2str ( int delsys );
@ -268,11 +444,12 @@ int dvb_str2pilot ( const char *str );
#define dvb_str2feclo dvb_str2fec
#define dvb_str2fechi dvb_str2fec
int dvb_bandwidth ( enum fe_bandwidth bw );
static inline int dvb_bandwidth( dvb_fe_bandwidth_t bw )
{
return bw < 1000 ? 0 : bw * 1000;
}
#if DVB_VER_ATLEAST(5,10)
int dvb_delsys2type ( enum fe_delivery_system ds );
#endif
int dvb_delsys2type ( enum dvb_fe_delivery_system ds );
#endif /* ENABLE_DVBAPI */

View file

@ -78,22 +78,11 @@ dvb_servicetype_lookup ( int t )
/**
* Tables for delivery descriptor parsing
*/
static const fe_code_rate_t fec_tab [16] = {
FEC_AUTO, FEC_1_2, FEC_2_3, FEC_3_4,
FEC_5_6, FEC_7_8, FEC_8_9,
#if DVB_VER_ATLEAST(5,0)
FEC_3_5,
#else
FEC_NONE,
#endif
FEC_4_5,
#if DVB_VER_ATLEAST(5,0)
FEC_9_10,
#else
FEC_NONE,
#endif
FEC_NONE, FEC_NONE,
FEC_NONE, FEC_NONE, FEC_NONE, FEC_NONE
static const dvb_fe_code_rate_t fec_tab [16] = {
DVB_FEC_AUTO, DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4,
DVB_FEC_5_6, DVB_FEC_7_8, DVB_FEC_8_9, DVB_FEC_3_5,
DVB_FEC_4_5, DVB_FEC_9_10, DVB_FEC_NONE, DVB_FEC_NONE,
DVB_FEC_NONE, DVB_FEC_NONE, DVB_FEC_NONE, DVB_FEC_NONE
};
/*
@ -127,58 +116,43 @@ dvb_desc_sat_del
}
memset(&dmc, 0, sizeof(dmc));
#if DVB_VER_ATLEAST(5,0)
dmc.dmc_fe_pilot = PILOT_AUTO;
#endif
dmc.dmc_fe_params.inversion = INVERSION_AUTO;
dmc.dmc_fe_params.frequency = frequency;
dmc.dmc_fe_orbital_pos = bcdtoint(ptr[4]) * 100 + bcdtoint(ptr[5]);
dmc.dmc_fe_orbital_dir = (ptr[6] & 0x80) ? 'E' : 'W';
dmc.dmc_fe_polarisation = (ptr[6] >> 5) & 0x03;
dmc.dmc_fe_pilot = DVB_PILOT_AUTO;
dmc.dmc_fe_inversion = DVB_INVERSION_AUTO;
dmc.dmc_fe_freq = frequency;
dmc.u.dmc_fe_qpsk.orbital_pos = bcdtoint(ptr[4]) * 100 + bcdtoint(ptr[5]);
dmc.u.dmc_fe_qpsk.orbital_dir = (ptr[6] & 0x80) ? 'E' : 'W';
dmc.u.dmc_fe_qpsk.polarisation = (ptr[6] >> 5) & 0x03;
dmc.dmc_fe_params.u.qpsk.symbol_rate = symrate * 100;
dmc.dmc_fe_params.u.qpsk.fec_inner = fec_tab[ptr[10] & 0x0f];
dmc.u.dmc_fe_qpsk.symbol_rate = symrate * 100;
dmc.u.dmc_fe_qpsk.fec_inner = fec_tab[ptr[10] & 0x0f];
#if DVB_VER_ATLEAST(5,0)
static int mtab[4] = {
0, QPSK,
#if DVB_VER_ATLEAST(5,3)
PSK_8,
#else
0,
#endif
QAM_16
DVB_MOD_NONE, DVB_MOD_QPSK, DVB_MOD_PSK_8, DVB_MOD_QAM_16
};
static int rtab[4] = {
ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_AUTO
DVB_ROLLOFF_35, DVB_ROLLOFF_25, DVB_ROLLOFF_20, DVB_ROLLOFF_AUTO
};
dmc.dmc_fe_delsys = (ptr[6] & 0x4) ? SYS_DVBS2 : SYS_DVBS;
dmc.dmc_fe_delsys = (ptr[6] & 0x4) ? DVB_SYS_DVBS2 : DVB_SYS_DVBS;
dmc.dmc_fe_modulation = mtab[ptr[6] & 0x3];
dmc.dmc_fe_rolloff = rtab[(ptr[6] >> 3) & 0x3];
if (dmc.dmc_fe_delsys == SYS_DVBS &&
dmc.dmc_fe_rolloff != ROLLOFF_35) {
if (dmc.dmc_fe_delsys == DVB_SYS_DVBS &&
dmc.dmc_fe_rolloff != DVB_ROLLOFF_35) {
tvhwarn("nit", "dvb-s rolloff error");
return NULL;
}
#endif
/* Debug */
const char *pol = dvb_pol2str(dmc.dmc_fe_polarisation);
tvhdebug("nit", " dvb-s%c pos %d%c freq %d %c sym %d fec %s"
#if DVB_VER_ATLEAST(5,0)
" mod %s roff %s"
#endif
,
const char *pol = dvb_pol2str(dmc.u.dmc_fe_qpsk.polarisation);
tvhdebug("nit",
" dvb-s%c pos %d%c freq %d %c sym %d fec %s mod %s roff %s",
(ptr[6] & 0x4) ? '2' : ' ',
dmc.dmc_fe_orbital_pos, dmc.dmc_fe_orbital_dir,
dmc.dmc_fe_params.frequency,
dmc.u.dmc_fe_qpsk.orbital_pos, dmc.u.dmc_fe_qpsk.orbital_dir,
dmc.dmc_fe_freq,
pol ? pol[0] : 'X',
symrate,
dvb_fec2str(dmc.dmc_fe_params.u.qpsk.fec_inner)
#if DVB_VER_ATLEAST(5,0)
, dvb_qam2str(dmc.dmc_fe_modulation),
dvb_fec2str(dmc.u.dmc_fe_qpsk.fec_inner),
dvb_qam2str(dmc.dmc_fe_modulation),
dvb_rolloff2str(dmc.dmc_fe_rolloff)
#endif
);
/* Create */
@ -197,7 +171,8 @@ dvb_desc_cable_del
dvb_mux_conf_t dmc;
static const fe_modulation_t qtab [6] = {
QAM_AUTO, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256
DVB_MOD_QAM_AUTO, DVB_MOD_QAM_16, DVB_MOD_QAM_32, DVB_MOD_QAM_64,
DVB_MOD_QAM_128, DVB_MOD_QAM_256
};
/* Not enough data */
@ -220,25 +195,23 @@ dvb_desc_cable_del
}
memset(&dmc, 0, sizeof(dmc));
#if DVB_VER_ATLEAST(5,0)
dmc.dmc_fe_delsys = SYS_DVBC_ANNEX_AC;
#endif
dmc.dmc_fe_params.inversion = INVERSION_AUTO;
dmc.dmc_fe_params.frequency = frequency * 100;
dmc.dmc_fe_delsys = DVB_SYS_DVBC_ANNEX_A;
dmc.dmc_fe_inversion = DVB_INVERSION_AUTO;
dmc.dmc_fe_freq = frequency * 100;
dmc.dmc_fe_params.u.qam.symbol_rate = symrate * 100;
dmc.u.dmc_fe_qam.symbol_rate = symrate * 100;
if((ptr[6] & 0x0f) >= sizeof(qtab))
dmc.dmc_fe_params.u.qam.modulation = QAM_AUTO;
dmc.dmc_fe_modulation = QAM_AUTO;
else
dmc.dmc_fe_params.u.qam.modulation = qtab[ptr[6] & 0x0f];
dmc.dmc_fe_params.u.qam.fec_inner = fec_tab[ptr[10] & 0x07];
dmc.dmc_fe_modulation = qtab[ptr[6] & 0x0f];
dmc.u.dmc_fe_qam.fec_inner = fec_tab[ptr[10] & 0x07];
/* Debug */
tvhdebug("nit", " dvb-c freq %d sym %d mod %s fec %s",
frequency,
symrate,
dvb_qam2str(dmc.dmc_fe_params.u.qam.modulation),
dvb_fec2str(dmc.dmc_fe_params.u.qam.fec_inner));
dvb_qam2str(dmc.dmc_fe_modulation),
dvb_fec2str(dmc.u.dmc_fe_qam.fec_inner));
/* Create */
return mm->mm_network->mn_create_mux(mm, onid, tsid, &dmc);
@ -253,28 +226,27 @@ dvb_desc_terr_del
const uint8_t *ptr, int len )
{
static const fe_bandwidth_t btab [8] = {
BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_6_MHZ, BANDWIDTH_AUTO,
BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO, BANDWIDTH_AUTO
};
DVB_BANDWIDTH_8_MHZ, DVB_BANDWIDTH_7_MHZ,
DVB_BANDWIDTH_6_MHZ, DVB_BANDWIDTH_AUTO,
DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_AUTO,
DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_AUTO
};
static const fe_modulation_t ctab [4] = {
QPSK, QAM_16, QAM_64, QAM_AUTO
DVB_MOD_QPSK, DVB_MOD_QAM_16, DVB_MOD_QAM_64, DVB_MOD_QAM_AUTO
};
static const fe_guard_interval_t gtab [4] = {
GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4
DVB_GUARD_INTERVAL_1_32, DVB_GUARD_INTERVAL_1_16,
DVB_GUARD_INTERVAL_1_8, DVB_GUARD_INTERVAL_1_4
};
static const fe_transmit_mode_t ttab [4] = {
TRANSMISSION_MODE_2K,
TRANSMISSION_MODE_8K,
#if DVB_VER_ATLEAST(5,1)
TRANSMISSION_MODE_4K,
#else
TRANSMISSION_MODE_AUTO,
#endif
TRANSMISSION_MODE_AUTO
};
DVB_TRANSMISSION_MODE_2K,
DVB_TRANSMISSION_MODE_8K,
DVB_TRANSMISSION_MODE_4K,
DVB_TRANSMISSION_MODE_AUTO
};
static const fe_hierarchy_t htab [8] = {
HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4,
HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, HIERARCHY_4
DVB_HIERARCHY_NONE, DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4,
DVB_HIERARCHY_NONE, DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4
};
int frequency;
@ -291,30 +263,28 @@ dvb_desc_terr_del
}
memset(&dmc, 0, sizeof(dmc));
#if DVB_VER_ATLEAST(5,0)
dmc.dmc_fe_delsys = SYS_DVBT;
#endif
dmc.dmc_fe_params.inversion = INVERSION_AUTO;
dmc.dmc_fe_params.frequency = frequency * 10;
dmc.dmc_fe_delsys = DVB_SYS_DVBT;
dmc.dmc_fe_inversion = DVB_INVERSION_AUTO;
dmc.dmc_fe_freq = frequency * 10;
dmc.dmc_fe_params.u.ofdm.bandwidth = btab[(ptr[4] >> 5) & 0x7];
dmc.dmc_fe_params.u.ofdm.constellation = ctab[(ptr[5] >> 6) & 0x3];
dmc.dmc_fe_params.u.ofdm.hierarchy_information = htab[(ptr[5] >> 3) & 0x3];
dmc.dmc_fe_params.u.ofdm.code_rate_HP = fec_tab[(ptr[5] + 1) & 0x7];
dmc.dmc_fe_params.u.ofdm.code_rate_LP = fec_tab[((ptr[6] + 1) >> 5) & 0x7];
dmc.dmc_fe_params.u.ofdm.guard_interval = gtab[(ptr[6] >> 3) & 0x3];
dmc.dmc_fe_params.u.ofdm.transmission_mode = ttab[(ptr[6] >> 1) & 0x3];
dmc.u.dmc_fe_ofdm.bandwidth = btab[(ptr[4] >> 5) & 0x7];
dmc.dmc_fe_modulation = ctab[(ptr[5] >> 6) & 0x3];
dmc.u.dmc_fe_ofdm.hierarchy_information = htab[(ptr[5] >> 3) & 0x3];
dmc.u.dmc_fe_ofdm.code_rate_HP = fec_tab[(ptr[5] + 1) & 0x7];
dmc.u.dmc_fe_ofdm.code_rate_LP = fec_tab[((ptr[6] + 1) >> 5) & 0x7];
dmc.u.dmc_fe_ofdm.guard_interval = gtab[(ptr[6] >> 3) & 0x3];
dmc.u.dmc_fe_ofdm.transmission_mode = ttab[(ptr[6] >> 1) & 0x3];
/* Debug */
tvhdebug("nit", " dvb-t freq %d bw %s cons %s hier %s code_rate %s:%s guard %s trans %s",
frequency,
dvb_bw2str(dmc.dmc_fe_params.u.ofdm.bandwidth),
dvb_qam2str(dmc.dmc_fe_params.u.ofdm.constellation),
dvb_hier2str(dmc.dmc_fe_params.u.ofdm.hierarchy_information),
dvb_fec2str(dmc.dmc_fe_params.u.ofdm.code_rate_HP),
dvb_fec2str(dmc.dmc_fe_params.u.ofdm.code_rate_LP),
dvb_guard2str(dmc.dmc_fe_params.u.ofdm.guard_interval),
dvb_mode2str(dmc.dmc_fe_params.u.ofdm.transmission_mode));
dvb_bw2str(dmc.u.dmc_fe_ofdm.bandwidth),
dvb_qam2str(dmc.dmc_fe_modulation),
dvb_hier2str(dmc.u.dmc_fe_ofdm.hierarchy_information),
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));
/* Create */
return mm->mm_network->mn_create_mux(mm, onid, tsid, &dmc);

View file

@ -380,439 +380,306 @@ dvb_convert_date(const uint8_t *dvb_buf)
*/
#if ENABLE_DVBAPI
#define dvb_str2val(p)\
const char *dvb_##p##2str (int p) { return val2str(p, p##tab); }\
int dvb_str2##p (const char *p) { return str2val(p, p##tab); }
const static struct strtab rollofftab[] = {
#if DVB_VER_ATLEAST(5,0)
{ "35", ROLLOFF_35 },
{ "20", ROLLOFF_20 },
{ "25", ROLLOFF_25 },
{ "AUTO", ROLLOFF_AUTO }
#endif
};
dvb_str2val(rolloff);
#define DVB_EOD -10 /* end-of-data */
static const char *dvb_common2str(int p)
{
if (p == 0)
return "NONE";
if (p == 1)
return "AUTO";
return NULL;
}
static int dvb_str2common(const char *p)
{
if (strcmp(p, "NONE") == 0)
return 0;
if (strcmp(p, "AUTO") == 0)
return 1;
return DVB_EOD;
}
static int dvb_verify(int val, int *table)
{
while (*table != DVB_EOD) {
if (val == *table)
return val;
table++;
}
return 0; /* NONE */
}
const char *dvb_rolloff2str(int p)
{
static char __thread buf[16];
const char *res = dvb_common2str(p);
if (res)
return res;
sprintf(buf, "%02i", p / 10);
return buf;
}
int dvb_str2rolloff(const char *p)
{
static int rolloff_table[] = {
DVB_ROLLOFF_20,
DVB_ROLLOFF_25,
DVB_ROLLOFF_35,
DVB_EOD,
};
int res = dvb_str2common(p);
if (res != DVB_EOD)
return res;
res = atoi(p) * 10;
return dvb_verify(atoi(p) * 10, rolloff_table);
}
const static struct strtab delsystab[] = {
#if DVB_VER_ATLEAST(5,0)
{ "UNDEFINED", SYS_UNDEFINED },
{ "DVBC_ANNEX_AC", SYS_DVBC_ANNEX_AC },
{ "DVBC_ANNEX_B", SYS_DVBC_ANNEX_B },
{ "DVBT", SYS_DVBT },
{ "DVBS", SYS_DVBS },
{ "DVBS2", SYS_DVBS2 },
{ "DVBH", SYS_DVBH },
{ "ISDBT", SYS_ISDBT },
{ "ISDBS", SYS_ISDBS },
{ "ISDBC", SYS_ISDBC },
{ "ATSC", SYS_ATSC },
{ "ATSCMH", SYS_ATSCMH },
{ "DMBTH", SYS_DMBTH },
{ "CMMB", SYS_CMMB },
{ "DAB", SYS_DAB },
#endif
#if DVB_VER_ATLEAST(5,1)
{ "DSS", SYS_DSS },
#endif
#if DVB_VER_ATLEAST(5,4)
{ "DVBT2", SYS_DVBT2 },
{ "TURBO", SYS_TURBO }
#endif
{ "NONE", DVB_SYS_NONE },
{ "DVBC_ANNEX_A", DVB_SYS_DVBC_ANNEX_A },
{ "DVBC_ANNEX_B", DVB_SYS_DVBC_ANNEX_B },
{ "DVBC_ANNEX_C", DVB_SYS_DVBC_ANNEX_C },
{ "DVBC_ANNEX_AC",DVB_SYS_DVBC_ANNEX_A }, /* for compatibility */
{ "DVBT", DVB_SYS_DVBT },
{ "DVBT2", DVB_SYS_DVBT2 },
{ "DVBS", DVB_SYS_DVBS },
{ "DVBS2", DVB_SYS_DVBS2 },
{ "DVBH", DVB_SYS_DVBH },
{ "ISDBT", DVB_SYS_ISDBT },
{ "ISDBS", DVB_SYS_ISDBS },
{ "ISDBC", DVB_SYS_ISDBC },
{ "ATSC", DVB_SYS_ATSC },
{ "ATSCMH", DVB_SYS_ATSCMH },
{ "DTMB", DVB_SYS_DTMB },
{ "DMBTH", DVB_SYS_DTMB }, /* for compatibility */
{ "CMMB", DVB_SYS_CMMB },
{ "DAB", DVB_SYS_DAB },
{ "DSS", DVB_SYS_DSS },
{ "TURBO", DVB_SYS_TURBO }
};
dvb_str2val(delsys);
#if DVB_VER_ATLEAST(5,10)
int
dvb_delsys2type ( fe_delivery_system_t delsys )
dvb_delsys2type ( dvb_fe_delivery_system_t delsys )
{
switch (delsys) {
case SYS_DVBC_ANNEX_AC:
case SYS_DVBC_ANNEX_B:
case SYS_ISDBC:
return FE_QAM;
case SYS_DVBT:
case SYS_DVBT2:
case SYS_TURBO:
case SYS_ISDBT:
return FE_OFDM;
case SYS_DVBS:
case SYS_DVBS2:
case SYS_ISDBS:
return FE_QPSK;
case SYS_ATSC:
case SYS_ATSCMH:
return FE_ATSC;
case DVB_SYS_DVBC_ANNEX_A:
case DVB_SYS_DVBC_ANNEX_B:
case DVB_SYS_DVBC_ANNEX_C:
case DVB_SYS_ISDBC:
return DVB_TYPE_C;
case DVB_SYS_DVBT:
case DVB_SYS_DVBT2:
case DVB_SYS_TURBO:
case DVB_SYS_ISDBT:
return DVB_TYPE_T;
case DVB_SYS_DVBS:
case DVB_SYS_DVBS2:
case DVB_SYS_ISDBS:
return DVB_TYPE_S;
case DVB_SYS_ATSC:
case DVB_SYS_ATSCMH:
return DVB_TYPE_ATSC;
default:
return -1;
return DVB_TYPE_NONE;
}
}
#endif
const static struct strtab fectab[] = {
{ "NONE", FEC_NONE },
{ "1/2", FEC_1_2 },
{ "2/3", FEC_2_3 },
{ "3/4", FEC_3_4 },
{ "4/5", FEC_4_5 },
{ "5/6", FEC_5_6 },
{ "6/7", FEC_6_7 },
{ "7/8", FEC_7_8 },
{ "8/9", FEC_8_9 },
{ "AUTO", FEC_AUTO },
#if DVB_VER_ATLEAST(5,0)
{ "3/5", FEC_3_5 },
{ "9/10", FEC_9_10 }
#endif
};
dvb_str2val(fec);
const char *dvb_fec2str(int p)
{
static char __thread buf[16];
const char *res = dvb_common2str(p);
if (res)
return res;
sprintf(buf, "%i/%i", p / 100, p % 100);
return buf;
}
int dvb_str2fec(const char *p)
{
static int fec_table[] = {
DVB_FEC_1_2,
DVB_FEC_1_3,
DVB_FEC_1_5,
DVB_FEC_2_3,
DVB_FEC_2_5,
DVB_FEC_2_9,
DVB_FEC_3_4,
DVB_FEC_3_5,
DVB_FEC_4_5,
DVB_FEC_4_15,
DVB_FEC_5_6,
DVB_FEC_5_9,
DVB_FEC_6_7,
DVB_FEC_7_8,
DVB_FEC_7_9,
DVB_FEC_7_15,
DVB_FEC_8_9,
DVB_FEC_8_15,
DVB_FEC_9_10,
DVB_FEC_9_20,
DVB_FEC_11_15,
DVB_FEC_11_20,
DVB_FEC_11_45,
DVB_FEC_13_18,
DVB_FEC_13_45,
DVB_FEC_14_45,
DVB_FEC_23_36,
DVB_FEC_25_36,
DVB_FEC_26_45,
DVB_FEC_28_45,
DVB_FEC_29_45,
DVB_FEC_31_45,
DVB_FEC_32_45,
DVB_FEC_77_90,
DVB_EOD,
};
int res = dvb_str2common(p);
int hi, lo;
if (res != DVB_EOD)
return res;
hi = lo = 0;
sscanf(p, "%i/%i", &hi, &lo);
return dvb_verify(hi * 100 + lo, fec_table);
}
const static struct strtab qamtab[] = {
{ "QPSK", QPSK },
{ "QAM16", QAM_16 },
{ "QAM32", QAM_32 },
{ "QAM64", QAM_64 },
{ "QAM128", QAM_128 },
{ "QAM256", QAM_256 },
{ "AUTO", QAM_AUTO },
{ "8VSB", VSB_8 },
{ "16VSB", VSB_16 },
#if DVB_VER_ATLEAST(5,0)
{ "DQPSK", DQPSK },
#endif
#if DVB_VER_ATLEAST(5,1)
{ "8PSK", PSK_8 },
{ "16APSK", APSK_16 },
{ "32APSK", APSK_32 },
#endif
{ "NONE", DVB_MOD_NONE },
{ "AUTO", DVB_MOD_AUTO },
{ "QPSK", DVB_MOD_QPSK },
{ "QAM4NR", DVB_MOD_QAM_4_NR },
{ "QAM-AUTO", DVB_MOD_QAM_AUTO },
{ "QAM16", DVB_MOD_QAM_16 },
{ "QAM32", DVB_MOD_QAM_32 },
{ "QAM64", DVB_MOD_QAM_64 },
{ "QAM128", DVB_MOD_QAM_128 },
{ "QAM256", DVB_MOD_QAM_256 },
{ "8VSB", DVB_MOD_VSB_8 },
{ "16VSB", DVB_MOD_VSB_16 },
{ "8PSK", DVB_MOD_PSK_8 },
{ "DQPSK", DVB_MOD_DQPSK },
{ "BPSK", DVB_MOD_BPSK },
{ "BPSK-S", DVB_MOD_BPSK_S },
{ "16APSK", DVB_MOD_APSK_16 },
{ "32APSK", DVB_MOD_APSK_32 },
{ "64APSK", DVB_MOD_APSK_64 },
{ "128APSK", DVB_MOD_APSK_128 },
{ "256APSK", DVB_MOD_APSK_256 },
{ "8APSK-L", DVB_MOD_APSK_8_L },
{ "16APSK-L", DVB_MOD_APSK_16_L },
{ "32APSK-L", DVB_MOD_APSK_32_L },
{ "64APSK-L", DVB_MOD_APSK_64_L },
{ "128APSK-L", DVB_MOD_APSK_128_L },
{ "256APSK-L", DVB_MOD_APSK_256_L },
};
dvb_str2val(qam);
const static struct strtab bwtab[] = {
{ "8MHz", BANDWIDTH_8_MHZ },
{ "7MHz", BANDWIDTH_7_MHZ },
{ "6MHz", BANDWIDTH_6_MHZ },
{ "AUTO", BANDWIDTH_AUTO },
#if DVB_VER_ATLEAST(5,3)
{ "5MHz", BANDWIDTH_5_MHZ },
{ "10MHz", BANDWIDTH_10_MHZ },
{ "1712kHz", BANDWIDTH_1_712_MHZ},
#endif
};
dvb_str2val(bw);
const char *dvb_bw2str(int p)
{
static char __thread buf[16];
const char *res = dvb_common2str(p);
if (res)
return res;
if (p % 1000)
sprintf(buf, "%i.%iMHz", p / 1000, p % 1000);
else
sprintf(buf, "%iMHz", p / 1000);
return buf;
}
int dvb_str2bw(const char *p)
{
static int bw_table[] = {
DVB_BANDWIDTH_1_712_MHZ,
DVB_BANDWIDTH_5_MHZ,
DVB_BANDWIDTH_6_MHZ,
DVB_BANDWIDTH_7_MHZ,
DVB_BANDWIDTH_8_MHZ,
DVB_BANDWIDTH_10_MHZ,
DVB_EOD,
};
int len, res = dvb_str2common(p);
int hi, lo;
if (res != DVB_EOD)
return res;
len = strlen(p);
hi = lo = 0;
sscanf(p, "%i.%i", &hi, &lo);
if (len > 3 && strcmp(&p[len-3], "MHz") == 0)
hi = hi * 1000 + lo;
return dvb_verify(hi, bw_table);
}
const static struct strtab modetab[] = {
{ "2k", TRANSMISSION_MODE_2K },
{ "8k", TRANSMISSION_MODE_8K },
{ "AUTO", TRANSMISSION_MODE_AUTO },
#if DVB_VER_ATLEAST(5,1)
{ "4k", TRANSMISSION_MODE_4K },
#endif
#if DVB_VER_ATLEAST(5,3)
{ "1k", TRANSMISSION_MODE_1K },
{ "2k", TRANSMISSION_MODE_16K },
{ "32k", TRANSMISSION_MODE_32K },
#endif
{ "NONE", DVB_TRANSMISSION_MODE_NONE },
{ "AUTO", DVB_TRANSMISSION_MODE_AUTO },
{ "1k", DVB_TRANSMISSION_MODE_1K },
{ "2k", DVB_TRANSMISSION_MODE_2K },
{ "8k", DVB_TRANSMISSION_MODE_8K },
{ "4k", DVB_TRANSMISSION_MODE_4K },
{ "16k", DVB_TRANSMISSION_MODE_16K },
{ "32k", DVB_TRANSMISSION_MODE_32K },
{ "C1", DVB_TRANSMISSION_MODE_C1 },
{ "C3780", DVB_TRANSMISSION_MODE_C3780 },
};
dvb_str2val(mode);
const static struct strtab guardtab[] = {
{ "1/32", GUARD_INTERVAL_1_32 },
{ "1/16", GUARD_INTERVAL_1_16 },
{ "1/8", GUARD_INTERVAL_1_8 },
{ "1/4", GUARD_INTERVAL_1_4 },
{ "AUTO", GUARD_INTERVAL_AUTO },
#if DVB_VER_ATLEAST(5,3)
{ "1/128", GUARD_INTERVAL_1_128 },
{ "19/128", GUARD_INTERVAL_19_128 },
{ "19/256", GUARD_INTERVAL_19_256},
#endif
{ "NONE", DVB_GUARD_INTERVAL_NONE },
{ "AUTO", DVB_GUARD_INTERVAL_AUTO },
{ "1/4", DVB_GUARD_INTERVAL_1_4 },
{ "1/8", DVB_GUARD_INTERVAL_1_8 },
{ "1/32", DVB_GUARD_INTERVAL_1_32 },
{ "1/16", DVB_GUARD_INTERVAL_1_16 },
{ "1/128", DVB_GUARD_INTERVAL_1_128 },
{ "19/128", DVB_GUARD_INTERVAL_19_128 },
{ "19/256", DVB_GUARD_INTERVAL_19_256 },
{ "PN420", DVB_GUARD_INTERVAL_PN420 },
{ "PN595", DVB_GUARD_INTERVAL_PN595 },
{ "PN945", DVB_GUARD_INTERVAL_PN945 },
};
dvb_str2val(guard);
const static struct strtab hiertab[] = {
{ "NONE", HIERARCHY_NONE },
{ "1", HIERARCHY_1 },
{ "2", HIERARCHY_2 },
{ "4", HIERARCHY_4 },
{ "AUTO", HIERARCHY_AUTO }
{ "NONE", DVB_HIERARCHY_NONE },
{ "AUTO", DVB_HIERARCHY_AUTO },
{ "1", DVB_HIERARCHY_1 },
{ "2", DVB_HIERARCHY_2 },
{ "4", DVB_HIERARCHY_4 },
};
dvb_str2val(hier);
const static struct strtab poltab[] = {
{ "V", POLARISATION_VERTICAL },
{ "H", POLARISATION_HORIZONTAL },
{ "L", POLARISATION_CIRCULAR_LEFT },
{ "R", POLARISATION_CIRCULAR_RIGHT },
{ "V", DVB_POLARISATION_VERTICAL },
{ "H", DVB_POLARISATION_HORIZONTAL },
{ "L", DVB_POLARISATION_CIRCULAR_LEFT },
{ "R", DVB_POLARISATION_CIRCULAR_RIGHT },
};
dvb_str2val(pol);
const static struct strtab typetab[] = {
{"DVB-T", FE_OFDM},
{"DVB-C", FE_QAM},
{"DVB-S", FE_QPSK},
{"ATSC", FE_ATSC},
{"DVB-T", DVB_TYPE_T},
{"DVB-C", DVB_TYPE_C},
{"DVB-S", DVB_TYPE_S},
{"ATSC", DVB_TYPE_ATSC},
};
dvb_str2val(type);
const static struct strtab pilottab[] = {
#if DVB_VER_ATLEAST(5,0)
{"AUTO", PILOT_AUTO},
{"ON", PILOT_ON},
{"OFF", PILOT_OFF}
#endif
{"NONE", DVB_PILOT_AUTO},
{"AUTO", DVB_PILOT_AUTO},
{"ON", DVB_PILOT_ON},
{"OFF", DVB_PILOT_OFF}
};
dvb_str2val(pilot);
#undef dvb_str2val
/*
* Process mux conf
*/
static const char *
dvb_mux_conf_load_dvbt ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
int r;
const char *s;
s = htsmsg_get_str(m, "bandwidth");
if(s == NULL || (r = dvb_str2bw(s)) < 0)
return "Invalid bandwidth";
dmc->dmc_fe_params.u.ofdm.bandwidth = r;
s = htsmsg_get_str(m, "constellation");
if(s == NULL || (r = dvb_str2qam(s)) < 0)
return "Invalid QAM constellation";
dmc->dmc_fe_params.u.ofdm.constellation = r;
s = htsmsg_get_str(m, "transmission_mode");
if(s == NULL || (r = dvb_str2mode(s)) < 0)
return "Invalid transmission mode";
dmc->dmc_fe_params.u.ofdm.transmission_mode = r;
s = htsmsg_get_str(m, "guard_interval");
if(s == NULL || (r = dvb_str2guard(s)) < 0)
return "Invalid guard interval";
dmc->dmc_fe_params.u.ofdm.guard_interval = r;
s = htsmsg_get_str(m, "hierarchy");
if(s == NULL || (r = dvb_str2hier(s)) < 0)
return "Invalid heirarchy information";
dmc->dmc_fe_params.u.ofdm.hierarchy_information = r;
s = htsmsg_get_str(m, "fec_hi");
if(s == NULL || (r = dvb_str2fec(s)) < 0)
return "Invalid hi-FEC";
dmc->dmc_fe_params.u.ofdm.code_rate_HP = r;
s = htsmsg_get_str(m, "fec_lo");
if(s == NULL || (r = dvb_str2fec(s)) < 0)
return "Invalid lo-FEC";
dmc->dmc_fe_params.u.ofdm.code_rate_LP = r;
return NULL;
}
static const char *
dvb_mux_conf_load_dvbc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
int r;
const char *s;
htsmsg_get_u32(m, "symbol_rate", &dmc->dmc_fe_params.u.qam.symbol_rate);
if(dmc->dmc_fe_params.u.qam.symbol_rate == 0)
return "Invalid symbol rate";
s = htsmsg_get_str(m, "constellation");
if(s == NULL || (r = dvb_str2qam(s)) < 0)
return "Invalid QAM constellation";
dmc->dmc_fe_params.u.qam.modulation = r;
s = htsmsg_get_str(m, "fec");
if(s == NULL || (r = dvb_str2fec(s)) < 0)
return "Invalid FEC";
dmc->dmc_fe_params.u.qam.fec_inner = r;
return NULL;
}
static const char *
dvb_mux_conf_load_dvbs ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
int r;
const char *s;
htsmsg_get_u32(m, "symbol_rate", &dmc->dmc_fe_params.u.qpsk.symbol_rate);
if(dmc->dmc_fe_params.u.qpsk.symbol_rate == 0)
return "Invalid symbol rate";
s = htsmsg_get_str(m, "fec");
if(s == NULL || (r = dvb_str2fec(s)) < 0)
return "Invalid FEC";
dmc->dmc_fe_params.u.qpsk.fec_inner = r;
s = htsmsg_get_str(m, "polarisation");
if(s == NULL || (r = dvb_str2pol(s)) < 0)
return "Invalid polarisation";
dmc->dmc_fe_polarisation = r;
#if DVB_VER_ATLEAST(5,0)
s = htsmsg_get_str(m, "modulation");
if(s == NULL || (r = dvb_str2qam(s)) < 0) {
r = QPSK;
tvhlog(LOG_INFO, "dvb", "no modulation, using default QPSK");
}
dmc->dmc_fe_modulation = r;
s = htsmsg_get_str(m, "rolloff");
if(s == NULL || (r = dvb_str2rolloff(s)) < 0) {
r = ROLLOFF_35;
tvhlog(LOG_INFO, "dvb", "no rolloff, using default ROLLOFF_35");
}
dmc->dmc_fe_rolloff = r;
// TODO: pilot mode
#endif
return NULL;
}
static const char *
dvb_mux_conf_load_atsc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
int r;
const char *s;
s = htsmsg_get_str(m, "constellation");
if(s == NULL || (r = dvb_str2qam(s)) < 0)
return "Invalid VSB constellation";
dmc->dmc_fe_params.u.vsb.modulation = r;
return NULL;
}
const char *
dvb_mux_conf_load ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
{
#if DVB_VER_ATLEAST(5,0)
int r;
const char *str;
#endif
uint32_t u32;
memset(dmc, 0, sizeof(dvb_mux_conf_t));
dmc->dmc_fe_params.inversion = INVERSION_AUTO;
/* Delivery system */
#if DVB_VER_ATLEAST(5,0)
str = htsmsg_get_str(m, "delsys");
if (!str || (r = dvb_str2delsys(str)) < 0) {
if (type == FE_OFDM) r = SYS_DVBT;
else if (type == FE_QAM) r = SYS_DVBC_ANNEX_AC;
else if (type == FE_QPSK) r = SYS_DVBS;
else if (type == FE_ATSC) r = SYS_ATSC;
else
return "Invalid FE type";
tvhlog(LOG_INFO, "dvb", "no delsys, using default %s", dvb_delsys2str(r));
}
dmc->dmc_fe_delsys = r;
#endif
/* Frequency */
if (htsmsg_get_u32(m, "frequency", &u32))
return "Invalid frequency";
dmc->dmc_fe_params.frequency = u32;
/* Type specific */
if (type == FE_OFDM) return dvb_mux_conf_load_dvbt(dmc, m);
else if (type == FE_QAM) return dvb_mux_conf_load_dvbc(dmc, m);
else if (type == FE_QPSK) return dvb_mux_conf_load_dvbs(dmc, m);
else if (type == FE_ATSC) return dvb_mux_conf_load_atsc(dmc, m);
else
return "Invalid FE type";
}
static void
dvb_mux_conf_save_dvbt ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
struct dvb_ofdm_parameters *ofdm = &dmc->dmc_fe_params.u.ofdm;
htsmsg_add_str(m, "bandwidth",
dvb_bw2str(ofdm->bandwidth));
htsmsg_add_str(m, "constellation",
dvb_qam2str(ofdm->constellation));
htsmsg_add_str(m, "transmission_mode",
dvb_mode2str(ofdm->transmission_mode));
htsmsg_add_str(m, "guard_interval",
dvb_guard2str(ofdm->guard_interval));
htsmsg_add_str(m, "hierarchy",
dvb_hier2str(ofdm->hierarchy_information));
htsmsg_add_str(m, "fec_hi",
dvb_fec2str(ofdm->code_rate_HP));
htsmsg_add_str(m, "fec_lo",
dvb_fec2str(ofdm->code_rate_LP));
}
static void
dvb_mux_conf_save_dvbc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
struct dvb_qam_parameters *qam = &dmc->dmc_fe_params.u.qam;
htsmsg_add_u32(m, "symbol_rate", qam->symbol_rate);
htsmsg_add_str(m, "constellation", dvb_qam2str(qam->modulation));
htsmsg_add_str(m, "fec", dvb_fec2str(qam->fec_inner));
}
static void
dvb_mux_conf_save_dvbs ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
struct dvb_qpsk_parameters *qpsk = &dmc->dmc_fe_params.u.qpsk;
htsmsg_add_u32(m, "symbol_rate", qpsk->symbol_rate);
htsmsg_add_str(m, "fec", dvb_fec2str(qpsk->fec_inner));
htsmsg_add_str(m, "polarisation", dvb_pol2str(dmc->dmc_fe_polarisation));
#if DVB_VER_ATLEAST(5,0)
htsmsg_add_str(m, "modulation", dvb_qam2str(dmc->dmc_fe_modulation));
htsmsg_add_str(m, "rolloff", dvb_rolloff2str(dmc->dmc_fe_rolloff));
#endif
}
static void
dvb_mux_conf_save_atsc ( dvb_mux_conf_t *dmc, htsmsg_t *m )
{
htsmsg_add_str(m, "constellation",
dvb_qam2str(dmc->dmc_fe_params.u.vsb.modulation));
}
void
dvb_mux_conf_save ( fe_type_t type, dvb_mux_conf_t *dmc, htsmsg_t *m )
{
htsmsg_add_u32(m, "frequency", dmc->dmc_fe_params.frequency);
#if DVB_VER_ATLEAST(5,0)
htsmsg_add_str(m, "delsys", dvb_delsys2str(dmc->dmc_fe_delsys));
#endif
if (type == FE_OFDM) dvb_mux_conf_save_dvbt(dmc, m);
else if (type == FE_QAM) dvb_mux_conf_save_dvbc(dmc, m);
else if (type == FE_QPSK) dvb_mux_conf_save_dvbs(dmc, m);
else if (type == FE_ATSC) dvb_mux_conf_save_atsc(dmc, m);
}
int
dvb_bandwidth ( fe_bandwidth_t bw )
{
switch (bw) {
#if DVB_VER_ATLEAST(5,3)
case BANDWIDTH_10_MHZ:
return 10000000;
case BANDWIDTH_5_MHZ:
return 5000000;
case BANDWIDTH_1_712_MHZ:
return 1712000;
#endif
case BANDWIDTH_8_MHZ:
return 8000000;
case BANDWIDTH_7_MHZ:
return 7000000;
case BANDWIDTH_6_MHZ:
return 6000000;
default:
return 0;
}
}
#endif /* ENABLE_DVBAPI */
/**

View file

@ -33,6 +33,8 @@
#include <fcntl.h>
#include <openssl/sha.h>
#include <linux/dvb/frontend.h>
#define FE_PATH "%s/frontend%d"
#define DVR_PATH "%s/dvr%d"
#define DMX_PATH "%s/demux%d"
@ -155,6 +157,26 @@ linuxdvb_adapter_create
return la;
}
/*
*
*/
static dvb_fe_type_t
linux_dvb_get_type(int linux_type)
{
switch (linux_type) {
case FE_QPSK:
return DVB_TYPE_S;
case FE_QAM:
return DVB_TYPE_C;
case FE_OFDM:
return DVB_TYPE_T;
case FE_ATSC:
return DVB_TYPE_ATSC;
default:
return DVB_TYPE_NONE;
}
}
/*
* Add adapter by path
*/
@ -170,8 +192,9 @@ linuxdvb_adapter_add ( const char *path )
uint8_t uuidbin[20];
htsmsg_t *conf, *feconf;
int save = 0;
dvb_fe_type_t type;
#if DVB_VER_ATLEAST(5,10)
int fetypes[4] = { 0 };
dvb_fe_type_t fetypes[DVB_TYPE_LAST+1] = { 0 };
struct dtv_property cmd = {
.cmd = DTV_ENUM_DELSYS
};
@ -242,6 +265,11 @@ linuxdvb_adapter_add ( const char *path )
tvhlog(LOG_ERR, "linuxdvb", "unable to query %s", fe_path);
continue;
}
type = linux_dvb_get_type(dfi.type);
if (type == DVB_TYPE_NONE) {
tvhlog(LOG_ERR, "linuxdvb", "unable to determine FE type %s - %i", fe_path, dfi.type);
continue;
}
/* DVR/DMX (bit of a guess) */
snprintf(dmx_path, sizeof(dmx_path), DMX_PATH, path, i);
@ -283,22 +311,23 @@ linuxdvb_adapter_add ( const char *path )
}
/* Create frontend */
linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, &dfi);
linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, type, dfi.name);
#if DVB_VER_ATLEAST(5,10)
fetypes[dfi.type] = 1;
fetypes[type] = 1;
for (j = 0; j < cmd.u.buffer.len; j++) {
/* Invalid */
if ((dfi.type = dvb_delsys2type(cmd.u.buffer.data[j])) == -1)
if ((type = dvb_delsys2type(cmd.u.buffer.data[j])) == DVB_TYPE_NONE)
continue;
/* Couldn't find */
if (fetypes[dfi.type])
if (fetypes[type])
continue;
/* Create */
linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, &dfi);
fetypes[dfi.type] = 1;
linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path,
type, dfi.name);
fetypes[type] = 1;
}
#endif
pthread_mutex_unlock(&global_lock);

View file

@ -30,6 +30,8 @@
#include <unistd.h>
#include <math.h>
#include <linux/dvb/frontend.h>
/* **************************************************************************
* Static definition
* *************************************************************************/

View file

@ -31,6 +31,8 @@
#include <fcntl.h>
#include <assert.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
static void
linuxdvb_frontend_monitor ( void *aux );
@ -331,13 +333,13 @@ linuxdvb_frontend_network_list ( mpegts_input_t *mi )
extern const idclass_t linuxdvb_network_dvbs_class;
extern const idclass_t linuxdvb_network_atsc_class;
if (lfe->lfe_info.type == FE_OFDM)
if (lfe->lfe_type == DVB_TYPE_T)
idc = &linuxdvb_network_dvbt_class;
else if (lfe->lfe_info.type == FE_QAM)
else if (lfe->lfe_type == DVB_TYPE_C)
idc = &linuxdvb_network_dvbc_class;
else if (lfe->lfe_info.type == FE_QPSK)
else if (lfe->lfe_type == DVB_TYPE_S)
idc = &linuxdvb_network_dvbs_class;
else if (lfe->lfe_info.type == FE_ATSC)
else if (lfe->lfe_type == DVB_TYPE_ATSC)
idc = &linuxdvb_network_atsc_class;
else
return NULL;
@ -358,8 +360,8 @@ linuxdvb_frontend_default_tables
psi_tables_default(mm);
/* ATSC */
if (lfe->lfe_info.type == FE_ATSC) {
if (lm->lm_tuning.dmc_fe_params.u.vsb.modulation == VSB_8)
if (lfe->lfe_type == DVB_TYPE_ATSC) {
if (lm->lm_tuning.dmc_fe_modulation == DVB_MOD_VSB_8)
psi_tables_atsc_t(mm);
else
psi_tables_atsc_c(mm);
@ -666,15 +668,180 @@ linuxdvb_frontend_input_thread ( void *aux )
* Tuning
* *************************************************************************/
typedef struct tvh2linuxdvb {
int t; ///< TVH internal value
int l; ///< LinuxDVB API value
} tvh2linuxdvb_t;
#define TABLE_EOD -1
static int
translate_from_table
(const char *prefix, int src, tvh2linuxdvb_t *tbl, int defval)
{
while (tbl->t >= 0) {
if (tbl->t == src)
return tbl->l;
tbl++;
}
tvhtrace("linuxdvb", "%s - cannot translate %d", prefix, src);
return defval;
}
#define TOSTR(s) #s
#define TR(s, t, d) translate_from_table(TOSTR(s), dmc->dmc_fe_##s , t, d)
#define TRU(s, t, d) translate_from_table(TOSTR(s), dmc->u.dmc_fe_##s , t, d)
int
linuxdvb_frontend_tune0
( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq )
{
static tvh2linuxdvb_t inv_tbl[] = {
{ .t = DVB_INVERSION_AUTO, .l = INVERSION_AUTO },
{ .t = DVB_INVERSION_OFF, .l = INVERSION_OFF },
{ .t = DVB_INVERSION_ON, .l = INVERSION_ON },
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t bw_tbl[] = {
{ .t = DVB_BANDWIDTH_AUTO, .l = BANDWIDTH_AUTO },
#if DVB_VER_ATLEAST(5,3)
{ .t = DVB_BANDWIDTH_1_712_MHZ, .l = BANDWIDTH_1_712_MHZ },
{ .t = DVB_BANDWIDTH_5_MHZ, .l = BANDWIDTH_5_MHZ },
#endif
{ .t = DVB_BANDWIDTH_6_MHZ, .l = BANDWIDTH_6_MHZ },
{ .t = DVB_BANDWIDTH_7_MHZ, .l = BANDWIDTH_7_MHZ },
{ .t = DVB_BANDWIDTH_8_MHZ, .l = BANDWIDTH_8_MHZ },
#if DVB_VER_ATLEAST(5,3)
{ .t = DVB_BANDWIDTH_10_MHZ, .l = BANDWIDTH_10_MHZ },
#endif
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t fec_tbl[] = {
{ .t = DVB_FEC_NONE, .l = FEC_NONE },
{ .t = DVB_FEC_AUTO, .l = FEC_AUTO },
{ .t = DVB_FEC_1_2, .l = FEC_1_2 },
{ .t = DVB_FEC_2_3, .l = FEC_2_3 },
{ .t = DVB_FEC_2_5, .l = FEC_2_5 },
{ .t = DVB_FEC_3_4, .l = FEC_3_4 },
#if DVB_VER_ATLEAST(5,0)
{ .t = DVB_FEC_3_5, .l = FEC_3_5 },
#endif
{ .t = DVB_FEC_4_5, .l = FEC_4_5 },
{ .t = DVB_FEC_5_6, .l = FEC_5_6 },
{ .t = DVB_FEC_6_7, .l = FEC_6_7 },
{ .t = DVB_FEC_7_8, .l = FEC_7_8 },
{ .t = DVB_FEC_8_9, .l = FEC_8_9 },
#if DVB_VER_ATLEAST(5,0)
{ .t = DVB_FEC_9_10, .l = FEC_9_10 },
#endif
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t mod_tbl[] = {
{ .t = DVB_MOD_AUTO, .l = QAM_AUTO },
{ .t = DVB_MOD_QPSK, .l = QPSK },
{ .t = DVB_MOD_QAM_16, .l = QAM_16 },
{ .t = DVB_MOD_QAM_32, .l = QAM_32 },
{ .t = DVB_MOD_QAM_64, .l = QAM_64 },
{ .t = DVB_MOD_QAM_128, .l = QAM_128 },
{ .t = DVB_MOD_QAM_256, .l = QAM_256 },
{ .t = DVB_MOD_QAM_AUTO, .l = QAM_AUTO },
{ .t = DVB_MOD_VSB_8, .l = VSB_8 },
{ .t = DVB_MOD_VSB_16, .l = VSB_16 },
#if DVB_VER_ATLEAST(5,1)
{ .t = DVB_MOD_PSK_8, .l = PSK_8, },
{ .t = DVB_MOD_APSK_16, .l = APSK_16 },
{ .t = DVB_MOD_APSK_32, .l = APSK_32 },
#endif
#if DVB_VER_ATLEAST(5,0)
{ .t = DVB_MOD_DQPSK, .l = DQPSK },
#endif
#if DVB_VER_ATLEAST(5,3)
{ .t = DVB_MOD_QAM_4_NR, .l = QAM_4_NR },
#endif
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t trans_tbl[] = {
{ .t = DVB_TRANSMISSION_MODE_AUTO, .l = TRANSMISSION_MODE_AUTO },
#if DVB_VER_ATLEAST(5,3)
{ .t = DVB_TRANSMISSION_MODE_1K, .l = TRANSMISSION_MODE_1K },
#endif
{ .t = DVB_TRANSMISSION_MODE_2K, .l = TRANSMISSION_MODE_2K },
#if DVB_VER_ATLEAST(5,1)
{ .t = DVB_TRANSMISSION_MODE_4K, .l = TRANSMISSION_MODE_4K },
#endif
{ .t = DVB_TRANSMISSION_MODE_8K, .l = TRANSMISSION_MODE_8K },
#if DVB_VER_ATLEAST(5,3)
{ .t = DVB_TRANSMISSION_MODE_16K, .l = TRANSMISSION_MODE_16K },
{ .t = DVB_TRANSMISSION_MODE_32K, .l = TRANSMISSION_MODE_32K },
{ .t = DVB_TRANSMISSION_MODE_C1, .l = TRANSMISSION_MODE_C1 },
{ .t = DVB_TRANSMISSION_MODE_C3780, .l = TRANSMISSION_MODE_C3780 },
#endif
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t guard_tbl[] = {
{ .t = DVB_GUARD_INTERVAL_AUTO, .l = GUARD_INTERVAL_AUTO },
{ .t = DVB_GUARD_INTERVAL_1_4, .l = GUARD_INTERVAL_1_4 },
{ .t = DVB_GUARD_INTERVAL_1_8, .l = GUARD_INTERVAL_1_8 },
{ .t = DVB_GUARD_INTERVAL_1_16, .l = GUARD_INTERVAL_1_16 },
{ .t = DVB_GUARD_INTERVAL_1_32, .l = GUARD_INTERVAL_1_32 },
#if DVB_VER_ATLEAST(5,3)
{ .t = DVB_GUARD_INTERVAL_1_128, .l = GUARD_INTERVAL_1_128 },
{ .t = DVB_GUARD_INTERVAL_19_128, .l = GUARD_INTERVAL_19_128 },
{ .t = DVB_GUARD_INTERVAL_19_256, .l = GUARD_INTERVAL_19_256 },
#endif
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t h_tbl[] = {
{ .t = DVB_HIERARCHY_NONE, .l = HIERARCHY_NONE },
{ .t = DVB_HIERARCHY_AUTO, .l = HIERARCHY_AUTO },
{ .t = DVB_HIERARCHY_1, .l = HIERARCHY_1 },
{ .t = DVB_HIERARCHY_2, .l = HIERARCHY_2 },
{ .t = DVB_HIERARCHY_4, .l = HIERARCHY_4 },
{ .t = TABLE_EOD }
};
#if DVB_API_VERSION >= 5
static tvh2linuxdvb_t delsys_tbl[] = {
{ .t = DVB_SYS_DVBC_ANNEX_A, .l = SYS_DVBC_ANNEX_A },
{ .t = DVB_SYS_DVBC_ANNEX_B, .l = SYS_DVBC_ANNEX_B },
{ .t = DVB_SYS_DVBC_ANNEX_C, .l = SYS_DVBC_ANNEX_C },
{ .t = DVB_SYS_DVBT, .l = SYS_DVBT },
{ .t = DVB_SYS_DVBT2, .l = SYS_DVBT2 },
{ .t = DVB_SYS_DVBS, .l = SYS_DVBS },
{ .t = DVB_SYS_DVBS2, .l = SYS_DVBS2 },
{ .t = DVB_SYS_DVBH, .l = SYS_DVBH },
{ .t = DVB_SYS_DSS, .l = SYS_DSS },
{ .t = DVB_SYS_ISDBT, .l = SYS_ISDBT },
{ .t = DVB_SYS_ISDBS, .l = SYS_ISDBS },
{ .t = DVB_SYS_ISDBC, .l = SYS_ISDBC },
{ .t = DVB_SYS_ATSC, .l = SYS_ATSC },
{ .t = DVB_SYS_ATSCMH, .l = SYS_ATSCMH },
{ .t = DVB_SYS_DTMB, .l = SYS_DTMB },
{ .t = DVB_SYS_CMMB, .l = SYS_CMMB },
{ .t = DVB_SYS_DAB, .l = SYS_DAB },
{ .t = DVB_SYS_TURBO, .l = SYS_TURBO },
{ .t = TABLE_EOD }
};
static tvh2linuxdvb_t pilot_tbl[] = {
{ .t = DVB_PILOT_AUTO, .l = PILOT_AUTO },
{ .t = DVB_PILOT_ON, .l = PILOT_ON },
{ .t = DVB_PILOT_OFF, .l = PILOT_OFF },
{ .l = TABLE_EOD }
};
static tvh2linuxdvb_t rolloff_tbl[] = {
{ .t = DVB_HIERARCHY_AUTO, .l = ROLLOFF_AUTO },
{ .t = DVB_ROLLOFF_20, .l = ROLLOFF_20 },
{ .t = DVB_ROLLOFF_25, .l = ROLLOFF_25 },
{ .t = DVB_ROLLOFF_35, .l = ROLLOFF_35 },
{ .t = TABLE_EOD },
};
#endif
int r;
struct dvb_frontend_event ev;
char buf1[256];
mpegts_mux_instance_t *cur = LIST_FIRST(&lfe->mi_mux_active);
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux;
dvb_mux_conf_t *dmc;
struct dvb_frontend_parameters p;
// Not sure if this is right place?
/* Currently active */
@ -701,10 +868,53 @@ linuxdvb_frontend_tune0
lfe->lfe_locked = 0;
lfe->lfe_status = 0;
/*
* copy the universal parameters to the Linux kernel structure
*/
dmc = &lm->lm_tuning;
memset(&p, 0, sizeof(p));
p.frequency = dmc->dmc_fe_freq;
p.inversion = TR(inversion, inv_tbl, INVERSION_AUTO);
switch (dmc->dmc_fe_type) {
case DVB_TYPE_T:
#define _OFDM(xyz) p.u.ofdm.xyz
_OFDM(bandwidth) = TRU(ofdm.bandwidth, bw_tbl, BANDWIDTH_AUTO);
_OFDM(code_rate_HP) = TRU(ofdm.code_rate_HP, fec_tbl, FEC_AUTO);
_OFDM(code_rate_LP) = TRU(ofdm.code_rate_LP, fec_tbl, FEC_AUTO);
_OFDM(constellation) = TR(modulation, mod_tbl, QAM_AUTO);
_OFDM(transmission_mode) = TRU(ofdm.transmission_mode, trans_tbl, TRANSMISSION_MODE_AUTO);
_OFDM(guard_interval) = TRU(ofdm.guard_interval, guard_tbl, GUARD_INTERVAL_AUTO);
_OFDM(hierarchy_information)
= TRU(ofdm.hierarchy_information, h_tbl, HIERARCHY_AUTO);
#undef _OFDM
break;
case DVB_TYPE_C:
p.u.qam.symbol_rate = dmc->u.dmc_fe_qam.symbol_rate;
p.u.qam.fec_inner = TRU(qam.fec_inner, fec_tbl, FEC_AUTO);
p.u.qam.modulation = TR(modulation, mod_tbl, QAM_AUTO);
break;
case DVB_TYPE_S:
p.u.qpsk.symbol_rate = dmc->u.dmc_fe_qpsk.symbol_rate;
p.u.qpsk.fec_inner = TRU(qpsk.fec_inner, fec_tbl, FEC_AUTO);
break;
case DVB_TYPE_ATSC:
p.u.vsb.modulation = TR(modulation, mod_tbl, QAM_AUTO);
break;
default:
tvherror("linuxdvb", "%s - unknown FE type %d", buf1, dmc->dmc_fe_type);
return SM_CODE_TUNING_FAILED;
}
if (freq != (uint32_t)-1)
p.frequency = freq;
if (dmc->dmc_fe_type != lfe->lfe_type) {
tvherror("linuxdvb", "%s - failed to tune [type does not match %i != %i]", buf1, dmc->dmc_fe_type, lfe->lfe_type);
return SM_CODE_TUNING_FAILED;
}
/* S2 tuning */
#if DVB_API_VERSION >= 5
dvb_mux_conf_t *dmc = &lm->lm_tuning;
struct dvb_frontend_parameters *p = &dmc->dmc_fe_params;
struct dtv_property cmds[20];
struct dtv_properties cmdseq = { .num = 0, .props = cmds };
@ -720,62 +930,58 @@ linuxdvb_frontend_tune0
return -1;
if (freq == (uint32_t)-1)
freq = p->frequency;
freq = p.frequency;
/* Tune */
#define S2CMD(c, d)\
cmds[cmdseq.num].cmd = c;\
cmds[cmdseq.num++].u.data = d
memset(&cmds, 0, sizeof(cmds));
S2CMD(DTV_DELIVERY_SYSTEM, lm->lm_tuning.dmc_fe_delsys);
S2CMD(DTV_DELIVERY_SYSTEM, TR(delsys, delsys_tbl, SYS_UNDEFINED));
S2CMD(DTV_FREQUENCY, freq);
S2CMD(DTV_INVERSION, p->inversion);
S2CMD(DTV_INVERSION, p.inversion);
/* DVB-T */
if (lfe->lfe_info.type == FE_OFDM) {
S2CMD(DTV_BANDWIDTH_HZ, dvb_bandwidth(p->u.ofdm.bandwidth));
if (lfe->lfe_type == DVB_TYPE_T) {
S2CMD(DTV_BANDWIDTH_HZ, dvb_bandwidth(dmc->u.dmc_fe_ofdm.bandwidth));
#if DVB_VER_ATLEAST(5,1)
S2CMD(DTV_CODE_RATE_HP, p->u.ofdm.code_rate_HP);
S2CMD(DTV_CODE_RATE_LP, p->u.ofdm.code_rate_LP);
S2CMD(DTV_CODE_RATE_HP, p.u.ofdm.code_rate_HP);
S2CMD(DTV_CODE_RATE_LP, p.u.ofdm.code_rate_LP);
#endif
S2CMD(DTV_MODULATION, p->u.ofdm.constellation);
S2CMD(DTV_MODULATION, p.u.ofdm.constellation);
#if DVB_VER_ATLEAST(5,1)
S2CMD(DTV_TRANSMISSION_MODE, p->u.ofdm.transmission_mode);
S2CMD(DTV_GUARD_INTERVAL, p->u.ofdm.guard_interval);
S2CMD(DTV_HIERARCHY, p->u.ofdm.hierarchy_information);
S2CMD(DTV_TRANSMISSION_MODE, p.u.ofdm.transmission_mode);
S2CMD(DTV_GUARD_INTERVAL, p.u.ofdm.guard_interval);
S2CMD(DTV_HIERARCHY, p.u.ofdm.hierarchy_information);
#endif
/* DVB-C */
} else if (lfe->lfe_info.type == FE_QAM) {
S2CMD(DTV_SYMBOL_RATE, p->u.qam.symbol_rate);
S2CMD(DTV_MODULATION, p->u.qam.modulation);
S2CMD(DTV_INNER_FEC, p->u.qam.fec_inner);
} else if (lfe->lfe_type == DVB_TYPE_C) {
S2CMD(DTV_SYMBOL_RATE, p.u.qam.symbol_rate);
S2CMD(DTV_MODULATION, p.u.qam.modulation);
S2CMD(DTV_INNER_FEC, p.u.qam.fec_inner);
/* DVB-S */
} else if (lfe->lfe_info.type == FE_QPSK) {
S2CMD(DTV_SYMBOL_RATE, p->u.qpsk.symbol_rate);
S2CMD(DTV_INNER_FEC, p->u.qpsk.fec_inner);
S2CMD(DTV_PILOT, dmc->dmc_fe_pilot);
S2CMD(DTV_MODULATION, dmc->dmc_fe_modulation);
if (lm->lm_tuning.dmc_fe_delsys == SYS_DVBS) {
S2CMD(DTV_ROLLOFF, ROLLOFF_35);
} 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_ROLLOFF, dmc->dmc_fe_rolloff);
S2CMD(DTV_ROLLOFF, TR(rolloff, rolloff_tbl, ROLLOFF_AUTO));
}
/* ATSC */
} else {
S2CMD(DTV_MODULATION, p->u.vsb.modulation);
S2CMD(DTV_MODULATION, p.u.vsb.modulation);
}
/* Tune */
S2CMD(DTV_TUNE, 0);
#undef S2CMD
#else
dvb_mux_conf_t dmc = lm->lm_tuning;
struct dvb_frontend_parameters *p = &dmc.dmc_fe_params;
if (freq != (uint32_t)-1)
p->frequency = freq;
#endif
/* discard stale events */
@ -842,16 +1048,16 @@ linuxdvb_frontend_t *
linuxdvb_frontend_create
( htsmsg_t *conf, linuxdvb_adapter_t *la, int number,
const char *fe_path, const char *dmx_path, const char *dvr_path,
struct dvb_frontend_info *dfi )
dvb_fe_type_t type, const char *name )
{
const idclass_t *idc;
const char *str, *uuid = NULL, *scuuid = NULL, *sctype = NULL;
char id[12], name[256];
char id[12], lname[256];
linuxdvb_frontend_t *lfe;
htsmsg_t *scconf = NULL;
/* Internal config ID */
snprintf(id, sizeof(id), "%s #%d", dvb_type2str(dfi->type), number);
snprintf(id, sizeof(id), "%s #%d", dvb_type2str(type), number);
if (conf)
conf = htsmsg_get_map(conf, id);
if (conf)
@ -868,16 +1074,16 @@ linuxdvb_frontend_create
}
/* Class */
if (dfi->type == FE_QPSK)
if (type == DVB_TYPE_S)
idc = &linuxdvb_frontend_dvbs_class;
else if (dfi->type == FE_QAM)
else if (type == DVB_TYPE_C)
idc = &linuxdvb_frontend_dvbc_class;
else if (dfi->type == FE_OFDM)
else if (type == DVB_TYPE_T)
idc = &linuxdvb_frontend_dvbt_class;
else if (dfi->type == FE_ATSC)
else if (type == DVB_TYPE_ATSC)
idc = &linuxdvb_frontend_atsc_class;
else {
tvherror("linuxdvb", "unknown FE type %d", dfi->type);
tvherror("linuxdvb", "unknown FE type %d", type);
return NULL;
}
@ -887,7 +1093,9 @@ linuxdvb_frontend_create
// in mpegts_input_create()). So we must set early.
lfe = calloc(1, sizeof(linuxdvb_frontend_t));
lfe->lfe_number = number;
memcpy(&lfe->lfe_info, dfi, sizeof(struct dvb_frontend_info));
lfe->lfe_type = type;
strncpy(lfe->lfe_name, name, sizeof(lfe->lfe_name));
lfe->lfe_name[sizeof(lfe->lfe_name)-1] = '\0';
lfe = (linuxdvb_frontend_t*)mpegts_input_create0((mpegts_input_t*)lfe, idc, uuid, conf);
if (!lfe) return NULL;
@ -897,8 +1105,8 @@ linuxdvb_frontend_create
/* Default name */
if (!lfe->mi_name) {
snprintf(name, sizeof(name), "%s : %s", dfi->name, id);
lfe->mi_name = strdup(name);
snprintf(lname, sizeof(lname), "%s : %s", name, id);
lfe->mi_name = strdup(lname);
}
/* Set paths */
@ -933,7 +1141,7 @@ linuxdvb_frontend_create
}
/* Create satconf */
if (dfi->type == FE_QPSK && !lfe->lfe_satconf)
if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf)
lfe->lfe_satconf = linuxdvb_satconf_create(lfe, sctype, scuuid, scconf);
return lfe;
@ -947,7 +1155,7 @@ linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *fe )
/* Save frontend */
mpegts_input_save((mpegts_input_t*)lfe, m);
htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_info.type));
htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_type));
if (lfe->lfe_satconf) {
htsmsg_t *s = htsmsg_create_map();
linuxdvb_satconf_save(lfe->lfe_satconf, s);
@ -956,7 +1164,7 @@ linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *fe )
}
/* Add to list */
snprintf(id, sizeof(id), "%s #%d", dvb_type2str(lfe->lfe_info.type), lfe->lfe_number);
snprintf(id, sizeof(id), "%s #%d", dvb_type2str(lfe->lfe_type), lfe->lfe_number);
htsmsg_add_msg(fe, id, m);
}

View file

@ -75,7 +75,7 @@ linuxdvb_lnb_standard_freq
( linuxdvb_lnb_t *l, linuxdvb_mux_t *lm )
{
linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l;
int32_t f = (int32_t)lm->lm_tuning.dmc_fe_params.frequency;
int32_t f = (int32_t)lm->lm_tuning.dmc_fe_freq;
if (lnb->lnb_switch && f > lnb->lnb_switch)
f -= lnb->lnb_high;
else
@ -88,7 +88,7 @@ linuxdvb_lnb_standard_band
( linuxdvb_lnb_t *l, linuxdvb_mux_t *lm )
{
linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l;
uint32_t f = lm->lm_tuning.dmc_fe_params.frequency;
uint32_t f = lm->lm_tuning.dmc_fe_freq;
return (lnb->lnb_switch && f > lnb->lnb_switch);
}
@ -97,8 +97,8 @@ linuxdvb_lnb_standard_pol
( linuxdvb_lnb_t *l, linuxdvb_mux_t *lm )
{
dvb_mux_conf_t *dmc = &lm->lm_tuning;
return dmc->dmc_fe_polarisation == POLARISATION_HORIZONTAL ||
dmc->dmc_fe_polarisation == POLARISATION_CIRCULAR_LEFT;
return dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL ||
dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT;
}
static int
@ -118,10 +118,10 @@ linuxdvb_lnb_bandstack_freq
( linuxdvb_lnb_t *l, linuxdvb_mux_t *lm )
{
linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l;
int32_t f = (int32_t)lm->lm_tuning.dmc_fe_params.frequency;
int32_t f = (int32_t)lm->lm_tuning.dmc_fe_freq;
dvb_mux_conf_t *dmc = &lm->lm_tuning;
int pol = dmc->dmc_fe_polarisation == POLARISATION_HORIZONTAL ||
dmc->dmc_fe_polarisation == POLARISATION_CIRCULAR_LEFT;
int pol = dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL ||
dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT;
if (pol)
f -= lnb->lnb_high;
else
@ -134,8 +134,8 @@ linuxdvb_lnb_bandstack_band
( linuxdvb_lnb_t *l, linuxdvb_mux_t *lm )
{
dvb_mux_conf_t *dmc = &lm->lm_tuning;
int pol = dmc->dmc_fe_polarisation == POLARISATION_HORIZONTAL ||
dmc->dmc_fe_polarisation == POLARISATION_CIRCULAR_LEFT;
int pol = dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL ||
dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT;
return pol;
}

View file

@ -44,21 +44,47 @@ extern const idclass_t mpegts_mux_class;
* Generic
*/
/* Macro to defien mux class str get/set */
#define linuxdvb_mux_class_X(c, f, p, l, ...)\
/* Macro to define mux class str get/set */
#define linuxdvb_mux_class_R(c, f, l, ...)\
static const void * \
linuxdvb_mux_##c##_class_##l##_get (void *o)\
{\
static const char *s;\
linuxdvb_mux_t *lm = o;\
s = dvb_##l##2str(lm->lm_tuning.dmc_fe_params.u.f.p);\
s = dvb_##l##2str(lm->lm_tuning.dmc_fe_##f);\
return &s;\
}\
static int \
linuxdvb_mux_##c##_class_##l##_set (void *o, const void *v)\
{\
linuxdvb_mux_t *lm = o;\
lm->lm_tuning.dmc_fe_params.u.f.p = dvb_str2##l ((const char*)v);\
lm->lm_tuning.dmc_fe_##f = dvb_str2##l ((const char*)v);\
return 1;\
}\
static htsmsg_t *\
linuxdvb_mux_##c##_class_##l##_enum (void *o)\
{\
static const int t[] = { __VA_ARGS__ };\
int i;\
htsmsg_t *m = htsmsg_create_list();\
for (i = 0; i < ARRAY_SIZE(t); i++)\
htsmsg_add_str(m, NULL, dvb_##l##2str(t[i]));\
return m;\
}
#define linuxdvb_mux_class_X(c, f, p, l, ...)\
static const void * \
linuxdvb_mux_##c##_class_##l##_get (void *o)\
{\
static const char *s;\
linuxdvb_mux_t *lm = o;\
s = dvb_##l##2str(lm->lm_tuning.u.dmc_fe_##f.p);\
return &s;\
}\
static int \
linuxdvb_mux_##c##_class_##l##_set (void *o, const void *v)\
{\
linuxdvb_mux_t *lm = o;\
lm->lm_tuning.u.dmc_fe_##f.p = dvb_str2##l ((const char*)v);\
return 1;\
}\
static htsmsg_t *\
@ -84,12 +110,8 @@ static const void *
linuxdvb_mux_class_delsys_get (void *o)
{
static const char *s;
#if DVB_VER_ATLEAST(5,0)
linuxdvb_mux_t *lm = o;
s = dvb_delsys2str(lm->lm_tuning.dmc_fe_delsys);
#else
s = NULL;
#endif
return &s;
}
static int
@ -122,50 +144,54 @@ const idclass_t linuxdvb_mux_class =
*/
linuxdvb_mux_class_X(dvbt, ofdm, bandwidth, bw,
BANDWIDTH_AUTO
, BANDWIDTH_8_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_6_MHZ
DVB_BANDWIDTH_AUTO
, DVB_BANDWIDTH_8_MHZ, DVB_BANDWIDTH_7_MHZ
, DVB_BANDWIDTH_6_MHZ
#if DVB_VER_ATLEAST(5,4)
, BANDWIDTH_5_MHZ
, BANDWIDTH_10_MHZ
, BANDWIDTH_1_712_MHZ
, DVB_BANDWIDTH_5_MHZ
, DVB_BANDWIDTH_10_MHZ
, DVB_BANDWIDTH_1_712_MHZ
#endif
);
linuxdvb_mux_class_X(dvbt, ofdm, constellation, qam,
QAM_AUTO, QPSK, QAM_16, QAM_64, QAM_256
linuxdvb_mux_class_R(dvbt, modulation, qam,
DVB_MOD_QAM_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16,
DVB_MOD_QAM_64, DVB_MOD_QAM_256
);
linuxdvb_mux_class_X(dvbt, ofdm, transmission_mode, mode,
TRANSMISSION_MODE_AUTO,
TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K
DVB_TRANSMISSION_MODE_AUTO,
DVB_TRANSMISSION_MODE_2K, DVB_TRANSMISSION_MODE_8K
#if DVB_VER_ATLEAST(5,4)
, TRANSMISSION_MODE_1K, TRANSMISSION_MODE_16K
, TRANSMISSION_MODE_32K
, DVB_TRANSMISSION_MODE_1K, DVB_TRANSMISSION_MODE_16K
, DVB_TRANSMISSION_MODE_32K
#endif
);
linuxdvb_mux_class_X(dvbt, ofdm, guard_interval, guard,
GUARD_INTERVAL_AUTO, GUARD_INTERVAL_1_4,
GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_16,
GUARD_INTERVAL_1_32
DVB_GUARD_INTERVAL_AUTO, DVB_GUARD_INTERVAL_1_4,
DVB_GUARD_INTERVAL_1_8, DVB_GUARD_INTERVAL_1_16,
DVB_GUARD_INTERVAL_1_32
#if DVB_VER_ATLEAST(5,4)
, GUARD_INTERVAL_1_128, GUARD_INTERVAL_19_128
, GUARD_INTERVAL_19_256
, DVB_GUARD_INTERVAL_1_128, DVB_GUARD_INTERVAL_19_128
, DVB_GUARD_INTERVAL_19_256
#endif
);
linuxdvb_mux_class_X(dvbt, ofdm, hierarchy_information, hier,
HIERARCHY_AUTO, HIERARCHY_NONE,
HIERARCHY_1, HIERARCHY_2, HIERARCHY_4
DVB_HIERARCHY_AUTO, DVB_HIERARCHY_NONE,
DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4
);
linuxdvb_mux_class_X(dvbt, ofdm, code_rate_HP, fechi,
FEC_AUTO,
FEC_1_2, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_7_8
DVB_FEC_AUTO,
DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5,
DVB_FEC_5_6, DVB_FEC_7_8
#if DVB_VER_ATLEAST(5,4)
, FEC_3_5
, DVB_FEC_3_5
#endif
);
linuxdvb_mux_class_X(dvbt, ofdm, code_rate_LP, feclo,
FEC_AUTO,
FEC_1_2, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_7_8
DVB_FEC_AUTO,
DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4,
DVB_FEC_4_5, DVB_FEC_5_6, DVB_FEC_7_8
#if DVB_VER_ATLEAST(5,4)
, FEC_3_5
, DVB_FEC_3_5
#endif
);
@ -176,11 +202,11 @@ linuxdvb_mux_dvbt_class_delsys_enum (void *o)
{
htsmsg_t *list = htsmsg_create_list();
#if DVB_VER_ATLEAST(5,0)
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_DVBT));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBT));
#endif
#if DVB_VER_ATLEAST(5,4)
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_DVBT2));
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_TURBO));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBT2));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_TURBO));
#endif
return list;
}
@ -199,7 +225,7 @@ const idclass_t linuxdvb_mux_dvbt_class =
.id = "frequency",
.name = "Frequency (Hz)",
.opts = PO_WRONCE,
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_params.frequency),
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_freq),
},
{
MUX_PROP_STR("bandwidth", "Bandwidth", dvbt, bw, "AUTO")
@ -230,14 +256,16 @@ const idclass_t linuxdvb_mux_dvbt_class =
* DVB-C
*/
linuxdvb_mux_class_X(dvbc, qam, modulation, qam,
QAM_AUTO, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256
linuxdvb_mux_class_R(dvbc, modulation, qam,
DVB_MOD_QAM_AUTO, DVB_MOD_QAM_16, DVB_MOD_QAM_32,
DVB_MOD_QAM_64, DVB_MOD_QAM_128, DVB_MOD_QAM_256
);
linuxdvb_mux_class_X(dvbc, qam, fec_inner, fec,
FEC_AUTO, FEC_NONE,
FEC_1_2, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9
DVB_FEC_AUTO, DVB_FEC_NONE,
DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5,
DVB_FEC_5_6, DVB_FEC_8_9
#if DVB_VER_ATLEAST(5,4)
, FEC_9_10
, DVB_FEC_9_10
#endif
);
@ -248,8 +276,11 @@ linuxdvb_mux_dvbc_class_delsys_enum (void *o)
{
htsmsg_t *list = htsmsg_create_list();
#if DVB_VER_ATLEAST(5,0)
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_DVBC_ANNEX_AC));
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_DVBC_ANNEX_B));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_A));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_B));
#if DVB_VER_ATLEAST(5,3)
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_C));
#endif
#endif
return list;
}
@ -268,14 +299,14 @@ const idclass_t linuxdvb_mux_dvbc_class =
.id = "frequency",
.name = "Frequency (Hz)",
.opts = PO_WRONCE,
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_params.frequency),
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_freq),
},
{
.type = PT_U32,
.id = "symbolrate",
.name = "Symbol Rate (Sym/s)",
.opts = PO_WRONCE,
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_params.u.qam.symbol_rate),
.off = offsetof(linuxdvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate),
},
{
MUX_PROP_STR("constellation", "Constellation", dvbc, qam, "AUTO")
@ -288,11 +319,11 @@ const idclass_t linuxdvb_mux_dvbc_class =
};
linuxdvb_mux_class_X(dvbs, qpsk, fec_inner, fec,
FEC_AUTO, FEC_NONE,
FEC_1_2, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_7_8,
FEC_8_9
DVB_FEC_AUTO, DVB_FEC_NONE,
DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5,
DVB_FEC_5_6, DVB_FEC_7_8, DVB_FEC_8_9
#if DVB_VER_ATLEAST(5,4)
, FEC_3_5, FEC_9_10
, DVB_FEC_3_5, DVB_FEC_9_10
#endif
);
static const void *
@ -300,24 +331,24 @@ linuxdvb_mux_dvbs_class_polarity_get (void *o)
{
static const char *s;
linuxdvb_mux_t *lm = o;
s = dvb_pol2str(lm->lm_tuning.dmc_fe_polarisation);
s = dvb_pol2str(lm->lm_tuning.u.dmc_fe_qpsk.polarisation);
return &s;
}
static int
linuxdvb_mux_dvbs_class_polarity_set (void *o, const void *s)
{
linuxdvb_mux_t *lm = o;
lm->lm_tuning.dmc_fe_polarisation = dvb_str2pol((const char*)s);
lm->lm_tuning.u.dmc_fe_qpsk.polarisation = dvb_str2pol((const char*)s);
return 1;
}
static htsmsg_t *
linuxdvb_mux_dvbs_class_polarity_enum (void *o)
{
htsmsg_t *list = htsmsg_create_list();
htsmsg_add_str(list, NULL, dvb_pol2str(POLARISATION_VERTICAL));
htsmsg_add_str(list, NULL, dvb_pol2str(POLARISATION_HORIZONTAL));
htsmsg_add_str(list, NULL, dvb_pol2str(POLARISATION_CIRCULAR_LEFT));
htsmsg_add_str(list, NULL, dvb_pol2str(POLARISATION_CIRCULAR_RIGHT));
htsmsg_add_str(list, NULL, dvb_pol2str(DVB_POLARISATION_VERTICAL));
htsmsg_add_str(list, NULL, dvb_pol2str(DVB_POLARISATION_HORIZONTAL));
htsmsg_add_str(list, NULL, dvb_pol2str(DVB_POLARISATION_CIRCULAR_LEFT));
htsmsg_add_str(list, NULL, dvb_pol2str(DVB_POLARISATION_CIRCULAR_RIGHT));
return list;
}
@ -325,36 +356,32 @@ static const void *
linuxdvb_mux_dvbs_class_modulation_get ( void *o )
{
static const char *s;
#if DVB_VER_ATLEAST(5,0)
linuxdvb_mux_t *lm = o;
s = dvb_qam2str(lm->lm_tuning.dmc_fe_modulation);
#endif
return &s;
}
static int
linuxdvb_mux_dvbs_class_modulation_set (void *o, const void *s)
{
#if DVB_VER_ATLEAST(5,0)
int mod = dvb_str2qam(s);
linuxdvb_mux_t *lm = o;
if (mod != lm->lm_tuning.dmc_fe_modulation) {
lm->lm_tuning.dmc_fe_modulation = mod;
return 1;
}
#endif
return 0;
}
static htsmsg_t *
linuxdvb_mux_dvbs_class_modulation_list ( void *o )
{
htsmsg_t *list = htsmsg_create_list();
htsmsg_add_str(list, NULL, dvb_qam2str(QAM_AUTO));
htsmsg_add_str(list, NULL, dvb_qam2str(QPSK));
htsmsg_add_str(list, NULL, dvb_qam2str(QAM_16));
htsmsg_add_str(list, NULL, dvb_qam2str(DVB_MOD_QAM_AUTO));
htsmsg_add_str(list, NULL, dvb_qam2str(DVB_MOD_QPSK));
htsmsg_add_str(list, NULL, dvb_qam2str(DVB_MOD_QAM_16));
#if DVB_VER_ATLEAST(5,4)
htsmsg_add_str(list, NULL, dvb_qam2str(PSK_8));
htsmsg_add_str(list, NULL, dvb_qam2str(APSK_16));
htsmsg_add_str(list, NULL, dvb_qam2str(APSK_32));
htsmsg_add_str(list, NULL, dvb_qam2str(DVB_MOD_PSK_8));
htsmsg_add_str(list, NULL, dvb_qam2str(DVB_MOD_APSK_16));
htsmsg_add_str(list, NULL, dvb_qam2str(DVB_MOD_APSK_32));
#endif
return list;
}
@ -379,12 +406,12 @@ static htsmsg_t *
linuxdvb_mux_dvbs_class_rolloff_list ( void *o )
{
htsmsg_t *list = htsmsg_create_list();
htsmsg_add_str(list, NULL, dvb_rolloff2str(ROLLOFF_35));
htsmsg_add_str(list, NULL, dvb_rolloff2str(DVB_ROLLOFF_35));
// Note: this is a bit naff, as the below values are only relevant
// to S2 muxes, but currently have no way to model that
htsmsg_add_str(list, NULL, dvb_rolloff2str(ROLLOFF_20));
htsmsg_add_str(list, NULL, dvb_rolloff2str(ROLLOFF_25));
htsmsg_add_str(list, NULL, dvb_rolloff2str(ROLLOFF_AUTO));
htsmsg_add_str(list, NULL, dvb_rolloff2str(DVB_ROLLOFF_20));
htsmsg_add_str(list, NULL, dvb_rolloff2str(DVB_ROLLOFF_25));
htsmsg_add_str(list, NULL, dvb_rolloff2str(DVB_ROLLOFF_AUTO));
return list;
}
@ -407,9 +434,9 @@ static htsmsg_t *
linuxdvb_mux_dvbs_class_pilot_list ( void *o )
{
htsmsg_t *list = htsmsg_create_list();
htsmsg_add_str(list, NULL, dvb_pilot2str(PILOT_AUTO));
htsmsg_add_str(list, NULL, dvb_pilot2str(PILOT_ON));
htsmsg_add_str(list, NULL, dvb_pilot2str(PILOT_OFF));
htsmsg_add_str(list, NULL, dvb_pilot2str(DVB_PILOT_AUTO));
htsmsg_add_str(list, NULL, dvb_pilot2str(DVB_PILOT_ON));
htsmsg_add_str(list, NULL, dvb_pilot2str(DVB_PILOT_OFF));
return list;
}
#endif
@ -420,10 +447,8 @@ static htsmsg_t *
linuxdvb_mux_dvbs_class_delsys_enum (void *o)
{
htsmsg_t *list = htsmsg_create_list();
#if DVB_VER_ATLEAST(5,0)
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_DVBS));
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_DVBS2));
#endif
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBS));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBS2));
return list;
}
@ -433,8 +458,8 @@ linuxdvb_mux_dvbs_class_orbital_get ( void *o )
static char buf[256], *s = buf;
linuxdvb_mux_t *lm = o;
snprintf(buf, sizeof(buf), "%0.1f%c",
lm->lm_tuning.dmc_fe_orbital_pos / 10.0,
lm->lm_tuning.dmc_fe_orbital_dir);
lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos / 10.0,
lm->lm_tuning.u.dmc_fe_qpsk.orbital_dir);
return &s;
}
@ -450,10 +475,10 @@ linuxdvb_mux_dvbs_class_orbital_set ( void *o, const void *s )
tmp[strlen(tmp)-1] = '\0';
pos = (int)floorf(atof(tmp) * 10.0);
if (pos != lm->lm_tuning.dmc_fe_orbital_pos ||
dir != lm->lm_tuning.dmc_fe_orbital_dir) {
lm->lm_tuning.dmc_fe_orbital_pos = pos;
lm->lm_tuning.dmc_fe_orbital_dir = dir;
if (pos != lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos ||
dir != lm->lm_tuning.u.dmc_fe_qpsk.orbital_dir) {
lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos = pos;
lm->lm_tuning.u.dmc_fe_qpsk.orbital_dir = dir;
save = 1;
}
return save;
@ -473,14 +498,14 @@ const idclass_t linuxdvb_mux_dvbs_class =
.id = "frequency",
.name = "Frequency (kHz)",
.opts = PO_WRONCE,
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_params.frequency),
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_freq),
},
{
.type = PT_U32,
.id = "symbolrate",
.name = "Symbol Rate (Sym/s)",
.opts = PO_WRONCE,
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_params.u.qpsk.symbol_rate),
.off = offsetof(linuxdvb_mux_t, lm_tuning.u.dmc_fe_qpsk.symbol_rate),
},
{
MUX_PROP_STR("polarisation", "Polarisation", dvbs, polarity, NULL)
@ -536,14 +561,14 @@ linuxdvb_mux_atsc_class_delsys_enum (void *o)
{
htsmsg_t *list = htsmsg_create_list();
#if DVB_VER_ATLEAST(5,0)
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_ATSC));
htsmsg_add_str(list, NULL, dvb_delsys2str(SYS_ATSCMH));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_ATSC));
htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_ATSCMH));
#endif
return list;
}
linuxdvb_mux_class_X(atsc, vsb, modulation, qam,
QAM_AUTO, QAM_256, VSB_8);
linuxdvb_mux_class_R(atsc, modulation, qam,
DVB_MOD_QAM_AUTO, DVB_MOD_QAM_256, DVB_MOD_VSB_8);
const idclass_t linuxdvb_mux_atsc_class =
{
@ -559,7 +584,7 @@ const idclass_t linuxdvb_mux_atsc_class =
.id = "frequency",
.name = "Frequency (kHz)",
.opts = PO_WRONCE,
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_params.frequency),
.off = offsetof(linuxdvb_mux_t, lm_tuning.dmc_fe_freq),
},
{
MUX_PROP_STR("modulation", "Modulation", atsc, qam, "AUTO")
@ -588,15 +613,15 @@ linuxdvb_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
{
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
linuxdvb_network_t *ln = (linuxdvb_network_t*)mm->mm_network;
uint32_t freq = lm->lm_tuning.dmc_fe_params.frequency;
uint32_t freq = lm->lm_tuning.dmc_fe_freq;
char pol[2] = { 0 };
if (ln->ln_type == FE_QPSK) {
const char *s = dvb_pol2str(lm->lm_tuning.dmc_fe_polarisation);
if (ln->ln_type == DVB_TYPE_S) {
const char *s = dvb_pol2str(lm->lm_tuning.u.dmc_fe_qpsk.polarisation);
if (s) pol[0] = *s;
freq /= 1000;
} else {
freq /= 1000;
}
}
snprintf(buf, len, "%d%s", freq, pol);
}
@ -641,13 +666,13 @@ linuxdvb_mux_create0
htsmsg_field_t *f;
/* Class */
if (ln->ln_type == FE_QPSK)
if (ln->ln_type == DVB_TYPE_S)
idc = &linuxdvb_mux_dvbs_class;
else if (ln->ln_type == FE_QAM)
else if (ln->ln_type == DVB_TYPE_C)
idc = &linuxdvb_mux_dvbc_class;
else if (ln->ln_type == FE_OFDM)
else if (ln->ln_type == DVB_TYPE_T)
idc = &linuxdvb_mux_dvbt_class;
else if (ln->ln_type == FE_ATSC)
else if (ln->ln_type == DVB_TYPE_ATSC)
idc = &linuxdvb_mux_atsc_class;
else {
tvherror("linuxdvb", "unknown FE type %d", ln->ln_type);
@ -659,10 +684,13 @@ linuxdvb_mux_create0
(mpegts_network_t*)ln, onid, tsid, conf)))
return NULL;
lm = (linuxdvb_mux_t*)mm;
lm->lm_tuning.dmc_fe_type = ln->ln_type;
/* Tuning */
if (dmc)
if (dmc) {
assert(dmc->dmc_fe_type == lm->lm_tuning.dmc_fe_type);
memcpy(&lm->lm_tuning, dmc, sizeof(dvb_mux_conf_t));
}
/* Callbacks */
lm->mm_delete = linuxdvb_mux_delete;
@ -671,10 +699,12 @@ linuxdvb_mux_create0
lm->mm_create_instances = linuxdvb_mux_create_instances;
/* Defaults */
lm->lm_tuning.dmc_fe_params.inversion = INVERSION_AUTO;
if (dmc == NULL) {
lm->lm_tuning.dmc_fe_inversion = DVB_INVERSION_AUTO;
#if DVB_VER_ATLEAST(5,0)
lm->lm_tuning.dmc_fe_pilot = PILOT_AUTO;
lm->lm_tuning.dmc_fe_pilot = DVB_PILOT_AUTO;
#endif
}
/* No config */
if (!conf) return lm;

View file

@ -216,9 +216,9 @@ linuxdvb_network_find_mux
mpegts_mux_t *mm;
LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) {
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
if (abs(lm->lm_tuning.dmc_fe_params.frequency
- dmc->dmc_fe_params.frequency) > LINUXDVB_FREQ_TOL) continue;
if (lm->lm_tuning.dmc_fe_polarisation != dmc->dmc_fe_polarisation) continue;
if (abs(lm->lm_tuning.dmc_fe_freq
- dmc->dmc_fe_freq) > LINUXDVB_FREQ_TOL) continue;
if (lm->lm_tuning.u.dmc_fe_qpsk.polarisation != dmc->u.dmc_fe_qpsk.polarisation) continue;
break;
}
return mm;
@ -247,7 +247,7 @@ linuxdvb_network_create_mux
save = 1;
} else if (mm) {
linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mm;
dmc->dmc_fe_params.frequency = lm->lm_tuning.dmc_fe_params.frequency;
dmc->dmc_fe_freq = lm->lm_tuning.dmc_fe_freq;
// Note: keep original freq, else it can bounce around if diff transponders
// report it slightly differently.
// TODO: Note: should we also leave AUTO settings as is?
@ -312,13 +312,13 @@ linuxdvb_network_create0
ln = calloc(1, sizeof(linuxdvb_network_t));
if (idc == &linuxdvb_network_dvbt_class)
ln->ln_type = FE_OFDM;
ln->ln_type = DVB_TYPE_T;
else if (idc == &linuxdvb_network_dvbc_class)
ln->ln_type = FE_QAM;
ln->ln_type = DVB_TYPE_C;
else if (idc == &linuxdvb_network_dvbs_class)
ln->ln_type = FE_QPSK;
ln->ln_type = DVB_TYPE_S;
else
ln->ln_type = FE_ATSC;
ln->ln_type = DVB_TYPE_ATSC;
/* Create */
if (!(ln = (linuxdvb_network_t*)mpegts_network_create0((void*)ln,

View file

@ -22,6 +22,13 @@
#include "input/mpegts.h"
#include <linux/dvb/version.h>
#define DVB_VER_INT(maj,min) (((maj) << 16) + (min))
#define DVB_VER_ATLEAST(maj, min) \
(DVB_VER_INT(DVB_API_VERSION, DVB_API_VERSION_MINOR) >= DVB_VER_INT(maj, min))
/* Max allowed frequency variation for something to be considered the same */
#define LINUXDVB_FREQ_TOL 2000
@ -75,7 +82,8 @@ struct linuxdvb_frontend
* Frontend info
*/
int lfe_number;
struct dvb_frontend_info lfe_info;
dvb_fe_type_t lfe_type;
char lfe_name[128];
char *lfe_fe_path;
char *lfe_dmx_path;
char *lfe_dvr_path;
@ -93,7 +101,7 @@ struct linuxdvb_frontend
* Tuning
*/
int lfe_locked;
fe_status_t lfe_status;
int lfe_status;
time_t lfe_monitor;
gtimer_t lfe_monitor_timer;
@ -218,7 +226,7 @@ linuxdvb_frontend_t *
linuxdvb_frontend_create
( htsmsg_t *conf, linuxdvb_adapter_t *la, int number,
const char *fe_path, const char *dmx_path, const char *dvr_path,
struct dvb_frontend_info *dfi );
dvb_fe_type_t type, const char *name );
void linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *m );
@ -243,7 +251,7 @@ struct linuxdvb_network
/*
* Network type
*/
fe_type_t ln_type;
dvb_fe_type_t ln_type;
};
void linuxdvb_network_init ( void );

View file

@ -28,6 +28,7 @@
#include <fcntl.h>
#include <assert.h>
#include <math.h>
#include <linux/dvb/frontend.h>
/* **************************************************************************
* Class definition

View file

@ -28,6 +28,7 @@
#include <fcntl.h>
#include <assert.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
static struct linuxdvb_satconf_type *
linuxdvb_satconf_type_find ( const char *type );

View file

@ -28,6 +28,7 @@
#include <fcntl.h>
#include <assert.h>
#include <linux/dvb/dmx.h>
#include <linux/dvb/frontend.h>
/* **************************************************************************
* Class definition

View file

@ -112,14 +112,12 @@ scanfile_load_atsc ( dvb_mux_conf_t *mux, const char *line )
{
char qam[20];
int r;
dvb_frontend_parameters_t *p = &mux->dmc_fe_params;
r = sscanf(line, "%u %s", &p->frequency, qam);
r = sscanf(line, "%u %s", &mux->dmc_fe_freq, qam);
if (r != 2) return 1;
#if DVB_VER_ATLEAST(5,0)
mux->dmc_fe_delsys = SYS_ATSC;
#endif
if ((p->u.vsb.modulation = dvb_str2qam(qam)) == -1) return 1;
mux->dmc_fe_type = DVB_TYPE_ATSC;
mux->dmc_fe_delsys = DVB_SYS_ATSC;
if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1;
return 0;
}
@ -130,31 +128,28 @@ scanfile_load_dvbt ( dvb_mux_conf_t *mux, const char *line )
char bw[20], fec[20], fec2[20], qam[20], mode[20], guard[20], hier[20];
int r;
uint32_t i;
dvb_frontend_parameters_t *p = &mux->dmc_fe_params;
if (*line == '2') {
r = sscanf(line+1, "%u %u %u %10s %10s %10s %10s %10s %10s %10s",
&i, &i, &p->frequency, bw, fec, fec2, qam, mode, guard, hier);
&i, &i, &mux->dmc_fe_freq, bw, fec, fec2, qam,
mode, guard, hier);
if(r != 10) return 1;
#if DVB_VER_ATLEAST(5,4)
mux->dmc_fe_delsys = SYS_DVBT2;
#endif
mux->dmc_fe_delsys = DVB_SYS_DVBT2;
} else {
r = sscanf(line, "%u %10s %10s %10s %10s %10s %10s %10s",
&p->frequency, bw, fec, fec2, qam, mode, guard, hier);
&mux->dmc_fe_freq, bw, fec, fec2, qam, mode, guard, hier);
if(r != 8) return 1;
#if DVB_VER_ATLEAST(5,0)
mux->dmc_fe_delsys = SYS_DVBT;
#endif
mux->dmc_fe_delsys = DVB_SYS_DVBT;
}
if ((p->u.ofdm.bandwidth = dvb_str2bw(bw)) == -1) return 1;
if ((p->u.ofdm.constellation = dvb_str2qam(qam)) == -1) return 1;
if ((p->u.ofdm.code_rate_HP = dvb_str2fec(fec)) == -1) return 1;
if ((p->u.ofdm.code_rate_LP = dvb_str2fec(fec2)) == -1) return 1;
if ((p->u.ofdm.transmission_mode = dvb_str2mode(mode)) == -1) return 1;
if ((p->u.ofdm.guard_interval = dvb_str2guard(guard)) == -1) return 1;
if ((p->u.ofdm.hierarchy_information = dvb_str2hier(hier)) == -1) return 1;
mux->dmc_fe_type = DVB_TYPE_T;
if ((mux->u.dmc_fe_ofdm.bandwidth = dvb_str2bw(bw)) == -1) return 1;
if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1;
if ((mux->u.dmc_fe_ofdm.code_rate_HP = dvb_str2fec(fec)) == -1) return 1;
if ((mux->u.dmc_fe_ofdm.code_rate_LP = dvb_str2fec(fec2)) == -1) return 1;
if ((mux->u.dmc_fe_ofdm.transmission_mode = dvb_str2mode(mode)) == -1) return 1;
if ((mux->u.dmc_fe_ofdm.guard_interval = dvb_str2guard(guard)) == -1) return 1;
if ((mux->u.dmc_fe_ofdm.hierarchy_information = dvb_str2hier(hier)) == -1) return 1;
return 0;
}
@ -164,7 +159,6 @@ scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line )
{
char pol[20], fec[20], qam[20], rolloff[20];
int r, v2 = 0;
dvb_frontend_parameters_t *p = &mux->dmc_fe_params;
if (*line == '2') {
v2 = 2;
@ -172,25 +166,23 @@ scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line )
}
r = sscanf(line, "%u %s %u %s %s %s",
&p->frequency, pol, &p->u.qpsk.symbol_rate,
&mux->dmc_fe_freq, pol, &mux->u.dmc_fe_qpsk.symbol_rate,
fec, rolloff, qam);
if (r < (4+v2)) return 1;
if ((mux->dmc_fe_polarisation = dvb_str2pol(pol)) == -1) return 1;
if ((p->u.qpsk.fec_inner = dvb_str2fec(fec)) == -1) return 1;
#if DVB_VER_ATLEAST(5,0)
mux->dmc_fe_type = DVB_TYPE_S;
if ((mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol)) == -1) return 1;
if ((mux->u.dmc_fe_qpsk.fec_inner = dvb_str2fec(fec)) == -1) return 1;
if (v2) {
mux->dmc_fe_delsys = SYS_DVBS2;
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;
} else {
mux->dmc_fe_delsys = SYS_DVBS;
mux->dmc_fe_rolloff = ROLLOFF_35;
mux->dmc_fe_modulation = QPSK;
mux->dmc_fe_delsys = DVB_SYS_DVBS;
mux->dmc_fe_rolloff = DVB_ROLLOFF_35;
mux->dmc_fe_modulation = DVB_MOD_QPSK;
}
#else
if (v2) return 1;
#endif
return 0;
}
@ -200,17 +192,15 @@ scanfile_load_dvbc ( dvb_mux_conf_t *mux, const char *line )
{
char fec[20], qam[20];
int r;
dvb_frontend_parameters_t *p = &mux->dmc_fe_params;
r = sscanf(line, "%u %u %s %s",
&p->frequency, &p->u.qam.symbol_rate, fec, qam);
&mux->dmc_fe_freq, &mux->u.dmc_fe_qam.symbol_rate, fec, qam);
if(r != 4) return 1;
#if DVB_VER_ATLEAST(5,0)
mux->dmc_fe_delsys = SYS_DVBC_ANNEX_AC;
#endif
if ((p->u.qam.fec_inner = dvb_str2fec(fec)) == -1) return 1;
if ((p->u.qam.modulation = dvb_str2qam(qam)) == -1) return 1;
mux->dmc_fe_type = DVB_TYPE_C;
mux->dmc_fe_delsys = DVB_SYS_DVBC_ANNEX_A;
if ((mux->u.dmc_fe_qam.fec_inner = dvb_str2fec(fec)) == -1) return 1;
if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1;
return 0;
}