mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
v4lsrc: optional support for device probing with gudev
Enumerate v4l devices using gudev if available. Fixes bug #583640.
This commit is contained in:
parent
94baad7490
commit
0f29d71a7d
3 changed files with 108 additions and 8 deletions
23
configure.ac
23
configure.ac
|
@ -436,6 +436,29 @@ AG_GST_CHECK_FEATURE(GST_V4L, [Video 4 Linux], video4linux, [
|
|||
fi
|
||||
])
|
||||
|
||||
# Optional gudev for device probing
|
||||
AC_ARG_WITH([gudev],
|
||||
AC_HELP_STRING([--with-gudev],
|
||||
[device detection with gudev]),
|
||||
[],
|
||||
[with_gudev=check])
|
||||
if test x$HAVE_GST_V4L = xyes; then
|
||||
if test x$with_gudev != xno; then
|
||||
PKG_CHECK_MODULES(GUDEV, [ gudev-1.0 >= 143 ],
|
||||
[ have_gudev=yes
|
||||
AC_DEFINE(HAVE_GUDEV, 1,
|
||||
[Whether gudev is available for device detection])
|
||||
AC_DEFINE([G_UDEV_API_IS_SUBJECT_TO_CHANGE], 1, [I know the API is subject to change.])
|
||||
], [
|
||||
have_gudev=no
|
||||
])
|
||||
else
|
||||
have_gudev=no
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(GUDEV_CFLAGS)
|
||||
AC_SUBST(GUDEV_LIBS)
|
||||
|
||||
dnl *** ext plug-ins ***
|
||||
dnl keep this list sorted alphabetically !
|
||||
|
||||
|
|
|
@ -22,10 +22,12 @@ libgstvideo4linux_la_SOURCES = \
|
|||
# gstv4lmjpegsink.c v4lmjpegsink_calls.c
|
||||
|
||||
libgstvideo4linux_la_CFLAGS = \
|
||||
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS)
|
||||
$(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(X_CFLAGS) \
|
||||
$(GUDEV_CFLAGS)
|
||||
libgstvideo4linux_la_LIBADD = \
|
||||
$(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-$(GST_MAJORMINOR).la \
|
||||
$(GST_BASE_LIBS) $(GST_LIBS) $(xv_libs)
|
||||
$(GST_BASE_LIBS) $(GST_LIBS) $(xv_libs) \
|
||||
$(GUDEV_LIBS)
|
||||
libgstvideo4linux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||
libgstvideo4linux_la_LIBTOOLFLAGS = --tag=disable-static
|
||||
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#include <gst/interfaces/propertyprobe.h>
|
||||
|
||||
#ifdef HAVE_GUDEV
|
||||
#include <gudev/gudev.h>
|
||||
#endif
|
||||
|
||||
#include "v4l_calls.h"
|
||||
#include "gstv4ltuner.h"
|
||||
#ifdef HAVE_XVIDEO
|
||||
|
@ -48,6 +52,8 @@ enum
|
|||
PROP_FLAGS
|
||||
};
|
||||
|
||||
GST_DEBUG_CATEGORY (v4lelement_debug);
|
||||
#define GST_CAT_DEFAULT v4lelement_debug
|
||||
|
||||
static void gst_v4lelement_init_interfaces (GType type);
|
||||
|
||||
|
@ -108,20 +114,76 @@ gst_v4l_probe_get_properties (GstPropertyProbe * probe)
|
|||
return list;
|
||||
}
|
||||
|
||||
static gboolean init = FALSE;
|
||||
static GList *devices = NULL;
|
||||
|
||||
#ifdef HAVE_GUDEV
|
||||
static gboolean
|
||||
gst_v4l_class_probe_devices_with_udev (GstV4lElementClass * klass,
|
||||
gboolean check)
|
||||
{
|
||||
GUdevClient *client;
|
||||
GList *item;
|
||||
|
||||
if (!check) {
|
||||
while (devices) {
|
||||
gchar *device = devices->data;
|
||||
devices = g_list_remove (devices, device);
|
||||
g_free (device);
|
||||
}
|
||||
|
||||
GST_INFO ("Enumerating video4linux devices from udev");
|
||||
client = g_udev_client_new (NULL);
|
||||
if (!client) {
|
||||
GST_WARNING ("Failed to initialize gudev client");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
item = g_udev_client_query_by_subsystem (client, "video4linux");
|
||||
while (item) {
|
||||
GUdevDevice *device = item->data;
|
||||
gchar *devnode = g_strdup (g_udev_device_get_device_file (device));
|
||||
gint api = g_udev_device_get_property_as_int (device, "ID_V4L_VERSION");
|
||||
GST_INFO ("Found new device: %s, API: %d", devnode, api);
|
||||
/* Append v4l1 devices only. If api is 0 probably v4l_id has
|
||||
been stripped out of the current udev installation, append
|
||||
anyway */
|
||||
if (api == 0) {
|
||||
GST_WARNING
|
||||
("Couldn't retrieve ID_V4L_VERSION, silly udev installation?");
|
||||
}
|
||||
if ((api == 1 || api == 0)) {
|
||||
devices = g_list_append (devices, devnode);
|
||||
} else {
|
||||
g_free (devnode);
|
||||
}
|
||||
g_object_unref (device);
|
||||
item = item->next;
|
||||
}
|
||||
g_list_free (item);
|
||||
init = TRUE;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (client) {
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
klass->devices = devices;
|
||||
|
||||
return init;
|
||||
}
|
||||
#endif /* HAVE_GUDEV */
|
||||
|
||||
static gboolean
|
||||
gst_v4l_class_probe_devices (GstV4lElementClass * klass, gboolean check)
|
||||
{
|
||||
static gboolean init = FALSE;
|
||||
static GList *devices = NULL;
|
||||
|
||||
if (!check) {
|
||||
gchar *dev_base[] = { "/dev/video", "/dev/v4l/video", NULL };
|
||||
gint base, n, fd;
|
||||
|
||||
while (devices) {
|
||||
GList *item = devices;
|
||||
gchar *device = item->data;
|
||||
|
||||
gchar *device = devices->data;
|
||||
devices = g_list_remove (devices, device);
|
||||
g_free (device);
|
||||
}
|
||||
|
@ -163,7 +225,12 @@ gst_v4l_probe_probe_property (GstPropertyProbe * probe,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE:
|
||||
#ifdef HAVE_GUDEV
|
||||
if (!gst_v4l_class_probe_devices_with_udev (klass, FALSE))
|
||||
gst_v4l_class_probe_devices (klass, FALSE);
|
||||
#else /* !HAVE_GUDEV */
|
||||
gst_v4l_class_probe_devices (klass, FALSE);
|
||||
#endif /* HAVE_GUDEV */
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec);
|
||||
|
@ -180,6 +247,11 @@ gst_v4l_probe_needs_probe (GstPropertyProbe * probe,
|
|||
|
||||
switch (prop_id) {
|
||||
case PROP_DEVICE:
|
||||
#ifdef HAVE_GUDEV
|
||||
ret = !gst_v4l_class_probe_devices_with_udev (klass, FALSE);
|
||||
#else /* !HAVE_GUDEV */
|
||||
ret = !gst_v4l_class_probe_devices (klass, TRUE);
|
||||
#endif /* HAVE_GUDEV */
|
||||
ret = !gst_v4l_class_probe_devices (klass, TRUE);
|
||||
break;
|
||||
default:
|
||||
|
@ -319,6 +391,9 @@ gst_v4lelement_base_init (gpointer g_class)
|
|||
GstV4lElementClass *klass = GST_V4LELEMENT_CLASS (g_class);
|
||||
|
||||
klass->devices = NULL;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (v4lelement_debug, "v4lelement", 0,
|
||||
"V4L Base Class debug");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue