[vlc-commits] Linux DVB: factorize and revector frontend probing
Rémi Denis-Courmont
git at videolan.org
Tue Mar 13 17:24:16 CET 2012
vlc/vlc-2.0 | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Mar 11 17:01:20 2012 +0200| [8c011362f036ffd0c01a9f9dd2ed237541747619] | committer: Rémi Denis-Courmont
Linux DVB: factorize and revector frontend probing
(cherry picked from commit a9862530656860c69d51d8a8fbe75baae0149e91)
> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.0.git/?a=commit;h=8c011362f036ffd0c01a9f9dd2ed237541747619
---
modules/access/dtv/linux.c | 139 +++++++++++++++++++++++--------------------
1 files changed, 74 insertions(+), 65 deletions(-)
diff --git a/modules/access/dtv/linux.c b/modules/access/dtv/linux.c
index 5afdc15..9ad2310 100644
--- a/modules/access/dtv/linux.c
+++ b/modules/access/dtv/linux.c
@@ -184,7 +184,7 @@ struct dvb_device
#ifdef HAVE_DVBPSI
cam_t *cam;
#endif
- struct dvb_frontend_info info;
+ unsigned systems;
bool budget;
//size_t buffer_size;
};
@@ -430,12 +430,66 @@ void dvb_remove_pid (dvb_device_t *d, uint16_t pid)
#endif
}
+/** Enumerates the systems supported by one frontend */
+static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
+{
+ struct dvb_frontend_info info;
+
+ if (ioctl (fd, FE_GET_INFO, &info) < 0)
+ {
+ msg_Err (d->obj, "cannot get frontend info: %m");
+ return 0;
+ }
+
+ msg_Dbg (d->obj, "probing frontend: %s", info.name);
+ msg_Dbg (d->obj, " type %u, capabilities 0x%08X", info.type, info.caps);
+ msg_Dbg (d->obj, " frequencies %10"PRIu32" to %10"PRIu32,
+ info.frequency_min, info.frequency_max);
+ msg_Dbg (d->obj, " (%"PRIu32" tolerance, %"PRIu32" per step)",
+ info.frequency_tolerance, info.frequency_stepsize);
+ msg_Dbg (d->obj, " bauds rates %10"PRIu32" to %10"PRIu32,
+ info.symbol_rate_min, info.symbol_rate_max);
+ msg_Dbg (d->obj, " (%"PRIu32" tolerance)", info.symbol_rate_tolerance);
+
+ unsigned systems;
+
+ /* DVB first generation and ATSC */
+ switch (info.type)
+ {
+ case FE_QPSK: systems = DVB_S; break;
+ case FE_QAM: systems = DVB_C; break;
+ case FE_OFDM: systems = DVB_T; break;
+ case FE_ATSC: systems = ATSC; break;
+ default:
+ systems = 0;
+ msg_Err (d->obj, "unknown frontend type %u", info.type);
+ }
+
+ /* DVB 2nd generation */
+ switch (info.type)
+ {
+ case FE_QPSK:
+ case FE_QAM:
+ case FE_OFDM:
+ if (info.caps & FE_CAN_2G_MODULATION)
+ systems |= systems << 1; /* DVB_foo -> DVB_foo|DVB_foo2 */
+ default:
+ break;
+ }
+
+ /* ISDB (only terrestrial before DVBv5.5) */
+ if (info.type == FE_OFDM)
+ systems |= ISDB_T;
+
+ return systems;
+}
+
/** Finds a frontend of the correct type */
-static int dvb_find_frontend (dvb_device_t *d, fe_type_t type, fe_caps_t caps)
+static int dvb_find_frontend (dvb_device_t *d, unsigned system)
{
if (d->frontend != -1)
{
- if (d->info.type == type || (d->info.caps & caps) == caps)
+ if (d->systems & system)
return 0; /* already got an adequate frontend */
close (d->frontend);
@@ -453,35 +507,15 @@ static int dvb_find_frontend (dvb_device_t *d, fe_type_t type, fe_caps_t caps)
continue;
}
- if (ioctl (fd, FE_GET_INFO, &d->info) < 0)
+ d->systems = dvb_probe_frontend (d, fd);
+ if (d->systems & system)
{
- msg_Err (d->obj, "cannot get frontend %u info: %m", n);
- goto skip;
- }
-
- msg_Dbg (d->obj, "probing frontend %u: %s", n, d->info.name);
- msg_Dbg (d->obj, " type %u, capabilities 0x%08X", d->info.type,
- d->info.caps);
- msg_Dbg (d->obj, " frequencies %10"PRIu32" to %10"PRIu32,
- d->info.frequency_min, d->info.frequency_max);
- msg_Dbg (d->obj, " (%"PRIu32" tolerance, %"PRIu32" per step)",
- d->info.frequency_tolerance, d->info.frequency_stepsize);
- msg_Dbg (d->obj, " bauds rates %10"PRIu32" to %10"PRIu32,
- d->info.symbol_rate_min, d->info.symbol_rate_max);
- msg_Dbg (d->obj, " (%"PRIu32" tolerance)",
- d->info.symbol_rate_tolerance);
-
- if (d->info.type != type || (d->info.caps & caps) != caps)
- {
- msg_Dbg (d->obj, "skipping frontend %u: wrong type", n);
- goto skip;
+ msg_Dbg (d->obj, "selected frontend %u", n);
+ d->frontend = fd;
+ return 0;
}
- msg_Dbg (d->obj, "selected frontend %u", n);
- d->frontend = fd;
- return 0;
-
- skip:
+ msg_Dbg (d->obj, "skipping frontend %u: wrong type", n);
close (fd);
}
@@ -508,33 +542,8 @@ unsigned dvb_enum_systems (dvb_device_t *d)
continue;
}
- struct dvb_frontend_info info;
- if (ioctl (fd, FE_GET_INFO, &info) < 0)
- {
- msg_Err (d->obj, "cannot get frontend %u info: %m", n);
- close (fd);
- continue;
- }
+ systems |= dvb_probe_frontend (d, fd);
close (fd);
-
- /* Linux DVB lacks detection for non-DVB/non-ATSC demods */
- static const unsigned types[] = {
- [FE_QPSK] = DVB_S,
- [FE_QAM] = DVB_C,
- [FE_OFDM] = DVB_T,
- [FE_ATSC] = ATSC,
- };
-
- if (((unsigned)info.type) >= sizeof (types) / sizeof (types[0]))
- {
- msg_Err (d->obj, "unknown frontend type %u", info.type);
- continue;
- }
-
- unsigned sys = types[info.type];
- if (info.caps & FE_CAN_2G_MODULATION)
- sys |= sys << 1; /* DVB_foo -> DVB_foo|DVB_foo2 */
- systems |= sys;
}
return systems;
}
@@ -631,7 +640,7 @@ int dvb_set_dvbc (dvb_device_t *d, uint32_t freq, const char *modstr,
unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
fec = dvb_parse_fec (fec);
- if (dvb_find_frontend (d, FE_QAM, FE_IS_STUPID))
+ if (dvb_find_frontend (d, DVB_C))
return -1;
return dvb_set_props (d, 6, DTV_CLEAR, 0,
#if DVBv5(5)
@@ -764,7 +773,7 @@ int dvb_set_dvbs (dvb_device_t *d, uint64_t freq_Hz,
uint32_t freq = freq_Hz / 1000;
fec = dvb_parse_fec (fec);
- if (dvb_find_frontend (d, FE_QPSK, FE_IS_STUPID))
+ if (dvb_find_frontend (d, DVB_S))
return -1;
return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS,
DTV_FREQUENCY, freq, DTV_SYMBOL_RATE, srate,
@@ -793,7 +802,7 @@ int dvb_set_dvbs2 (dvb_device_t *d, uint64_t freq_Hz, const char *modstr,
default: rolloff = PILOT_AUTO; break;
}
- if (dvb_find_frontend (d, FE_QPSK, FE_CAN_2G_MODULATION))
+ if (dvb_find_frontend (d, DVB_S2))
return -1;
return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBS2,
DTV_FREQUENCY, freq, DTV_MODULATION, mod,
@@ -877,7 +886,7 @@ int dvb_set_dvbt (dvb_device_t *d, uint32_t freq, const char *modstr,
guard = dvb_parse_guard (guard);
hierarchy = dvb_parse_hierarchy (hierarchy);
- if (dvb_find_frontend (d, FE_OFDM, FE_IS_STUPID))
+ if (dvb_find_frontend (d, DVB_T))
return -1;
return dvb_set_props (d, 10, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT,
DTV_FREQUENCY, freq, DTV_MODULATION, mod,
@@ -899,7 +908,7 @@ int dvb_set_dvbt2 (dvb_device_t *d, uint32_t freq, const char *modstr,
transmit_mode = dvb_parse_transmit_mode (transmit_mode);
guard = dvb_parse_guard (guard);
- if (dvb_find_frontend (d, FE_OFDM, FE_CAN_2G_MODULATION))
+ if (dvb_find_frontend (d, DVB_T2))
return -1;
return dvb_set_props (d, 8, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_DVBT2,
DTV_FREQUENCY, freq, DTV_MODULATION, mod,
@@ -923,7 +932,7 @@ int dvb_set_isdbc (dvb_device_t *d, uint32_t freq, const char *modstr,
unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
fec = dvb_parse_fec (fec);
- if (dvb_find_frontend (d, FE_QAM, FE_IS_STUPID))
+ if (dvb_find_frontend (d, ISDB_C))
return -1;
return dvb_set_props (d, 6, DTV_CLEAR, 0,
#if DVBv5(5)
@@ -943,7 +952,7 @@ int dvb_set_isdbs (dvb_device_t *d, uint64_t freq_Hz, uint16_t ts_id)
#if DVBv5(1)
uint32_t freq = freq_Hz / 1000;
- if (dvb_find_frontend (d, FE_QPSK, FE_IS_STUPID))
+ if (dvb_find_frontend (d, ISDB_S))
return -1;
return dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBS,
DTV_FREQUENCY, freq,
@@ -986,7 +995,7 @@ int dvb_set_isdbt (dvb_device_t *d, uint32_t freq, uint32_t bandwidth,
transmit_mode = dvb_parse_transmit_mode (transmit_mode);
guard = dvb_parse_guard (guard);
- if (dvb_find_frontend (d, FE_OFDM, FE_IS_STUPID))
+ if (dvb_find_frontend (d, ISDB_T))
return -1;
if (dvb_set_props (d, 5, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ISDBT,
DTV_FREQUENCY, freq, DTV_BANDWIDTH_HZ, bandwidth,
@@ -1011,7 +1020,7 @@ int dvb_set_atsc (dvb_device_t *d, uint32_t freq, const char *modstr)
{
unsigned mod = dvb_parse_modulation (modstr, VSB_8);
- if (dvb_find_frontend (d, FE_ATSC, FE_IS_STUPID))
+ if (dvb_find_frontend (d, ATSC))
return -1;
return dvb_set_props (d, 4, DTV_CLEAR, 0, DTV_DELIVERY_SYSTEM, SYS_ATSC,
DTV_FREQUENCY, freq, DTV_MODULATION, mod);
@@ -1021,7 +1030,7 @@ int dvb_set_cqam (dvb_device_t *d, uint32_t freq, const char *modstr)
{
unsigned mod = dvb_parse_modulation (modstr, QAM_AUTO);
- if (dvb_find_frontend (d, FE_QAM, FE_IS_STUPID))
+ if (dvb_find_frontend (d, ATSC))
return -1;
return dvb_set_props (d, 4, DTV_CLEAR, 0,
DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B,
More information about the vlc-commits
mailing list