• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2020 Igalia, S.L.
3  *     Author: Víctor Jáquez <vjaquez@igalia.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "gstvadevice.h"
26 
27 #if HAVE_GUDEV
28 #include <gudev/gudev.h>
29 #endif
30 
31 #define GST_CAT_DEFAULT gstva_debug
32 GST_DEBUG_CATEGORY_EXTERN (gstva_debug);
33 
34 GST_DEFINE_MINI_OBJECT_TYPE (GstVaDevice, gst_va_device);
35 
36 static void
gst_va_device_free(GstVaDevice * device)37 gst_va_device_free (GstVaDevice * device)
38 {
39   gst_clear_object (&device->display);
40   g_free (device->render_device_path);
41   g_free (device);
42 }
43 
44 static GstVaDevice *
gst_va_device_new(GstVaDisplay * display,const gchar * render_device_path)45 gst_va_device_new (GstVaDisplay * display, const gchar * render_device_path)
46 {
47   GstVaDevice *device = g_new0 (GstVaDevice, 1);
48 
49   gst_mini_object_init (GST_MINI_OBJECT_CAST (device), 0, GST_TYPE_VA_DEVICE,
50       NULL, NULL, (GstMiniObjectFreeFunction) gst_va_device_free);
51 
52   /* take ownership */
53   device->display = display;
54   device->render_device_path = g_strdup (render_device_path);
55 
56   return device;
57 }
58 
59 static gint
compare_device_path(gconstpointer a,gconstpointer b,gpointer user_data)60 compare_device_path (gconstpointer a, gconstpointer b, gpointer user_data)
61 {
62   const GstVaDevice *pa = a, *pb = b;
63 
64   return strcmp (pa->render_device_path, pb->render_device_path);
65 }
66 
67 #if HAVE_GUDEV
68 GList *
gst_va_device_find_devices(void)69 gst_va_device_find_devices (void)
70 {
71   GUdevClient *client;
72   GList *udev_devices, *dev;
73   GQueue devices = G_QUEUE_INIT;
74 
75   client = g_udev_client_new (NULL);
76   udev_devices = g_udev_client_query_by_subsystem (client, "drm");
77 
78   for (dev = udev_devices; dev; dev = g_list_next (dev)) {
79     GstVaDisplay *dpy;
80     GUdevDevice *udev = (GUdevDevice *) dev->data;
81     const gchar *path = g_udev_device_get_device_file (udev);
82     const gchar *name = g_udev_device_get_name (udev);
83 
84     if (!path || !g_str_has_prefix (name, "renderD")) {
85       GST_LOG ("Ignoring %s in %s", name, path);
86       continue;
87     }
88 
89     if (!(dpy = gst_va_display_drm_new_from_path (path)))
90       continue;
91 
92     GST_INFO ("Found VA-API device: %s", path);
93     g_queue_push_head (&devices, gst_va_device_new (dpy, path));
94   }
95 
96   g_queue_sort (&devices, compare_device_path, NULL);
97   g_list_free_full (udev_devices, g_object_unref);
98   g_object_unref (client);
99 
100   return devices.head;
101 }
102 #else
103 GList *
gst_va_device_find_devices(void)104 gst_va_device_find_devices (void)
105 {
106   GstVaDisplay *dpy;
107   GQueue devices = G_QUEUE_INIT;
108   gchar path[64];
109   guint i;
110 
111   for (i = 0; i < 8; i++) {
112     g_snprintf (path, sizeof (path), "/dev/dri/renderD%d", 128 + i);
113     if (!g_file_test (path, G_FILE_TEST_EXISTS))
114       continue;
115 
116     if (!(dpy = gst_va_display_drm_new_from_path (path)))
117       continue;
118 
119     GST_INFO ("Found VA-API device: %s", path);
120     g_queue_push_head (&devices, gst_va_device_new (dpy, path));
121   }
122 
123   g_queue_sort (&devices, compare_device_path, NULL);
124   return devices.head;
125 }
126 #endif
127 
128 void
gst_va_device_list_free(GList * devices)129 gst_va_device_list_free (GList * devices)
130 {
131   g_list_free_full (devices, (GDestroyNotify) gst_mini_object_unref);
132 }
133