Commit 3aae0170 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Linux DVB: run-time fallback from 5.5 to 5.0 frontend probing

This enables running VLC to run on a kernel that does not support
version 5.5 of the Linux DVB API (i.e. Linux < 3.3), even if VLC was
compiled with more recent kernel headers.

Unfortunately, this is of limited use. In practice, the running kernel
version is more likely to be newer than the kernel headers, than to be
older. In that case, VLC will print an explicit error.
parent 0c9d696d
...@@ -447,7 +447,7 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -447,7 +447,7 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
if (ioctl (fd, FE_GET_PROPERTY, &props) < 0) if (ioctl (fd, FE_GET_PROPERTY, &props) < 0)
{ {
msg_Err (d->obj, "cannot enumerate frontend systems: %m"); msg_Err (d->obj, "cannot enumerate frontend systems: %m");
return 0; goto legacy;
} }
static const unsigned systab[] = { static const unsigned systab[] = {
...@@ -489,6 +489,10 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -489,6 +489,10 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
msg_Dbg (d->obj, " system %u", sys); msg_Dbg (d->obj, " system %u", sys);
systems |= systab[sys]; systems |= systab[sys];
} }
return systems;
legacy:
props.num = 1;
#else #else
struct dtv_property prop[1] = { struct dtv_property prop[1] = {
{ .cmd = DTV_API_VERSION }, { .cmd = DTV_API_VERSION },
...@@ -497,7 +501,8 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -497,7 +501,8 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
.num = 1, .num = 1,
.props = prop .props = prop
}; };
unsigned systems = 0;
#endif
if (ioctl (fd, FE_GET_PROPERTY, &props) < 0) if (ioctl (fd, FE_GET_PROPERTY, &props) < 0)
{ {
msg_Err (d->obj, "unsupported kernel DVB version 3 or older (%m)"); msg_Err (d->obj, "unsupported kernel DVB version 3 or older (%m)");
...@@ -507,6 +512,15 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -507,6 +512,15 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
msg_Dbg (d->obj, "probing frontend (kernel API v%u.%u, user API v%u.%u)", msg_Dbg (d->obj, "probing frontend (kernel API v%u.%u, user API v%u.%u)",
prop[0].u.data >> 8, prop[0].u.data & 0xFF, prop[0].u.data >> 8, prop[0].u.data & 0xFF,
DVB_API_VERSION, DVB_API_VERSION_MINOR); DVB_API_VERSION, DVB_API_VERSION_MINOR);
#if !DVBv5(5)
/* Some delivery systems cannot be detected without the DVB API v5.5.
* To run correctly on recent kernels (Linux >= 3.3),
* VLC needs to be compiled with up-to-date kernel headers. */
if ((prop[0].u.data >> 8) > 5
|| ((prop[0].u.data >> 8) == 5 && (prop[0].u.data & 0xFF) >= 5))
msg_Err (d->obj, "obsolete user API version running on a new kernel");
msg_Info (d->obj, "please recompile "PACKAGE_NAME" "PACKAGE_VERSION);
#endif
struct dvb_frontend_info info; struct dvb_frontend_info info;
if (ioctl (fd, FE_GET_INFO, &info) < 0) if (ioctl (fd, FE_GET_INFO, &info) < 0)
{ {
...@@ -523,8 +537,6 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -523,8 +537,6 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
info.symbol_rate_min, info.symbol_rate_max); info.symbol_rate_min, info.symbol_rate_max);
msg_Dbg (d->obj, " (%"PRIu32" tolerance)", info.symbol_rate_tolerance); msg_Dbg (d->obj, " (%"PRIu32" tolerance)", info.symbol_rate_tolerance);
unsigned systems;
/* DVB first generation and ATSC */ /* DVB first generation and ATSC */
switch (info.type) switch (info.type)
{ {
...@@ -533,7 +545,6 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -533,7 +545,6 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
case FE_OFDM: systems = DVB_T; break; case FE_OFDM: systems = DVB_T; break;
case FE_ATSC: systems = ATSC | CQAM; break; case FE_ATSC: systems = ATSC | CQAM; break;
default: default:
systems = 0;
msg_Err (d->obj, "unknown frontend type %u", info.type); msg_Err (d->obj, "unknown frontend type %u", info.type);
} }
...@@ -552,7 +563,7 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd) ...@@ -552,7 +563,7 @@ static unsigned dvb_probe_frontend (dvb_device_t *d, int fd)
/* ISDB (only terrestrial before DVBv5.5) */ /* ISDB (only terrestrial before DVBv5.5) */
if (info.type == FE_OFDM) if (info.type == FE_OFDM)
systems |= ISDB_T; systems |= ISDB_T;
#endif
return systems; return systems;
} }
......
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