From 726fc3b5249274d9a56dcd3c7dc45e48c52b912d Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Fri, 2 May 2014 16:55:05 -0400 Subject: [PATCH] v4l2: Add a common device enumerator This will allow removing code duplication (hence bugs duplication). https://bugzilla.gnome.org/show_bug.cgi?id=727925 --- sys/v4l2/Makefile.am | 2 + sys/v4l2/v4l2-utils.c | 166 ++++++++++++++++++++++++++++++++++++++++++ sys/v4l2/v4l2-utils.h | 50 +++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 sys/v4l2/v4l2-utils.c create mode 100644 sys/v4l2/v4l2-utils.h diff --git a/sys/v4l2/Makefile.am b/sys/v4l2/Makefile.am index dfde1f6c25..248605fb75 100644 --- a/sys/v4l2/Makefile.am +++ b/sys/v4l2/Makefile.am @@ -14,6 +14,7 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \ gstv4l2videodec.c \ gstv4l2vidorient.c \ v4l2_calls.c \ + v4l2-utils.c \ tuner.c \ tunerchannel.c \ tunernorm.c @@ -52,6 +53,7 @@ noinst_HEADERS = \ gstv4l2videodec.h \ gstv4l2vidorient.h \ v4l2_calls.h \ + v4l2-utils.h \ tuner.h \ tunerchannel.h \ tunernorm.h diff --git a/sys/v4l2/v4l2-utils.c b/sys/v4l2/v4l2-utils.c new file mode 100644 index 0000000000..899c19119d --- /dev/null +++ b/sys/v4l2/v4l2-utils.c @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "v4l2-utils.h" + +/**************************/ +/* Common device iterator */ +/**************************/ + +#if HAVE_GUDEV +#include + +struct _GstV4l2GUdevIterator +{ + GstV4l2Iterator parent; + GList *devices; + GUdevDevice *device; + GUdevClient *client; +}; + +GstV4l2Iterator * +gst_v4l2_iterator_new (void) +{ + static const gchar *subsystems[] = { "video4linux", NULL }; + struct _GstV4l2GUdevIterator *it; + + it = g_slice_new0 (struct _GstV4l2GUdevIterator); + + it->client = g_udev_client_new (subsystems); + it->devices = g_udev_client_query_by_subsystem (it->client, "video4linux"); + + return (GstV4l2Iterator *) it; +} + +gboolean +gst_v4l2_iterator_next (GstV4l2Iterator * _it) +{ + struct _GstV4l2GUdevIterator *it = (struct _GstV4l2GUdevIterator *) _it; + const gchar *device_name; + + if (it->device) + g_object_unref (it->device); + + it->device = NULL; + it->parent.device_path = NULL; + it->parent.device_name = NULL; + + if (it->devices == NULL) + return FALSE; + + it->device = it->devices->data; + it->devices = g_list_delete_link (it->devices, it->devices); + + device_name = g_udev_device_get_property (it->device, "ID_V4L_PRODUCT"); + if (!device_name) + device_name = g_udev_device_get_property (it->device, "ID_MODEL_ENC"); + if (!device_name) + device_name = g_udev_device_get_property (it->device, "ID_MODEL"); + + it->parent.device_path = g_udev_device_get_device_file (it->device); + it->parent.device_name = device_name; + it->parent.sys_path = g_udev_device_get_sysfs_path (it->device); + + return TRUE; +} + +void +gst_v4l2_iterator_free (GstV4l2Iterator * _it) +{ + struct _GstV4l2GUdevIterator *it = (struct _GstV4l2GUdevIterator *) _it; + g_list_free_full (it->devices, g_object_unref); + gst_object_unref (it->client); + g_slice_free (struct _GstV4l2GUdevIterator, it); +} + +#else /* No GUDEV */ + +struct _GstV4l2FsIterator +{ + GstV4l2Iterator parent; + gint base_idx; + gint video_idx; + gchar *device; +}; + +GstV4l2Iterator * +gst_v4l2_iterator_new (void) +{ + struct _GstV4l2FsIterator *it; + + it = g_slice_new0 (struct _GstV4l2FsIterator); + it->base_idx = 0; + it->video_idx = -1; + it->device = NULL; + + return (GstV4l2Iterator *) it; +} + +gboolean +gst_v4l2_iterator_next (GstV4l2Iterator * _it) +{ + struct _GstV4l2FsIterator *it = (struct _GstV4l2FsIterator *) _it; + static const gchar *dev_base[] = { "/dev/video", "/dev/v4l2/video", NULL }; + gchar *device = NULL; + + g_free ((gchar *) it->parent.device_path); + it->parent.device_path = NULL; + + while (device == NULL) { + it->video_idx++; + + if (it->video_idx >= 64) { + it->video_idx = 0; + it->base_idx++; + } + + if (dev_base[it->base_idx] == NULL) { + it->video_idx = 0; + break; + } + + device = g_strdup_printf ("%s%d", dev_base[it->base_idx], it->video_idx); + + if (g_file_test (device, G_FILE_TEST_EXISTS)) { + it->parent.device_path = device; + break; + } + + g_free (device); + device = NULL; + } + + return it->parent.device_path != NULL; +} + +void +gst_v4l2_iterator_free (GstV4l2Iterator * _it) +{ + struct _GstV4l2FsIterator *it = (struct _GstV4l2FsIterator *) _it; + g_free ((gchar *) it->parent.device_path); + g_slice_free (struct _GstV4l2FsIterator, it); +} + +#endif diff --git a/sys/v4l2/v4l2-utils.h b/sys/v4l2/v4l2-utils.h new file mode 100644 index 0000000000..9a73bd9139 --- /dev/null +++ b/sys/v4l2/v4l2-utils.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 Collabora Ltd. + * Author: Nicolas Dufresne + * + * 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., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#ifndef __V4L2_UTILS_H__ +#define __V4L2_UTILS_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GstV4l2Iterator GstV4l2Iterator; + +struct _GstV4l2Iterator +{ + const gchar *device_path; + const gchar *device_name; + const gchar *sys_path; +}; + +GstV4l2Iterator * gst_v4l2_iterator_new (void); +gboolean gst_v4l2_iterator_next (GstV4l2Iterator *it); +void gst_v4l2_iterator_free (GstV4l2Iterator *it); + +const gchar * gst_v4l2_iterator_get_device_path (GstV4l2Iterator *it); +const gchar * gst_v4l2_iterator_get_device_name (GstV4l2Iterator *it); +const gchar * gst_v4l2_iterator_get_sys_path (GstV4l2Iterator *it); + +G_END_DECLS + +#endif /* __V4L2_UTILS_H__ */ + +