udev: partial support for optical discs
authorRémi Denis-Courmont <remi@remlab.net>
Fri, 16 Oct 2009 19:09:06 +0000 (22:09 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Fri, 16 Oct 2009 19:20:29 +0000 (22:20 +0300)
It should work with CDDA, DVD and Blu-rays, but I only tested DVD.

FIXME: This does not detect media change (eject/insert) properly yet.

modules/services_discovery/udev.c

index b23c363..9215008 100644 (file)
@@ -32,6 +32,7 @@
 #include <errno.h>
 
 static int OpenV4L (vlc_object_t *);
+static int OpenDisc (vlc_object_t *);
 static void Close (vlc_object_t *);
 
 /*
@@ -44,8 +45,17 @@ vlc_module_begin ()
     set_subcategory (SUBCAT_PLAYLIST_SD)
     set_capability ("services_discovery", 0)
     set_callbacks (OpenV4L, Close)
+    add_shortcut ("v4l")
+
+    add_submodule ()
+    set_shortname (N_("Discs"))
+    set_description (N_("Discs"))
+    set_category (CAT_PLAYLIST)
+    set_subcategory (SUBCAT_PLAYLIST_SD)
+    set_capability ("services_discovery", 0)
+    set_callbacks (OpenDisc, Close)
+    add_shortcut ("disc")
 
-    add_shortcut ("udev")
 vlc_module_end ()
 
 struct subsys
@@ -335,3 +345,78 @@ int OpenV4L (vlc_object_t *obj)
 
     return Open (obj, &subsys);
 }
+
+/*** Discs support ***/
+static char *disc_get_mrl (struct udev_device *dev)
+{
+    const char *val;
+
+    val = udev_device_get_property_value (dev, "ID_CDROM");
+    if (val == NULL)
+        return NULL; /* Ignore non-optical block devices */
+
+    val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_STATE");
+    if ((val == NULL) || !strcmp (val, "blank"))
+        return NULL; /* ignore empty drives and virgin recordable discs */
+
+    const char *scheme = "file";
+    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";
+#ifdef LOL
+    val = udev_device_get_property_value (dev, "ID_CDROM_MEDIA_HDDVD");
+    if (val && atoi (val))
+        scheme = "hddvd";
+#endif
+
+    val = udev_device_get_devnode (dev);
+    char *mrl;
+
+    if (asprintf (&mrl, "%s://%s", scheme, val) == -1)
+        mrl = NULL;
+    return mrl;
+}
+
+static char *disc_get_name (struct udev_device *dev)
+{
+    return decode_property (dev, "ID_FS_LABEL_ENC");
+}
+
+static char *disc_get_cat (struct udev_device *dev)
+{
+    const char *val;
+    const char *cat = "Unknown";
+
+    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";
+
+    return strdup (cat);
+}
+
+int OpenDisc (vlc_object_t *obj)
+{
+    static const struct subsys subsys = {
+        "block", disc_get_mrl, disc_get_name, disc_get_cat,
+    };
+
+    return Open (obj, &subsys);
+}