Commit 19a4b35b authored by François Cartegnie's avatar François Cartegnie 🤞

access: dtv: simplify/regroup setup and drop delsys

We'll need to be able to change setup between tunings
(Ex: mixed T2/T transponder)
parent fea861ef
......@@ -428,24 +428,18 @@ struct access_sys_t
{
dvb_device_t *dev;
uint8_t signal_poll;
tuner_setup_t pf_setup;
};
typedef struct delsys
{
int (*setup) (vlc_object_t *, dvb_device_t *, uint64_t freq);
/* TODO: scan stuff */
} delsys_t;
static const delsys_t dvbc, dvbs, dvbs2, dvbt, dvbt2;
static const delsys_t isdbc, isdbs, isdbt;
static const delsys_t atsc, cqam;
static block_t *Read (access_t *);
static int Control (access_t *, int, va_list);
static const delsys_t *GuessSystem (const char *, dvb_device_t *);
static int Tune (vlc_object_t *, dvb_device_t *, const delsys_t *, uint64_t);
static dtv_delivery_t GuessSystem (const char *, dvb_device_t *);
static dtv_delivery_t GetDeliveryByScheme(const char *psz_scheme);
static int Tune (vlc_object_t *, dvb_device_t *, tuner_setup_t, uint64_t);
static uint64_t var_InheritFrequency (vlc_object_t *);
tuner_setup_t dtv_get_delivery_tuner_setup( dtv_delivery_t d );
static int Open (vlc_object_t *obj)
{
access_t *access = (access_t *)obj;
......@@ -464,13 +458,17 @@ static int Open (vlc_object_t *obj)
sys->dev = dev;
sys->signal_poll = 0;
sys->pf_setup = NULL;
access->p_sys = sys;
uint64_t freq = var_InheritFrequency (obj);
if (freq != 0)
{
const delsys_t *delsys = GuessSystem (access->psz_access, dev);
if (delsys == NULL || Tune (obj, dev, delsys, freq))
dtv_delivery_t d = GuessSystem (access->psz_access, dev);
if(d != DTV_DELIVERY_NONE)
sys->pf_setup = dtv_get_delivery_tuner_setup(d);
if (sys->pf_setup == NULL || Tune (obj, dev, sys->pf_setup, freq))
{
msg_Err (obj, "tuning to %"PRIu64" Hz failed", freq);
vlc_dialog_display_error (obj, N_("Digital broadcasting"),
......@@ -603,82 +601,11 @@ static int Control (access_t *access, int query, va_list args)
/*** Generic tuning ***/
/** Determines which delivery system to use. */
static const delsys_t *GuessSystem (const char *scheme, dvb_device_t *dev)
{
/* Specific delivery system is specified */
if (!strcasecmp (scheme, "atsc"))
return &atsc;
if (!strcasecmp (scheme, "cqam"))
return &cqam;
if (!strcasecmp (scheme, "dvb-c"))
return &dvbc;
if (!strcasecmp (scheme, "dvb-s"))
return &dvbs;
if (!strcasecmp (scheme, "dvb-s2"))
return &dvbs2;
if (!strcasecmp (scheme, "dvb-t"))
return &dvbt;
if (!strcasecmp (scheme, "dvb-t2"))
return &dvbt2;
if (!strcasecmp (scheme, "isdb-c"))
return &isdbc;
if (!strcasecmp (scheme, "isdb-s"))
return &isdbs;
if (!strcasecmp (scheme, "isdb-t"))
return &isdbt;
/* If the demodulator supports 2G, we cannot guess whether
* 1G or 2G is intended. For backward compatibility, 1G is assumed
* (this is not a limitation of Linux DVB). We will probably need something
* smarter when 2G (semi automatic) scanning is implemented. */
unsigned systems = dvb_enum_systems (dev);
/* Only wave carrier is specified */
if (!strcasecmp (scheme, "cable"))
{
if (systems & DTV_DELIVERY_DVB_C)
return &dvbc;
if (systems & DTV_DELIVERY_CQAM)
return &cqam;
if (systems & DTV_DELIVERY_ISDB_C)
return &isdbc;
}
if (!strcasecmp (scheme, "satellite"))
{
if (systems & DTV_DELIVERY_DVB_S)
return &dvbs;
if (systems & DTV_DELIVERY_ISDB_S)
return &isdbs;
}
if (!strcasecmp (scheme, "terrestrial"))
{
if (systems & DTV_DELIVERY_DVB_T)
return &dvbc;
if (systems & DTV_DELIVERY_ATSC)
return &cqam;
if (systems & DTV_DELIVERY_ISDB_T)
return &isdbt;
}
/* Only standards family or nothing is specified */
if (systems & DTV_DELIVERY_DVB_C)
return &dvbc;
if (systems & DTV_DELIVERY_DVB_S)
return &dvbs;
if (systems & DTV_DELIVERY_DVB_T)
return &dvbt;
if (systems & DTV_DELIVERY_ATSC)
return &atsc;
return NULL;
}
/** Set parameters and tune the device */
static int Tune (vlc_object_t *obj, dvb_device_t *dev, const delsys_t *delsys,
static int Tune (vlc_object_t *obj, dvb_device_t *dev, tuner_setup_t pf_setup,
uint64_t freq)
{
if (delsys->setup (obj, dev, freq)
if (pf_setup(obj, dev, freq)
|| dvb_set_inversion (dev, var_InheritInteger (obj, "dvb-inversion"))
|| dvb_tune (dev))
return VLC_EGENERIC;
......@@ -801,8 +728,6 @@ static int atsc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return dvb_set_atsc (dev, freq, mod);
}
static const delsys_t atsc = { .setup = atsc_setup };
static int cqam_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
{
const char *mod = var_InheritModulation (obj, "dvb-modulation");
......@@ -810,9 +735,6 @@ static int cqam_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return dvb_set_cqam (dev, freq, mod);
}
static const delsys_t cqam = { .setup = cqam_setup };
/*** DVB-C ***/
static int dvbc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
{
......@@ -823,9 +745,6 @@ static int dvbc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return dvb_set_dvbc (dev, freq, mod, srate, fec);
}
static const delsys_t dvbc = { .setup = dvbc_setup };
/*** DVB-S ***/
static char var_InheritPolarization (vlc_object_t *obj)
{
......@@ -890,10 +809,6 @@ static int dvbs2_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return ret;
}
static const delsys_t dvbs = { .setup = dvbs_setup };
static const delsys_t dvbs2 = { .setup = dvbs2_setup };
/*** DVB-T ***/
static int dvbt_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
{
......@@ -920,10 +835,6 @@ static int dvbt2_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return dvb_set_dvbt2 (dev, freq, mod, fec, bw, tx, guard, plp);
}
static const delsys_t dvbt = { .setup = dvbt_setup };
static const delsys_t dvbt2 = { .setup = dvbt2_setup };
/*** ISDB-C ***/
static int isdbc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
{
......@@ -934,9 +845,6 @@ static int isdbc_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return dvb_set_isdbc (dev, freq, mod, srate, fec);
}
static const delsys_t isdbc = { .setup = isdbc_setup };
/*** ISDB-S ***/
static int isdbs_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
{
......@@ -948,9 +856,6 @@ static int isdbs_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return ret;
}
static const delsys_t isdbs = { .setup = isdbs_setup };
/*** ISDB-T ***/
static int isdbt_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
{
......@@ -978,4 +883,90 @@ static int isdbt_setup (vlc_object_t *obj, dvb_device_t *dev, uint64_t freq)
return dvb_set_isdbt (dev, freq, bw, tx, guard, layers);
}
static const delsys_t isdbt = { .setup = isdbt_setup };
static const struct
{
const dtv_delivery_t delivery;
tuner_setup_t const pf_setup;
const char *psz_scheme;
} delsys_mappings[] = {
{ DTV_DELIVERY_ATSC, atsc_setup, "atsc" },
{ DTV_DELIVERY_CQAM, cqam_setup, "cqam" },
{ DTV_DELIVERY_DVB_C, dvbc_setup, "dvb-c" },
{ DTV_DELIVERY_DVB_C2, dvbc_setup, "dvb-c2" },
{ DTV_DELIVERY_DVB_S, dvbs_setup, "dvb-s" },
{ DTV_DELIVERY_DVB_S2, dvbs2_setup, "dvb-s2" },
{ DTV_DELIVERY_DVB_T, dvbt_setup, "dvb-t" },
{ DTV_DELIVERY_DVB_T2, dvbt2_setup, "dvb-t2" },
{ DTV_DELIVERY_ISDB_C, isdbc_setup, "isdb-c" },
{ DTV_DELIVERY_ISDB_S, isdbs_setup, "isdb-s" },
{ DTV_DELIVERY_ISDB_T, isdbt_setup, "isdb-t" },
};
tuner_setup_t dtv_get_delivery_tuner_setup( dtv_delivery_t d )
{
for (size_t i=0; i<ARRAY_SIZE(delsys_mappings); i++)
{
if ( delsys_mappings[i].delivery == d )
return delsys_mappings[i].pf_setup;
}
return NULL;
}
static dtv_delivery_t GetDeliveryByScheme(const char *psz_scheme)
{
for (size_t i=0; i<ARRAY_SIZE(delsys_mappings); i++)
{
if(!strcasecmp(psz_scheme, delsys_mappings[i].psz_scheme))
return delsys_mappings[i].delivery;
}
return DTV_DELIVERY_NONE;
}
static inline dtv_delivery_t GetSingleDelivery( dtv_delivery_t d )
{
if( d == 0 )
return DTV_DELIVERY_NONE;
else
return 1 << ctz( d );
}
/** Determines which delivery system to use. */
static dtv_delivery_t GuessSystem (const char *scheme, dvb_device_t *dev)
{
/* Specific delivery system is specified */
dtv_delivery_t d = GetDeliveryByScheme(scheme);
if(d != DTV_DELIVERY_NONE)
return d;
/* If the demodulator supports 2G, we cannot guess whether
* 1G or 2G is intended. For backward compatibility, 1G is assumed
* (this is not a limitation of Linux DVB). We will probably need something
* smarter when 2G (semi automatic) scanning is implemented. */
unsigned systems = dvb_enum_systems (dev);
systems &= ~DTV_DELGROUP_G2;
if( systems )
{
/* Only wave carrier is specified */
if (!strcasecmp (scheme, "cable"))
{
return GetSingleDelivery(systems & DTV_DELGROUP_CABLE);
}
else if (!strcasecmp (scheme, "satellite"))
{
return GetSingleDelivery(systems & DTV_DELGROUP_SAT);
}
else if (!strcasecmp (scheme, "terrestrial"))
{
return GetSingleDelivery(systems & DTV_DELGROUP_TERRES);
}
else
{
/* Only standards family or nothing is specified */
return GetSingleDelivery(systems);
}
}
return DTV_DELIVERY_NONE;
}
......@@ -26,7 +26,8 @@
extern "C" {
# endif
enum {
typedef enum {
DTV_DELIVERY_NONE = 0x00000000,
DTV_DELIVERY_ATSC = 0x00000001,
DTV_DELIVERY_CQAM = 0x00000002,
......@@ -40,10 +41,25 @@ enum {
DTV_DELIVERY_ISDB_C = 0x00001000,
DTV_DELIVERY_ISDB_S = 0x00002000,
DTV_DELIVERY_ISDB_T = 0x00004000,
};
} dtv_delivery_t;
#define DTV_DELGROUP_G2 ( DTV_DELIVERY_DVB_C2 | DTV_DELIVERY_DVB_T2 | \
DTV_DELIVERY_DVB_S2 )
#define DTV_DELGROUP_SAT ( DTV_DELIVERY_DVB_S | DTV_DELIVERY_DVB_S2 | \
DTV_DELIVERY_ISDB_S )
#define DTV_DELGROUP_CABLE ( DTV_DELIVERY_DVB_C | DTV_DELIVERY_DVB_C2 | \
DTV_DELIVERY_CQAM | DTV_DELIVERY_ISDB_C )
#define DTV_DELGROUP_TERRES ( DTV_DELIVERY_DVB_T | DTV_DELIVERY_DVB_T2 | \
DTV_DELIVERY_ATSC | DTV_DELIVERY_ISDB_T )
typedef struct dvb_device dvb_device_t;
typedef int (* tuner_setup_t) (vlc_object_t *, dvb_device_t *, uint64_t freq);
tuner_setup_t dtv_get_delivery_tuner_setup( dtv_delivery_t );
dvb_device_t *dvb_open (vlc_object_t *obj);
void dvb_close (dvb_device_t *);
ssize_t dvb_read (dvb_device_t *, void *, size_t, int);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment