mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-20 19:10:18 +00:00
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: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/412>
This commit is contained in:
parent
c4e76d6fc5
commit
23967fc02b
1 changed files with 23 additions and 56 deletions
|
@ -41,6 +41,16 @@
|
||||||
#define DEBUG_VAAPI_DISPLAY 1
|
#define DEBUG_VAAPI_DISPLAY 1
|
||||||
#include "gstvaapidebug.h"
|
#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,
|
G_DEFINE_TYPE_WITH_PRIVATE (GstVaapiDisplayDRM, gst_vaapi_display_drm,
|
||||||
GST_TYPE_VAAPI_DISPLAY);
|
GST_TYPE_VAAPI_DISPLAY);
|
||||||
|
|
||||||
|
@ -182,14 +192,9 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device)
|
||||||
{
|
{
|
||||||
GstVaapiDisplayDRMPrivate *const priv =
|
GstVaapiDisplayDRMPrivate *const priv =
|
||||||
GST_VAAPI_DISPLAY_DRM_PRIVATE (display);
|
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;
|
gboolean success = FALSE;
|
||||||
gint i;
|
gchar fd_name[MAXPATHLEN];
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
g_free (priv->device_path);
|
g_free (priv->device_path);
|
||||||
priv->device_path = NULL;
|
priv->device_path = NULL;
|
||||||
|
@ -197,61 +202,23 @@ set_device_path_from_fd (GstVaapiDisplay * display, gint drm_device)
|
||||||
if (drm_device < 0)
|
if (drm_device < 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
busid = drmGetBusid (drm_device);
|
sprintf (fd_name, "/proc/%d/fd/%d", getpid (), drm_device);
|
||||||
if (!busid)
|
priv->device_path = g_file_read_link (fd_name, &error);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
g_error_free (error);
|
||||||
goto end;
|
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)
|
if (g_str_has_prefix (priv->device_path, "/dev/dri/card") ||
|
||||||
goto end;
|
g_str_has_prefix (priv->device_path, "/dev/dri/renderD"))
|
||||||
|
|
||||||
udev = udev_new ();
|
|
||||||
if (!udev)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
e = udev_enumerate_new (udev);
|
|
||||||
if (!e)
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
else {
|
||||||
|
g_free (priv->device_path);
|
||||||
|
priv->device_path = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (e)
|
|
||||||
udev_enumerate_unref (e);
|
|
||||||
if (udev)
|
|
||||||
udev_unref (udev);
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue