From 7a7267b4028530869557fdbee4710c4bc9aeba38 Mon Sep 17 00:00:00 2001 From: Youness Alaoui Date: Mon, 10 Sep 2012 18:20:48 -0400 Subject: [PATCH] uvch264: Make gudev/libusb a hard dependency and remove XU_FIND_UNIT ioctl support Conflicts: sys/uvch264/gstuvch264_src.c --- configure.ac | 9 +- sys/uvch264/gstuvch264_src.c | 180 ++++++++++++++--------------------- sys/uvch264/gstuvch264_src.h | 4 - 3 files changed, 80 insertions(+), 113 deletions(-) diff --git a/configure.ac b/configure.ac index d9134c2f4b..4b3ab03713 100644 --- a/configure.ac +++ b/configure.ac @@ -694,7 +694,7 @@ AG_GST_CHECK_FEATURE(VCD, [Video CD], vcdsrc, [ dnl *** UVC H264 *** translit(dnm, m, l) AM_CONDITIONAL(USE_UVCH264, true) AG_GST_CHECK_FEATURE(UVCH264, [UVC H264], uvch264, [ - AC_CHECK_HEADER(linux/uvcvideo.h, HAVE_UVCH264=yes, HAVE_UVCH264=no) + AC_CHECK_HEADER(linux/uvcvideo.h, HAVE_UVCVIDEO_H=yes, HAVE_UVCVIDEO_H=no) AG_GST_PKG_CHECK_MODULES(GST_VIDEO, gstreamer-video-0.10 >= 0.10.36) PKG_CHECK_MODULES(G_UDEV, gudev-1.0 , [ AC_DEFINE([HAVE_GUDEV], 1, [Define if gudev is installed]) @@ -704,6 +704,13 @@ AG_GST_CHECK_FEATURE(UVCH264, [UVC H264], uvch264, [ AC_DEFINE([HAVE_LIBUSB], 1, [Define if libusb 1.x is installed]) HAVE_LIBUSB="yes" ], [HAVE_LIBUSB="no"]) + if test "x$HAVE_UVCVIDEO_H" == "xyes" && \ + test "x$HAVE_GUDEV" == "xyes" && \ + test "x$HAVE_LIBUSB" == "xyes"; then + HAVE_UVCH264=yes + else + HAVE_UVCH264=no + fi ]) AC_SUBST(LIBUDEV_CFLAGS) AC_SUBST(LIBUDEV_LIBS) diff --git a/sys/uvch264/gstuvch264_src.c b/sys/uvch264/gstuvch264_src.c index 21b6c8c15b..04bbee27e7 100644 --- a/sys/uvch264/gstuvch264_src.c +++ b/sys/uvch264/gstuvch264_src.c @@ -32,13 +32,16 @@ # include #endif +#include "gstuvch264_src.h" + #include #include #include #include #include -#if defined (HAVE_GUDEV) && defined (HAVE_LIBUSB) +#include "gstuvch264_src.h" +#include "gstuvch264-marshal.h" #include #include @@ -61,22 +64,6 @@ typedef struct #define USB_VIDEO_CONTROL 1 #define USB_VIDEO_CONTROL_INTERFACE 0x24 #define USB_VIDEO_CONTROL_XU_TYPE 0x06 -#endif - -#include "gstuvch264_src.h" - -#ifndef UVCIOC_XU_FIND_UNIT -/* Define the needed structure if is too old. - * This might fail though if the kernel itself does not support it. - */ -struct uvc_xu_find_unit -{ - __u8 guid[16]; - __u8 unit; -}; -#define UVCIOC_XU_FIND_UNIT _IOWR('u', 0x22, struct uvc_xu_find_unit) -#endif - enum { @@ -628,13 +615,9 @@ gst_uvc_h264_src_dispose (GObject * object) { GstUvcH264Src *self = GST_UVC_H264_SRC (object); -#if defined (HAVE_GUDEV) && defined (HAVE_LIBUSB) if (self->usb_ctx) libusb_exit (self->usb_ctx); self->usb_ctx = NULL; -#else - (void) self; -#endif G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -1811,112 +1794,93 @@ gst_uvc_h264_src_event (GstPad * pad, GstEvent * event) static guint8 xu_get_id (GstUvcH264Src * self) { - struct uvc_xu_find_unit xu; static const __u8 guid[16] = GUID_UVCX_H264_XU; + GUdevClient *client; + GUdevDevice *udevice; + GUdevDevice *parent; + guint64 busnum; + guint64 devnum; + libusb_device **device_list = NULL; + libusb_device *device = NULL; + ssize_t cnt; + int i, j, k; - if (self->v4l2_fd == -1) { - GST_WARNING_OBJECT (self, "Can't query XU with fd = -1"); - return 0; + + if (self->usb_ctx == NULL) + libusb_init (&self->usb_ctx); + + client = g_udev_client_new (NULL); + if (client) { + udevice = g_udev_client_query_by_device_file (client, self->device); + if (udevice) { + parent = g_udev_device_get_parent_with_subsystem (udevice, "usb", + "usb_device"); + if (parent) { + busnum = g_udev_device_get_sysfs_attr_as_uint64 (parent, "busnum"); + devnum = g_udev_device_get_sysfs_attr_as_uint64 (parent, "devnum"); + + cnt = libusb_get_device_list (self->usb_ctx, &device_list); + for (i = 0; i < cnt; i++) { + if (busnum == libusb_get_bus_number (device_list[i]) && + devnum == libusb_get_device_address (device_list[i])) { + device = libusb_ref_device (device_list[i]); + break; + } + } + libusb_free_device_list (device_list, 1); + g_object_unref (parent); + } + g_object_unref (udevice); + } + g_object_unref (client); } - memcpy (xu.guid, guid, 16); - xu.unit = 0; + if (device) { + struct libusb_device_descriptor desc; - if (-1 == ioctl (self->v4l2_fd, UVCIOC_XU_FIND_UNIT, &xu)) { -#if defined (HAVE_GUDEV) && defined (HAVE_LIBUSB) - /* Fallback on libusb */ - GUdevClient *client; - GUdevDevice *udevice; - GUdevDevice *parent; - guint64 busnum; - guint64 devnum; - libusb_device **device_list = NULL; - libusb_device *device = NULL; - ssize_t cnt; - int i, j, k; + if (libusb_get_device_descriptor (device, &desc) == 0) { + for (i = 0; i < desc.bNumConfigurations; ++i) { + struct libusb_config_descriptor *config = NULL; - GST_DEBUG_OBJECT (self, "XU_FIND_UNIT ioctl failed. Fallback on libusb"); + if (libusb_get_config_descriptor (device, i, &config) == 0) { + for (j = 0; j < config->bNumInterfaces; j++) { + for (k = 0; k < config->interface[j].num_altsetting; k++) { + const struct libusb_interface_descriptor *interface; + const guint8 *ptr = NULL; - if (self->usb_ctx == NULL) - libusb_init (&self->usb_ctx); + interface = &config->interface[j].altsetting[k]; + if (interface->bInterfaceClass != LIBUSB_CLASS_VIDEO || + interface->bInterfaceSubClass != USB_VIDEO_CONTROL) + continue; + ptr = interface->extra; + while (ptr - interface->extra + + sizeof (xu_descriptor) < interface->extra_length) { + xu_descriptor *desc = (xu_descriptor *) ptr; - client = g_udev_client_new (NULL); - if (client) { - udevice = g_udev_client_query_by_device_file (client, self->device); - if (udevice) { - parent = g_udev_device_get_parent_with_subsystem (udevice, "usb", - "usb_device"); - if (parent) { - busnum = g_udev_device_get_sysfs_attr_as_uint64 (parent, "busnum"); - devnum = g_udev_device_get_sysfs_attr_as_uint64 (parent, "devnum"); + GST_DEBUG_OBJECT (self, "Found VideoControl interface with " + "unit id %d : %" GUID_FORMAT, desc->bUnitID, + GUID_ARGS (desc->guidExtensionCode)); + if (desc->bDescriptorType == USB_VIDEO_CONTROL_INTERFACE && + desc->bDescriptorSubType == USB_VIDEO_CONTROL_XU_TYPE && + memcmp (desc->guidExtensionCode, guid, 16) == 0) { + guint8 unit_id = desc->bUnitID; - cnt = libusb_get_device_list (self->usb_ctx, &device_list); - for (i = 0; i < cnt; i++) { - if (busnum == libusb_get_bus_number (device_list[i]) && - devnum == libusb_get_device_address (device_list[i])) { - device = libusb_ref_device (device_list[i]); - break; - } - } - libusb_free_device_list (device_list, 1); - g_object_unref (parent); - } - g_object_unref (udevice); - } - g_object_unref (client); - } + GST_DEBUG_OBJECT (self, "Found H264 XU unit : %d", unit_id); - if (device) { - struct libusb_device_descriptor desc; - - if (libusb_get_device_descriptor (device, &desc) == 0) { - for (i = 0; i < desc.bNumConfigurations; ++i) { - struct libusb_config_descriptor *config = NULL; - - if (libusb_get_config_descriptor (device, i, &config) == 0) { - for (j = 0; j < config->bNumInterfaces; j++) { - for (k = 0; k < config->interface[j].num_altsetting; k++) { - const struct libusb_interface_descriptor *interface; - const guint8 *ptr = NULL; - - interface = &config->interface[j].altsetting[k]; - if (interface->bInterfaceClass != LIBUSB_CLASS_VIDEO || - interface->bInterfaceSubClass != USB_VIDEO_CONTROL) - continue; - ptr = interface->extra; - while (ptr - interface->extra + - sizeof (xu_descriptor) < interface->extra_length) { - xu_descriptor *desc = (xu_descriptor *) ptr; - - GST_DEBUG_OBJECT (self, "Found VideoControl interface with " - "unit id %d : %" GUID_FORMAT, desc->bUnitID, - GUID_ARGS (desc->guidExtensionCode)); - if (desc->bDescriptorType == USB_VIDEO_CONTROL_INTERFACE && - desc->bDescriptorSubType == USB_VIDEO_CONTROL_XU_TYPE && - memcmp (desc->guidExtensionCode, guid, 16) == 0) { - guint8 unit_id = desc->bUnitID; - - GST_DEBUG_OBJECT (self, "Found H264 XU unit : %d", unit_id); - - libusb_unref_device (device); - return unit_id; - } - ptr += desc->bLength; + libusb_unref_device (device); + return unit_id; } + ptr += desc->bLength; } } } } } - libusb_unref_device (device); } -#else - GST_WARNING_OBJECT (self, "XU_FIND_UNIT ioctl failed"); -#endif - return 0; + libusb_unref_device (device); } - return xu.unit; + return 0; } static gboolean diff --git a/sys/uvch264/gstuvch264_src.h b/sys/uvch264/gstuvch264_src.h index 3eb846bc0e..0b139ff11e 100644 --- a/sys/uvch264/gstuvch264_src.h +++ b/sys/uvch264/gstuvch264_src.h @@ -30,9 +30,7 @@ #include #include -#if defined (HAVE_GUDEV) && defined (HAVE_LIBUSB) #include -#endif #include "uvc_h264.h" @@ -105,9 +103,7 @@ struct _GstUvcH264Src int v4l2_fd; guint8 h264_unit_id; -#if defined (HAVE_GUDEV) && defined (HAVE_LIBUSB) libusb_context *usb_ctx; -#endif GstPadEventFunction srcpad_event_func; GstEvent *key_unit_event;