From 23967fc02bf1d9a1ecaf06704d024bdc8904e295 Mon Sep 17 00:00:00 2001 From: Haihao Xiang Date: Mon, 25 Jan 2021 14:45:47 +0800 Subject: [PATCH] libs: display: drm: fix set_device_path_from_fd drmGetBusid() (GET_UNIQUE ioctl) won't return a valid bus id when drmSetInterfaceVersion() (SET_VERSION ioctl) hasn't been called(see[1]), so we can't get the right device path. Running test-display will get the error below: ** (test-display:18630): ERROR **: 10:26:00.434: could not create Gst/VA display Calling drmSetInterfaceVersion() before drmGetBusid() can't fix this issue because a special permission is required for SET_VERSION ioctl. This patch retrieves the device path from file descriptor via g_file_read_link() [1] https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/drm_ioctl.c#L48-L104 Part-of: --- gst-libs/gst/vaapi/gstvaapidisplay_drm.c | 79 ++++++++++---------------------- 1 file changed, 23 insertions(+), 56 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c index ecc5a14..d575ffd 100644 --- a/gst-libs/gst/vaapi/gstvaapidisplay_drm.c +++ b/gst-libs/gst/vaapi/gstvaapidisplay_drm.c @@ -41,6 +41,16 @@ #define DEBUG_VAAPI_DISPLAY 1 #include "gstvaapidebug.h" +#ifndef MAXPATHLEN +#if defined(PATH_MAX) +#define MAXPATHLEN PATH_MAX +#elif defined(_PC_PATH_MAX) +#define MAXPATHLEN sysconf(_PC_PATH_MAX) +#else +#define MAXPATHLEN 2048 +#endif +#endif + G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayDRM, gst_vaapi_display_drm, GST_TYPE_VAAPI_DISPLAY); @@ -182,14 +192,9 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) { GstVaapiDisplayDRMPrivate *const priv = GST_VAAPI_DISPLAY_DRM_PRIVATE (display); - const gchar *busid, *path, *str; - gsize busid_length, path_length; - struct udev *udev = NULL; - struct udev_device *device; - struct udev_enumerate *e = NULL; - struct udev_list_entry *l; gboolean success = FALSE; - gint i; + gchar fd_name[MAXPATHLEN]; + GError *error = NULL; g_free (priv->device_path); priv->device_path = NULL; @@ -197,61 +202,23 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device) if (drm_device < 0) goto end; - busid = drmGetBusid (drm_device); - if (!busid) - goto end; - - for (i = 0; allowed_subsystems[i] != NULL; i++) { - busid_length = strlen (allowed_subsystems[i]); - - if (strncmp (busid, allowed_subsystems[i], busid_length) == 0) { - busid += busid_length + 1; - busid_length = strlen (busid); - } - } - - if (allowed_subsystems[i] == NULL) - goto end; - - udev = udev_new (); - if (!udev) - goto end; + sprintf (fd_name, "/proc/%d/fd/%d", getpid (), drm_device); + priv->device_path = g_file_read_link (fd_name, &error); - e = udev_enumerate_new (udev); - if (!e) + if (error) { + g_error_free (error); goto end; + } - udev_enumerate_add_match_subsystem (e, "drm"); - udev_enumerate_scan_devices (e); - udev_list_entry_foreach (l, udev_enumerate_get_list_entry (e)) { - path = udev_list_entry_get_name (l); - str = strstr (path, busid); - if (!str || str <= path || str[-1] != '/') - continue; - - path_length = strlen (path); - if (str + busid_length >= path + path_length) - continue; - if (strncmp (&str[busid_length], "/drm/card", 9) != 0 && - strncmp (&str[busid_length], "/drm/renderD", 12) != 0) - continue; - - device = udev_device_new_from_syspath (udev, path); - if (!device) - continue; - - path = udev_device_get_devnode (device); - priv->device_path = g_strdup (path); - udev_device_unref (device); - break; + if (g_str_has_prefix (priv->device_path, "/dev/dri/card") || + g_str_has_prefix (priv->device_path, "/dev/dri/renderD")) + success = TRUE; + else { + g_free (priv->device_path); + priv->device_path = NULL; } - success = TRUE; end: - if (e) - udev_enumerate_unref (e); - if (udev) - udev_unref (udev); return success; } -- 2.7.4