summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac7
-rw-r--r--sys/v4l2/Makefile.am2
-rw-r--r--sys/v4l2/gstv4l2.c3
-rw-r--r--sys/v4l2/gstv4l2devicemonitor.c509
-rw-r--r--sys/v4l2/gstv4l2devicemonitor.h101
5 files changed, 622 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index c9d51b10d..f05434c56 100644
--- a/configure.ac
+++ b/configure.ac
@@ -518,6 +518,13 @@ AC_ARG_WITH([gudev],
AS_HELP_STRING([--with-gudev],[device detection with gudev]),
[],
[with_gudev=check])
+if test x$with_gudev != xno; then
+ PKG_CHECK_MODULES(GUDEV, [ gudev-1.0 >= 147 ],
+ [ AC_DEFINE(HAVE_GUDEV, 1,
+ [Whether gudev is available for device detection])
+ ])
+fi
+
AC_SUBST(GUDEV_CFLAGS)
AC_SUBST(GUDEV_LIBS)
diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am
index 4e62c6eb0..df3f98049 100644
--- a/sys/v4l2/Makefile.am
+++ b/sys/v4l2/Makefile.am
@@ -4,6 +4,7 @@ include $(top_srcdir)/common/gst-glib-gen.mak
libgstvideo4linux2_la_SOURCES = gstv4l2.c \
gstv4l2colorbalance.c \
+ gstv4l2devicemonitor.c \
gstv4l2object.c \
gstv4l2bufferpool.c \
gstv4l2sink.c \
@@ -38,6 +39,7 @@ libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
noinst_HEADERS = \
gstv4l2bufferpool.h \
gstv4l2colorbalance.h \
+ gstv4l2devicemonitor.h \
gstv4l2object.h \
gstv4l2sink.h \
gstv4l2src.h \
diff --git a/sys/v4l2/gstv4l2.c b/sys/v4l2/gstv4l2.c
index dd44069c0..a5361d748 100644
--- a/sys/v4l2/gstv4l2.c
+++ b/sys/v4l2/gstv4l2.c
@@ -34,6 +34,7 @@
#include "gstv4l2sink.h"
#include "gstv4l2radio.h"
#include "gstv4l2videodec.h"
+#include "gstv4l2devicemonitor.h"
/* #include "gstv4l2jpegsrc.h" */
/* #include "gstv4l2mjpegsrc.h" */
/* #include "gstv4l2mjpegsink.h" */
@@ -53,6 +54,8 @@ plugin_init (GstPlugin * plugin)
!gst_element_register (plugin, "v4l2radio", GST_RANK_NONE,
GST_TYPE_V4L2RADIO) ||
!gst_v4l2_video_dec_register (plugin) ||
+ !gst_device_monitor_register (plugin, "v4l2monitor",
+ GST_RANK_PRIMARY, GST_TYPE_V4L2_DEVICE_MONITOR) ||
/* !gst_element_register (plugin, "v4l2jpegsrc", */
/* GST_RANK_NONE, GST_TYPE_V4L2JPEGSRC) || */
/* !gst_element_register (plugin, "v4l2mjpegsrc", */
diff --git a/sys/v4l2/gstv4l2devicemonitor.c b/sys/v4l2/gstv4l2devicemonitor.c
new file mode 100644
index 000000000..db2f974f1
--- /dev/null
+++ b/sys/v4l2/gstv4l2devicemonitor.c
@@ -0,0 +1,509 @@
+/* GStreamer
+ * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstv4l2devicemonitor.c: V4l2 device probing and monitoring
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstv4l2devicemonitor.h"
+
+#include <string.h>
+#include <sys/stat.h>
+
+#include <gst/gst.h>
+
+#include "gstv4l2object.h"
+#include "v4l2_calls.h"
+
+#ifdef HAVE_GUDEV
+#include <gudev/gudev.h>
+#endif
+
+static GstV4l2Device *gst_v4l2_device_new (const gchar * device_path,
+ const gchar * device_name, GstCaps * caps, GstV4l2DeviceType type);
+
+
+G_DEFINE_TYPE (GstV4l2DeviceMonitor, gst_v4l2_device_monitor,
+ GST_TYPE_DEVICE_MONITOR);
+
+static void gst_v4l2_device_monitor_finalize (GObject * object);
+static GList *gst_v4l2_device_monitor_probe (GstDeviceMonitor * monitor);
+
+#if HAVE_GUDEV
+static gboolean gst_v4l2_device_monitor_start (GstDeviceMonitor * monitor);
+static void gst_v4l2_device_monitor_stop (GstDeviceMonitor * monitor);
+#endif
+
+
+static void
+gst_v4l2_device_monitor_class_init (GstV4l2DeviceMonitorClass * klass)
+{
+ GstDeviceMonitorClass *dm_class = GST_DEVICE_MONITOR_CLASS (klass);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ dm_class->probe = gst_v4l2_device_monitor_probe;
+
+#if HAVE_GUDEV
+ dm_class->start = gst_v4l2_device_monitor_start;
+ dm_class->stop = gst_v4l2_device_monitor_stop;
+#endif
+
+ gobject_class->finalize = gst_v4l2_device_monitor_finalize;
+
+ gst_device_monitor_class_set_static_metadata (dm_class,
+ "Video (video4linux2) Device Monitor", "Source/Sink/Video",
+ "List and monitor video4linux2 source and sink devices",
+ "Olivier Crete <olivier.crete@collabora.com>");
+}
+
+static void
+gst_v4l2_device_monitor_init (GstV4l2DeviceMonitor * monitor)
+{
+#if HAVE_GUDEV
+ g_cond_init (&monitor->started_cond);
+#endif
+}
+
+static void
+gst_v4l2_device_monitor_finalize (GObject * object)
+{
+#if HAVE_GUDEV
+ GstV4l2DeviceMonitor *monitor = GST_V4L2_DEVICE_MONITOR (object);
+
+ g_cond_clear (&monitor->started_cond);
+#endif
+
+ G_OBJECT_CLASS (gst_v4l2_device_monitor_parent_class)->finalize (object);
+}
+
+static GstV4l2Device *
+gst_v4l2_device_monitor_probe_device (GstV4l2DeviceMonitor * monitor,
+ const gchar * device_path, const gchar * device_name)
+{
+ GstV4l2Object *v4l2obj;
+ GstCaps *caps;
+ GstV4l2Device *device = NULL;
+ struct stat st;
+ GstV4l2DeviceType type = GST_V4L2_DEVICE_TYPE_INVALID;
+
+ if (stat (device_path, &st) == -1)
+ return NULL;
+
+ if (!S_ISCHR (st.st_mode))
+ return NULL;
+
+ v4l2obj = gst_v4l2_object_new ((GstElement *) monitor,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE, device_path, NULL, NULL, NULL);
+
+ if (!gst_v4l2_open (v4l2obj))
+ goto destroy;
+
+
+ if (v4l2obj->vcap.capabilities & V4L2_CAP_VIDEO_CAPTURE)
+ type = GST_V4L2_DEVICE_TYPE_SOURCE;
+
+ if (v4l2obj->vcap.capabilities & V4L2_CAP_VIDEO_OUTPUT) {
+ /* Morph it in case our initial guess was wrong */
+ v4l2obj->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+
+ if (type == GST_V4L2_DEVICE_TYPE_INVALID)
+ type = GST_V4L2_DEVICE_TYPE_SINK;
+ else
+ /* We ignore M2M devices that are both capture and output for now
+ * The monitor is not for them
+ */
+ goto close;
+ }
+
+ caps = gst_v4l2_object_get_caps (v4l2obj, NULL);
+
+ if (caps == NULL)
+ goto close;
+ if (gst_caps_is_empty (caps)) {
+ gst_caps_unref (caps);
+ goto close;
+ }
+
+ device = gst_v4l2_device_new (device_path,
+ device_name ? device_name : (gchar *) v4l2obj->vcap.card, caps, type);
+ gst_caps_unref (caps);
+
+close:
+
+ gst_v4l2_close (v4l2obj);
+
+destroy:
+
+ gst_v4l2_object_destroy (v4l2obj);
+
+ return device;
+}
+
+
+static GList *
+gst_v4l2_device_monitor_probe (GstDeviceMonitor * monitor)
+{
+ GstV4l2DeviceMonitor *self = GST_V4L2_DEVICE_MONITOR (monitor);
+ GList *devices = NULL;
+ const gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL };
+ gint base, n;
+
+ /*
+ * detect /dev entries
+ */
+ for (n = 0; n < 64; n++) {
+ for (base = 0; dev_base[base] != NULL; base++) {
+ gchar *dev = g_strdup_printf ("%s%d", dev_base[base], n);
+ GstV4l2Device *device;
+
+ device = gst_v4l2_device_monitor_probe_device (self, dev, NULL);
+
+ if (device) {
+ gst_object_ref_sink (device);
+ devices = g_list_prepend (devices, device);
+ }
+
+ g_free (dev);
+ }
+ }
+
+ return devices;
+}
+
+#if HAVE_GUDEV
+
+static GstDevice *
+gst_v4l2_device_monitor_device_from_udev (GstV4l2DeviceMonitor * monitor,
+ GUdevDevice * udev_device)
+{
+ GstV4l2Device *gstdev;
+ const gchar *device_path = g_udev_device_get_device_file (udev_device);
+ const gchar *device_name;
+
+ device_name = g_udev_device_get_property (udev_device, "ID_V4L_PRODUCT");
+ if (!device_name)
+ device_name = g_udev_device_get_property (udev_device, "ID_MODEL_ENC");
+ if (!device_name)
+ device_name = g_udev_device_get_property (udev_device, "ID_MODEL");
+
+ gstdev = gst_v4l2_device_monitor_probe_device (monitor, device_path,
+ device_name);
+
+ if (gstdev)
+ gstdev->syspath = g_strdup (g_udev_device_get_sysfs_path (udev_device));
+
+ return GST_DEVICE (gstdev);
+}
+
+static void
+uevent_cb (GUdevClient * client, const gchar * action, GUdevDevice * device,
+ GstV4l2DeviceMonitor * self)
+{
+ GstDeviceMonitor *monitor = GST_DEVICE_MONITOR (self);
+
+ /* Not V4L2, ignoring */
+ if (g_udev_device_get_property_as_int (device, "ID_V4L_VERSION") != 2)
+ return;
+
+ if (!strcmp (action, "add")) {
+ GstDevice *gstdev = NULL;
+
+ gstdev = gst_v4l2_device_monitor_device_from_udev (self, device);
+
+ if (gstdev)
+ gst_device_monitor_device_add (monitor, gstdev);
+ } else if (!strcmp (action, "remove")) {
+ GstV4l2Device *gstdev = NULL;
+ GList *item;
+
+ GST_OBJECT_LOCK (self);
+ for (item = monitor->devices; item; item = item->next) {
+ gstdev = item->data;
+
+ if (!strcmp (gstdev->syspath, g_udev_device_get_sysfs_path (device))) {
+ gst_object_ref (gstdev);
+ break;
+ }
+
+ gstdev = NULL;
+ }
+ GST_OBJECT_UNLOCK (monitor);
+
+ if (gstdev) {
+ gst_device_monitor_device_remove (monitor, GST_DEVICE (gstdev));
+ g_object_unref (gstdev);
+ }
+ } else {
+ GST_WARNING ("Unhandled action %s", action);
+ }
+}
+
+static gpointer
+monitor_thread (gpointer data)
+{
+ GstV4l2DeviceMonitor *monitor = data;
+ GMainContext *context = NULL;
+ GMainLoop *loop = NULL;
+ GUdevClient *client;
+ GList *devices;
+ static const gchar *subsystems[] = { "video4linux", NULL };
+
+ GST_OBJECT_LOCK (monitor);
+ if (monitor->context)
+ context = g_main_context_ref (monitor->context);
+ if (monitor->loop)
+ loop = g_main_loop_ref (monitor->loop);
+
+ if (context == NULL || loop == NULL) {
+ monitor->started = TRUE;
+ g_cond_broadcast (&monitor->started_cond);
+ GST_OBJECT_UNLOCK (monitor);
+ return NULL;
+ }
+ GST_OBJECT_UNLOCK (monitor);
+
+ g_main_context_push_thread_default (context);
+
+ client = g_udev_client_new (subsystems);
+
+ g_signal_connect (client, "uevent", G_CALLBACK (uevent_cb), monitor);
+
+ devices = g_udev_client_query_by_subsystem (client, "video4linux");
+
+ while (devices) {
+ GUdevDevice *udev_device = devices->data;
+ GstDevice *gstdev;
+
+ devices = g_list_remove (devices, udev_device);
+
+ if (g_udev_device_get_property_as_int (udev_device, "ID_V4L_VERSION") == 2) {
+ gstdev = gst_v4l2_device_monitor_device_from_udev (monitor, udev_device);
+ if (gstdev)
+ gst_device_monitor_device_add (GST_DEVICE_MONITOR (monitor), gstdev);
+ }
+
+ g_object_unref (udev_device);
+ }
+
+ GST_OBJECT_LOCK (monitor);
+ monitor->started = TRUE;
+ g_cond_broadcast (&monitor->started_cond);
+ GST_OBJECT_UNLOCK (monitor);
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
+
+ g_object_unref (client);
+ g_main_context_unref (context);
+
+ gst_object_unref (monitor);
+
+ return NULL;
+}
+
+static gboolean
+gst_v4l2_device_monitor_start (GstDeviceMonitor * monitor)
+{
+ GstV4l2DeviceMonitor *self = GST_V4L2_DEVICE_MONITOR (monitor);
+
+ GST_OBJECT_LOCK (self);
+ g_assert (self->context == NULL);
+
+ self->context = g_main_context_new ();
+ self->loop = g_main_loop_new (self->context, FALSE);
+
+ self->thread = g_thread_new ("v4l2-device-monitor", monitor_thread,
+ g_object_ref (self));
+
+ while (self->started == FALSE)
+ g_cond_wait (&self->started_cond, GST_OBJECT_GET_LOCK (self));
+
+ GST_OBJECT_UNLOCK (self);
+
+ return TRUE;
+}
+
+static void
+gst_v4l2_device_monitor_stop (GstDeviceMonitor * monitor)
+{
+ GstV4l2DeviceMonitor *self = GST_V4L2_DEVICE_MONITOR (monitor);
+ GMainContext *context;
+ GMainLoop *loop;
+ GSource *idle_stop_source;
+
+ GST_OBJECT_LOCK (self);
+ context = self->context;
+ loop = self->loop;
+ self->context = NULL;
+ self->loop = NULL;
+ GST_OBJECT_UNLOCK (self);
+
+ if (!context || !loop)
+ return;
+
+ idle_stop_source = g_idle_source_new ();
+ g_source_set_callback (idle_stop_source, (GSourceFunc) g_main_loop_quit, loop,
+ (GDestroyNotify) g_main_loop_unref);
+ g_source_attach (idle_stop_source, context);
+ g_source_unref (idle_stop_source);
+ g_main_context_unref (context);
+
+ g_thread_join (self->thread);
+ g_thread_unref (self->thread);
+ self->thread = NULL;
+ self->started = FALSE;
+}
+
+#endif
+
+enum
+{
+ PROP_DEVICE_PATH = 1,
+};
+
+G_DEFINE_TYPE (GstV4l2Device, gst_v4l2_device, GST_TYPE_DEVICE);
+
+static void gst_v4l2_device_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec);
+static void gst_v4l2_device_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec);
+static void gst_v4l2_device_finalize (GObject * object);
+static GstElement *gst_v4l2_device_create_element (GstDevice * device,
+ const gchar * name);
+
+static void
+gst_v4l2_device_class_init (GstV4l2DeviceClass * klass)
+{
+ GstDeviceClass *dev_class = GST_DEVICE_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ dev_class->create_element = gst_v4l2_device_create_element;
+
+ object_class->get_property = gst_v4l2_device_get_property;
+ object_class->set_property = gst_v4l2_device_set_property;
+ object_class->finalize = gst_v4l2_device_finalize;
+
+ g_object_class_install_property (object_class, PROP_DEVICE_PATH,
+ g_param_spec_string ("device-path", "Device Path",
+ "The Path of the device node", "",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gst_v4l2_device_init (GstV4l2Device * device)
+{
+}
+
+static void
+gst_v4l2_device_finalize (GObject * object)
+{
+ GstV4l2Device *device = GST_V4L2_DEVICE (object);
+
+ g_free (device->device_path);
+ g_free (device->syspath);
+
+ G_OBJECT_CLASS (gst_v4l2_device_parent_class)->finalize (object);
+}
+
+static GstElement *
+gst_v4l2_device_create_element (GstDevice * device, const gchar * name)
+{
+ GstV4l2Device *v4l2_dev = GST_V4L2_DEVICE (device);
+ GstElement *elem;
+
+ elem = gst_element_factory_make (v4l2_dev->element, name);
+ g_object_set (elem, "device", v4l2_dev->device_path, NULL);
+
+ return elem;
+}
+
+static GstV4l2Device *
+gst_v4l2_device_new (const gchar * device_path, const gchar * device_name,
+ GstCaps * caps, GstV4l2DeviceType type)
+{
+ GstV4l2Device *gstdev;
+ const gchar *element;
+ const gchar *klass;
+
+ g_return_val_if_fail (device_path, NULL);
+ g_return_val_if_fail (device_name, NULL);
+ g_return_val_if_fail (caps, NULL);
+
+ switch (type) {
+ case GST_V4L2_DEVICE_TYPE_SOURCE:
+ element = "v4l2src";
+ klass = "Video/Source";
+ break;
+ case GST_V4L2_DEVICE_TYPE_SINK:
+ element = "v4l2sink";
+ klass = "Video/Sink";
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ gstdev = g_object_new (GST_TYPE_V4L2_DEVICE, "device-path", device_path,
+ "display-name", device_name, "caps", caps, "klass", klass, NULL);
+
+ gstdev->element = element;
+
+
+ return gstdev;
+}
+
+
+static void
+gst_v4l2_device_get_property (GObject * object, guint prop_id,
+ GValue * value, GParamSpec * pspec)
+{
+ GstV4l2Device *device;
+
+ device = GST_V4L2_DEVICE_CAST (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE_PATH:
+ g_value_set_string (value, device->device_path);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+gst_v4l2_device_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstV4l2Device *device;
+
+ device = GST_V4L2_DEVICE_CAST (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE_PATH:
+ device->device_path = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
diff --git a/sys/v4l2/gstv4l2devicemonitor.h b/sys/v4l2/gstv4l2devicemonitor.h
new file mode 100644
index 000000000..4e3050e44
--- /dev/null
+++ b/sys/v4l2/gstv4l2devicemonitor.h
@@ -0,0 +1,101 @@
+/* GStreamer
+ * Copyright (C) 2012 Olivier Crete <olivier.crete@collabora.com>
+ *
+ * gstv4l2devicemonitor.h: V4l2 device probing and monitoring
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_V4L2_DEVICE_MONITOR_H__
+#define __GST_V4L2_DEVICE_MONITOR_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gst/gst.h>
+
+#ifdef HAVE_GUDEV
+#include <gudev/gudev.h>
+#endif
+
+G_BEGIN_DECLS
+
+typedef struct _GstV4l2DeviceMonitor GstV4l2DeviceMonitor;
+typedef struct _GstV4l2DeviceMonitorPrivate GstV4l2DeviceMonitorPrivate;
+typedef struct _GstV4l2DeviceMonitorClass GstV4l2DeviceMonitorClass;
+
+#define GST_TYPE_V4L2_DEVICE_MONITOR (gst_v4l2_device_monitor_get_type())
+#define GST_IS_V4L2_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_DEVICE_MONITOR))
+#define GST_IS_V4L2_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L2_DEVICE_MONITOR))
+#define GST_V4L2_DEVICE_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_V4L2_DEVICE_MONITOR, GstV4l2DeviceMonitorClass))
+#define GST_V4L2_DEVICE_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_DEVICE_MONITOR, GstV4l2DeviceMonitor))
+#define GST_V4L2_DEVICE_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE_MONITOR, GstV4l2DeviceMonitorClass))
+#define GST_V4L2_DEVICE_MONITOR_CAST(obj) ((GstV4l2DeviceMonitor *)(obj))
+
+struct _GstV4l2DeviceMonitor {
+ GstDeviceMonitor parent;
+
+#ifdef HAVE_GUDEV
+ GMainContext *context;
+ GMainLoop *loop;
+ GThread *thread;
+ gboolean started;
+ GCond started_cond;
+#endif
+};
+
+typedef enum {
+ GST_V4L2_DEVICE_TYPE_INVALID = 0,
+ GST_V4L2_DEVICE_TYPE_SOURCE,
+ GST_V4L2_DEVICE_TYPE_SINK
+} GstV4l2DeviceType;
+
+struct _GstV4l2DeviceMonitorClass {
+ GstDeviceMonitorClass parent_class;
+};
+
+GType gst_v4l2_device_monitor_get_type (void);
+
+
+typedef struct _GstV4l2Device GstV4l2Device;
+typedef struct _GstV4l2DevicePrivate GstV4l2DevicePrivate;
+typedef struct _GstV4l2DeviceClass GstV4l2DeviceClass;
+
+#define GST_TYPE_V4L2_DEVICE (gst_v4l2_device_get_type())
+#define GST_IS_V4L2_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L2_DEVICE))
+#define GST_IS_V4L2_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L2_DEVICE))
+#define GST_V4L2_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_V4L2_DEVICE, GstV4l2DeviceClass))
+#define GST_V4L2_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L2_DEVICE, GstV4l2Device))
+#define GST_V4L2_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DEVICE, GstV4l2DeviceClass))
+#define GST_V4L2_DEVICE_CAST(obj) ((GstV4l2Device *)(obj))
+
+struct _GstV4l2Device {
+ GstDevice parent;
+
+ gchar *device_path;
+ gchar *syspath;
+ const gchar *element;
+};
+
+struct _GstV4l2DeviceClass {
+ GstDeviceClass parent_class;
+};
+
+GType gst_v4l2_device_get_type (void);
+
+#endif /* __GST_V4L2_DEVICE_MONITOR_H__ */