]> git.sesse.net Git - vlc/blobdiff - modules/services_discovery/udev.c
udev: rudimentary ALSA capture support
[vlc] / modules / services_discovery / udev.c
index 0a85c88dfaf1821d993eda3d67eabe29541b59db..7168684b4ceec29dfa7c015cf23534811dec0e9c 100644 (file)
 #include <errno.h>
 
 static int OpenV4L (vlc_object_t *);
+static int OpenALSA (vlc_object_t *);
 static int OpenDisc (vlc_object_t *);
 static void Close (vlc_object_t *);
+static int vlc_sd_probe_Open (vlc_object_t *);
 
 /*
  * Module descriptor
  */
 vlc_module_begin ()
-    set_shortname (N_("Devices"))
-    set_description (N_("Capture devices"))
+    set_shortname (N_("Video capture"))
+    set_description (N_("Video capture (Video4Linux)"))
     set_category (CAT_PLAYLIST)
     set_subcategory (SUBCAT_PLAYLIST_SD)
     set_capability ("services_discovery", 0)
     set_callbacks (OpenV4L, Close)
     add_shortcut ("v4l")
 
+    add_submodule ()
+    set_shortname (N_("Audio capture"))
+    set_description (N_("Audio capture (ALSA)"))
+    set_category (CAT_PLAYLIST)
+    set_subcategory (SUBCAT_PLAYLIST_SD)
+    set_capability ("services_discovery", 0)
+    set_callbacks (OpenALSA, Close)
+    add_shortcut ("alsa")
+
     add_submodule ()
     set_shortname (N_("Discs"))
     set_description (N_("Discs"))
@@ -57,8 +68,33 @@ vlc_module_begin ()
     set_callbacks (OpenDisc, Close)
     add_shortcut ("disc")
 
+    VLC_SD_PROBE_SUBMODULE
+
 vlc_module_end ()
 
+static int vlc_sd_probe_Open (vlc_object_t *obj)
+{
+    vlc_probe_t *probe = (vlc_probe_t *)obj;
+
+    struct udev *udev = udev_new ();
+    if (udev == NULL)
+        return VLC_PROBE_CONTINUE;
+
+    struct udev_monitor *mon = udev_monitor_new_from_netlink (udev, "udev");
+    if (mon != NULL)
+    {
+        vlc_sd_probe_Add (probe, "v4l{longname=\"Video capture\"}",
+                          N_("Video capture"), SD_CAT_DEVICES);
+        vlc_sd_probe_Add (probe, "alsa{longname=\"Audio capture\"}",
+                          N_("Audio capture"), SD_CAT_DEVICES);
+        vlc_sd_probe_Add (probe, "disc{longname=\"Discs\"}", N_("Discs"),
+                          SD_CAT_MYCOMPUTER);
+        udev_monitor_unref (mon);
+    }
+    udev_unref (udev);
+    return VLC_PROBE_CONTINUE;
+}
+
 struct device
 {
     dev_t devnum; /* must be first */
@@ -354,6 +390,7 @@ static char *decode_property (struct udev_device *dev, const char *name)
     return decode (udev_device_get_property_value (dev, name));
 }
 
+
 /*** Video4Linux support ***/
 static bool is_v4l_legacy (struct udev_device *dev)
 {
@@ -397,6 +434,74 @@ int OpenV4L (vlc_object_t *obj)
     return Open (obj, &subsys);
 }
 
+
+/*** Advanced Linux Sound Architecture support ***/
+static int alsa_get_device (struct udev_device *dev, unsigned *restrict pcard,
+                            unsigned *restrict pdevice)
+{
+    const char *node = udev_device_get_devnode (dev);
+    char type;
+
+    if (node == NULL)
+        return -1;
+    if (sscanf (node, "/dev/snd/pcmC%uD%u%c", pcard, pdevice, &type) < 3)
+        return -1;
+    if (type != 'c')
+        return -1;
+    return 0;
+}
+
+
+static char *alsa_get_mrl (struct udev_device *dev)
+{
+    /* Determine media location */
+    char *mrl;
+    unsigned card, device;
+
+    if (alsa_get_device (dev, &card, &device))
+        return NULL;
+
+    if (asprintf (&mrl, "alsa://plughw:%u,%u", card, device) == -1)
+        mrl = NULL;
+    return mrl;
+}
+
+static char *alsa_get_name (struct udev_device *dev)
+{
+    char *name;
+    unsigned card, device;
+
+    if (alsa_get_device (dev, &card, &device))
+        return NULL;
+
+    if (asprintf (&name, _("Device %u"), device) == -1)
+        name = NULL;
+    return name;
+}
+
+static char *alsa_get_cat (struct udev_device *dev)
+{
+    char *name;
+    unsigned card, device;
+
+    if (alsa_get_device (dev, &card, &device))
+        return NULL;
+
+    if (asprintf (&name, _("Card %u"), card) == -1)
+        name = NULL;
+    return name;
+}
+
+int OpenALSA (vlc_object_t *obj)
+{
+    static const struct subsys subsys = {
+        "sound", alsa_get_mrl, alsa_get_name, alsa_get_cat, ITEM_TYPE_CARD,
+    };
+
+    return Open (obj, &subsys);
+}
+
+
 /*** Discs support ***/
 static char *disc_get_mrl (struct udev_device *dev)
 {