]> git.sesse.net Git - vlc/blobdiff - modules/access/dtv/linux.c
SRTP: remove dedicated gcrypt initialization, use VLC one
[vlc] / modules / access / dtv / linux.c
index b6c22f17af1468886bf3634242446c09b8f87cdc..9e353dd4142026764a526ef5852a3a8bb40969de 100644 (file)
@@ -489,35 +489,54 @@ static int dvb_find_frontend (dvb_device_t *d, fe_type_t type, fe_caps_t caps)
     return -1;
 }
 
-const delsys_t *dvb_guess_system (dvb_device_t *d)
+/**
+ * Detects supported delivery systems.
+ * @return a bit mask of supported systems (zero on failure)
+ */
+unsigned dvb_enum_systems (dvb_device_t *d)
 {
-    if (d->frontend == -1)
+    unsigned systems = 0;
+
+    for (unsigned n = 0; n < 256; n++)
     {
-        d->frontend = dvb_open_node (d->dir, "frontend", 0, O_RDWR);
-        if (d->frontend == -1)
+        int fd = dvb_open_node (d->dir, "frontend", n, O_RDWR);
+        if (fd == -1)
         {
-            msg_Err (d->obj, "cannot access frontend %u; %m", 0);
-            return NULL;
+            if (errno == ENOENT)
+                break; /* all frontends already enumerated */
+            msg_Err (d->obj, "cannot access frontend %u; %m", n);
+            continue;
         }
 
-        if (ioctl (d->frontend, FE_GET_INFO, &d->info) < 0)
+        struct dvb_frontend_info info;
+        if (ioctl (fd, FE_GET_INFO, &info) < 0)
         {
-            msg_Err (d->obj, "cannot get frontend %u info: %m", 0);
-            close (d->frontend);
-            d->frontend = -1;
-            return NULL;
+            msg_Err (d->obj, "cannot get frontend %u info: %m", n);
+            close (fd);
+            continue;
         }
-    }
+        close (fd);
 
-    //bool v2 = d->info.caps & FE_CAN_2G_MODULATION;
-    switch (d->info.type)
-    {
-        case FE_QPSK: return /*v2 ? &dvbs2 :*/ &dvbs;
-        case FE_QAM:  return &dvbc;
-        case FE_OFDM: return /*v2 ? &dvbt2 :*/ &dvbt;
-        case FE_ATSC: return &atsc;
+        /* 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 NULL;
+    return systems;
 }
 
 float dvb_get_signal_strength (dvb_device_t *d)
@@ -615,7 +634,7 @@ int dvb_set_dvbc (dvb_device_t *d, uint32_t freq, const char *modstr,
         return -1;
     return dvb_set_props (d, 6, DTV_CLEAR, 0,
                           DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_AC,
-                          DTV_FREQUENCY, freq * 1000, DTV_MODULATION, mod,
+                          DTV_FREQUENCY, freq, DTV_MODULATION, mod,
                           DTV_SYMBOL_RATE, srate, DTV_INNER_FEC, fec);
 }
 
@@ -633,9 +652,11 @@ static unsigned dvb_parse_polarization (char pol)
     return dvb_parse_int (pol, tab, 5, SEC_VOLTAGE_OFF);
 }
 
-int dvb_set_sec (dvb_device_t *d, uint32_t freq, char pol,
+int dvb_set_sec (dvb_device_t *d, uint64_t freq_Hz, char pol,
                  uint32_t lowf, uint32_t highf, uint32_t switchf)
 {
+    uint32_t freq = freq_Hz / 1000;
+
     /* Always try to configure high voltage, but only warn on enable failure */
     int val = var_InheritBool (d->obj, "dvb-high-voltage");
     if (ioctl (d->frontend, FE_ENABLE_HIGH_LNB_VOLTAGE, &val) < 0 && val)
@@ -656,10 +677,10 @@ int dvb_set_sec (dvb_device_t *d, uint32_t freq, char pol,
              {  2500,  2700,  3650,     0 }, /* S band */
              {   950,  2150,     0,     0 }, /* adjusted IF (L band) */
         };
-        uint_fast16_t mhz = freq / 1000;
+        uint_fast16_t mHz = freq / 1000;
 
         for (size_t i = 0; i < sizeof (tab) / sizeof (tab[0]); i++)
-             if (mhz >= tab[i].min && mhz <= tab[i].max)
+             if (mHz >= tab[i].min && mHz <= tab[i].max)
              {
                  lowf = tab[i].low * 1000;
                  highf = tab[i].high * 1000;
@@ -732,8 +753,10 @@ known:
     return dvb_set_props (d, 2, DTV_FREQUENCY, freq, DTV_TONE, tone);
 }
 
-int dvb_set_dvbs (dvb_device_t *d, uint32_t freq, uint32_t srate, uint32_t fec)
+int dvb_set_dvbs (dvb_device_t *d, uint64_t freq_Hz,
+                  uint32_t srate, uint32_t fec)
 {
+    uint32_t freq = freq_Hz / 1000;
     fec = dvb_parse_fec (fec);
 
     if (dvb_find_frontend (d, FE_QPSK, FE_IS_STUPID))
@@ -743,9 +766,10 @@ int dvb_set_dvbs (dvb_device_t *d, uint32_t freq, uint32_t srate, uint32_t fec)
                           DTV_INNER_FEC, fec);
 }
 
-int dvb_set_dvbs2 (dvb_device_t *d, uint32_t freq, const char *modstr,
+int dvb_set_dvbs2 (dvb_device_t *d, uint64_t freq_Hz, const char *modstr,
                    uint32_t srate, uint32_t fec, int pilot, int rolloff)
 {
+    uint32_t freq = freq_Hz / 1000;
     unsigned mod = dvb_parse_modulation (modstr, QPSK);
     fec = dvb_parse_fec (fec);