X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fservices_discovery%2Fudev.c;h=2b513c81e37b11ef92be4597d1af216c27567e6d;hb=6364bc24f805685438bf88357546683c6c457a3d;hp=1e4901b217fc475c2fabde3c139ed9d7fb382e74;hpb=2a2dd55119a03f4e410fca67cc07c7a4e990ed95;p=vlc diff --git a/modules/services_discovery/udev.c b/modules/services_discovery/udev.c index 1e4901b217..2b513c81e3 100644 --- a/modules/services_discovery/udev.c +++ b/modules/services_discovery/udev.c @@ -28,11 +28,17 @@ #include #include #include -#include +#include +#ifdef HAVE_SEARCH_H +# include +#endif #include #include static int OpenV4L (vlc_object_t *); +#ifdef HAVE_ALSA +static int OpenALSA (vlc_object_t *); +#endif static int OpenDisc (vlc_object_t *); static void Close (vlc_object_t *); static int vlc_sd_probe_Open (vlc_object_t *); @@ -41,14 +47,23 @@ 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") - +#ifdef HAVE_ALSA + 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") +#endif add_submodule () set_shortname (N_("Discs")) set_description (N_("Discs")) @@ -75,7 +90,12 @@ static int vlc_sd_probe_Open (vlc_object_t *obj) { vlc_sd_probe_Add (probe, "v4l{longname=\"Video capture\"}", N_("Video capture"), SD_CAT_DEVICES); - vlc_sd_probe_Add (probe, "disc{longname=\"Discs\"}", N_("Discs"), SD_CAT_MYCOMPUTER); +#ifdef HAVE_ALSA + vlc_sd_probe_Add (probe, "alsa{longname=\"Audio capture\"}", + N_("Audio capture"), SD_CAT_DEVICES); +#endif + vlc_sd_probe_Add (probe, "disc{longname=\"Discs\"}", N_("Discs"), + SD_CAT_DEVICES); udev_monitor_unref (mon); } udev_unref (udev); @@ -377,6 +397,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) { @@ -420,6 +441,97 @@ int OpenV4L (vlc_object_t *obj) return Open (obj, &subsys); } + +#ifdef HAVE_ALSA +/*** Advanced Linux Sound Architecture support ***/ +#include + +static int alsa_get_device (struct udev_device *dev, unsigned *restrict pcard, + unsigned *restrict pdevice) +{ + const char *node = udev_device_get_devpath (dev); + char type; + + node = strrchr (node, '/'); + if (node == NULL) + return -1; + if (sscanf (node, "/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 = NULL; + unsigned card, device; + + if (alsa_get_device (dev, &card, &device)) + return NULL; + + char card_name[4 + 3 * sizeof (int)]; + snprintf (card_name, sizeof (card_name), "hw:%u", card); + + snd_ctl_t *ctl; + if (snd_ctl_open (&ctl, card_name, 0)) + return NULL; + + snd_pcm_info_t *pcm_info; + snd_pcm_info_alloca (&pcm_info); + snd_pcm_info_set_device (pcm_info, device); + snd_pcm_info_set_subdevice (pcm_info, 0); + snd_pcm_info_set_stream (pcm_info, SND_PCM_STREAM_CAPTURE); + if (snd_ctl_pcm_info (ctl, pcm_info)) + goto out; + + name = strdup (snd_pcm_info_get_name (pcm_info)); +out: + snd_ctl_close (ctl); + return name; +} + +static char *alsa_get_cat (struct udev_device *dev) +{ + const char *vnd; + + dev = udev_device_get_parent (dev); + if (dev == NULL) + return NULL; + + vnd = udev_device_get_property_value (dev, "ID_VENDOR_FROM_DATABASE"); + if (vnd == NULL) + /* FIXME: USB may take time to settle... the parent device */ + vnd = udev_device_get_property_value (dev, "ID_BUS"); + return vnd ? strdup (vnd) : NULL; +} + +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); +} +#endif /* HAVE_ALSA */ + + /*** Discs support ***/ static char *disc_get_mrl (struct udev_device *dev) { @@ -430,19 +542,18 @@ static char *disc_get_mrl (struct udev_device *dev) return NULL; /* Ignore non-optical block devices */ val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_STATE"); - if ((val == NULL) || !strcmp (val, "blank")) + if (val && !strcmp (val, "blank")) return NULL; /* ignore empty drives and virgin recordable discs */ - const char *scheme = "file"; + const char *scheme = NULL; val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); if (val && atoi (val)) scheme = "cdda"; /* Audio CD rather than file system */ -#if 0 /* we can use file:// for DVDs */ val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_DVD"); if (val && atoi (val)) scheme = "dvd"; -#endif + val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_BD"); if (val && atoi (val)) scheme = "bd"; @@ -452,12 +563,13 @@ static char *disc_get_mrl (struct udev_device *dev) scheme = "hddvd"; #endif - val = udev_device_get_devnode (dev); - char *mrl; + /* We didn't get any property that could tell we have optical disc + that we can play */ + if (scheme == NULL) + return NULL; - if (asprintf (&mrl, "%s://%s", scheme, val) == -1) - mrl = NULL; - return mrl; + val = udev_device_get_devnode (dev); + return make_URI (val, scheme); } static char *disc_get_name (struct udev_device *dev) @@ -467,23 +579,39 @@ static char *disc_get_name (struct udev_device *dev) static char *disc_get_cat (struct udev_device *dev) { - const char *val; - const char *cat = "Unknown"; + struct udev_list_entry *list, *entry; - val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_CD"); - if (val && atoi (val)) - cat = "CD"; - val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_DVD"); - if (val && atoi (val)) - cat = "DVD"; - val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_BD"); - if (val && atoi (val)) - cat = "Blue-ray disc"; - val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_HDDVD"); - if (val && atoi (val)) - cat = "HD DVD"; + list = udev_device_get_properties_list_entry (dev); + if (unlikely(list == NULL)) + return NULL; + + const char *cat = NULL; + udev_list_entry_foreach (entry, list) + { + const char *name = udev_list_entry_get_name (entry); + + if (strncmp (name, "ID_CDROM_MEDIA_", 15)) + continue; + if (!atoi (udev_list_entry_get_value (entry))) + continue; + name += 15; + + if (!strncmp (name, "CD", 2)) + cat = N_("CD"); + else if (!strncmp (name, "DVD", 3)) + cat = N_("DVD"); + else if (!strncmp (name, "BD", 2)) + cat = N_("Blu-Ray"); + else if (!strncmp (name, "HDDVD", 5)) + cat = N_("HD DVD"); + + if (cat != NULL) + break; + } - return strdup (cat); + if (cat == NULL) + cat = N_("Unknown type"); + return strdup (vlc_gettext (cat)); } int OpenDisc (vlc_object_t *obj)