diff options
author | Youness Alaoui <youness.alaoui@collabora.co.uk> | 2013-01-10 19:44:43 -0500 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2013-01-16 14:44:49 -0500 |
commit | e2abfee1ca63892d76de66a1b769fedbcef188de (patch) | |
tree | fab35b62ba1adf1194e0831b5ad144ebad54e921 | |
parent | 28059878e3c3e80223a803e9777dec675b3a1b63 (diff) |
uvch264: Add GstPropertyProbe support to uvch264_src
-rw-r--r-- | sys/uvch264/Makefile.am | 3 | ||||
-rw-r--r-- | sys/uvch264/gstuvch264_src.c | 189 | ||||
-rw-r--r-- | sys/uvch264/gstuvch264_src.h | 5 |
3 files changed, 190 insertions, 7 deletions
diff --git a/sys/uvch264/Makefile.am b/sys/uvch264/Makefile.am index 8ecff113f..ee077c9ba 100644 --- a/sys/uvch264/Makefile.am +++ b/sys/uvch264/Makefile.am @@ -41,7 +41,8 @@ libgstuvch264_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \ $(GST_LIBS) \ $(G_UDEV_LIBS) \ $(LIBUSB_LIBS) \ - $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-$(GST_MAJORMINOR).la + $(top_builddir)/gst-libs/gst/basecamerabinsrc/libgstbasecamerabinsrc-$(GST_MAJORMINOR).la \ + -lgstinterfaces-$(GST_MAJORMINOR) noinst_HEADERS = gstuvch264_mjpgdemux.h \ gstuvch264_src.h \ diff --git a/sys/uvch264/gstuvch264_src.c b/sys/uvch264/gstuvch264_src.c index c5539d813..442d841e5 100644 --- a/sys/uvch264/gstuvch264_src.c +++ b/sys/uvch264/gstuvch264_src.c @@ -38,6 +38,7 @@ #include <sys/ioctl.h> #include <string.h> +#include <gst/interfaces/propertyprobe.h> #include "gstuvch264_src.h" #include "gstuvch264-marshal.h" #include <gudev/gudev.h> @@ -149,9 +150,6 @@ static guint _signals[LAST_SIGNAL]; GST_DEBUG_CATEGORY (uvc_h264_src_debug); #define GST_CAT_DEFAULT uvc_h264_src_debug -GST_BOILERPLATE (GstUvcH264Src, gst_uvc_h264_src, - GstBaseCameraSrc, GST_TYPE_BASE_CAMERA_SRC); - #define GST_UVC_H264_SRC_VF_CAPS_STR \ GST_VIDEO_CAPS_RGB ";" \ GST_VIDEO_CAPS_RGB";" \ @@ -243,6 +241,7 @@ static void fill_probe_commit (GstUvcH264Src * self, UvcH264StreamFormat stream_format); static gboolean xu_query (GstUvcH264Src * self, guint selector, guint query, guchar * data); +static guint8 xu_get_id (GstUvcH264Src * self, const gchar * device_file); static void set_rate_control (GstUvcH264Src * self); static void set_level_idc (GstUvcH264Src * self); @@ -262,6 +261,39 @@ static gboolean gst_uvc_h264_src_get_boolean_setting (GstUvcH264Src * self, static gboolean gst_uvc_h264_src_get_int_setting (GstUvcH264Src * self, gchar * property, gint * min, gint * def, gint * max); +/* GstPropertyProbe */ +static void gst_uvc_h264_src_init_interfaces (GType type); +static void +gst_uvc_h264_src_implements_interface_init (GstImplementsInterfaceClass * + klass); +static void +gst_uvc_h264_src_property_probe_interface_init (GstPropertyProbeInterface * + iface); + +GST_BOILERPLATE_FULL (GstUvcH264Src, gst_uvc_h264_src, + GstBaseCameraSrc, GST_TYPE_BASE_CAMERA_SRC, + gst_uvc_h264_src_init_interfaces); + +static void +gst_uvc_h264_src_init_interfaces (GType type) +{ + static const GInterfaceInfo uvcsrc_propertyprobe_info = { + (GInterfaceInitFunc) gst_uvc_h264_src_property_probe_interface_init, + NULL, + NULL, + }; + static const GInterfaceInfo uvcsrc_implements_interface_info = { + (GInterfaceInitFunc) gst_uvc_h264_src_implements_interface_init, + NULL, + NULL, + }; + + g_type_add_interface_static (type, GST_TYPE_PROPERTY_PROBE, + &uvcsrc_propertyprobe_info); + g_type_add_interface_static (type, GST_TYPE_IMPLEMENTS_INTERFACE, + &uvcsrc_implements_interface_info); +} + static void gst_uvc_h264_src_base_init (gpointer g_class) { @@ -619,9 +651,154 @@ gst_uvc_h264_src_dispose (GObject * object) libusb_exit (self->usb_ctx); self->usb_ctx = NULL; + if (self->probe_properties) + g_list_free (self->probe_properties); + self->probe_properties = NULL; + if (self->probe_v4l2src) + gst_object_unref (self->probe_v4l2src); + self->probe_v4l2src = NULL; + if (self->probe_device) + g_value_array_free (self->probe_device); + self->probe_device = NULL; + G_OBJECT_CLASS (parent_class)->dispose (object); } +static gboolean +gst_uvc_h264_src_interface_supported (GstImplementsInterface * iface, + GType iface_type) +{ + if (iface_type == GST_TYPE_PROPERTY_PROBE) + return TRUE; + else + return FALSE; +} + +static void +gst_uvc_h264_src_implements_interface_init (GstImplementsInterfaceClass * klass) +{ + klass->supported = gst_uvc_h264_src_interface_supported; +} + +static const GList * +gst_uvc_h264_src_probe_get_properties (GstPropertyProbe * probe) +{ + GstUvcH264Src *self = GST_UVC_H264_SRC (probe); + GObjectClass *klass = G_OBJECT_GET_CLASS (probe); + GList **l = &self->probe_properties; + + if (!*l) + *l = g_list_append (*l, g_object_class_find_property (klass, "device")); + + return *l; +} + +static gboolean +gst_uvc_h264_src_probe_needs_probe (GstPropertyProbe * probe, + guint prop_id, const GParamSpec * pspec) +{ + GstUvcH264Src *self = GST_UVC_H264_SRC (probe); + + if (prop_id != PROP_DEVICE) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); + return FALSE; + } + + if (!self->probe_v4l2src) + self->probe_v4l2src = gst_element_factory_make ("v4l2src", "uvch264_probe"); + + if (self->probe_v4l2src) { + GstPropertyProbe *v4l2src = GST_PROPERTY_PROBE (self->probe_v4l2src); + const GParamSpec *spec; + + spec = gst_property_probe_get_property (v4l2src, "device"); + + return gst_property_probe_needs_probe (v4l2src, spec); + } + + return FALSE; +} + +static void +gst_uvc_h264_src_probe_probe_property (GstPropertyProbe * probe, + guint prop_id, const GParamSpec * pspec) +{ + GstUvcH264Src *self = GST_UVC_H264_SRC (probe); + + if (prop_id != PROP_DEVICE) { + G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); + return; + } + + if (!self->probe_v4l2src) + self->probe_v4l2src = gst_element_factory_make ("v4l2src", "uvch264_probe"); + + if (self->probe_v4l2src) { + GstPropertyProbe *v4l2src = GST_PROPERTY_PROBE (self->probe_v4l2src); + GValueArray *values; + guint i; + + if (self->probe_device) + g_value_array_free (self->probe_device); + self->probe_device = g_value_array_new (0); + + values = gst_property_probe_probe_and_get_values_name (v4l2src, "device"); + if (values) { + GValue value = { 0 }; + + g_value_init (&value, G_TYPE_STRING); + + for (i = 0; i < values->n_values; ++i) { + GValue *val; + const gchar *device = NULL; + guint8 xu_id; + + val = g_value_array_get_nth (values, i); + if (val == NULL || !G_VALUE_HOLDS_STRING (val)) + continue; + + device = g_value_get_string (val); + if (device == NULL) + continue; + + xu_id = xu_get_id (self, device); + if (xu_id != 0) { + g_value_set_string (&value, device); + g_value_array_append (self->probe_device, &value); + } + } + g_value_unset (&value); + g_value_array_free (values); + } + } + +} + +static GValueArray * +gst_uvc_h264_src_probe_get_values (GstPropertyProbe * probe, + guint prop_id, const GParamSpec * pspec) +{ + GstUvcH264Src *self = GST_UVC_H264_SRC (probe); + + if (prop_id == PROP_DEVICE) { + return g_value_array_copy (self->probe_device); + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); + } + + return NULL; +} + +static void +gst_uvc_h264_src_property_probe_interface_init (GstPropertyProbeInterface * + iface) +{ + iface->needs_probe = gst_uvc_h264_src_probe_needs_probe; + iface->probe_property = gst_uvc_h264_src_probe_probe_property; + iface->get_properties = gst_uvc_h264_src_probe_get_properties; + iface->get_values = gst_uvc_h264_src_probe_get_values; +} + static void gst_uvc_h264_src_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -1792,7 +1969,7 @@ gst_uvc_h264_src_event (GstPad * pad, GstEvent * event) } static guint8 -xu_get_id (GstUvcH264Src * self) +xu_get_id (GstUvcH264Src * self, const gchar * device_file) { static const __u8 guid[16] = GUID_UVCX_H264_XU; GUdevClient *client; @@ -1811,7 +1988,7 @@ xu_get_id (GstUvcH264Src * self) client = g_udev_client_new (NULL); if (client) { - udevice = g_udev_client_query_by_device_file (client, self->device); + udevice = g_udev_client_query_by_device_file (client, device_file); if (udevice) { parent = g_udev_device_get_parent_with_subsystem (udevice, "usb", "usb_device"); @@ -2497,7 +2674,7 @@ ensure_v4l2src (GstUvcH264Src * self) /* Set/Update the fd and unit id after we go to READY */ g_object_get (self->v4l2_src, "device-fd", &self->v4l2_fd, NULL); - self->h264_unit_id = xu_get_id (self); + self->h264_unit_id = xu_get_id (self, self->device); if (self->h264_unit_id == 0) { GST_ELEMENT_ERROR (self, RESOURCE, SETTINGS, diff --git a/sys/uvch264/gstuvch264_src.h b/sys/uvch264/gstuvch264_src.h index 0b139ff11..a3f2a8d36 100644 --- a/sys/uvch264/gstuvch264_src.h +++ b/sys/uvch264/gstuvch264_src.h @@ -83,6 +83,11 @@ struct _GstUvcH264Src GstPad *imgsrc; GstPad *vidsrc; + /* GstPropertyProbe */ + GList *probe_properties; + GstElement *probe_v4l2src; + GValueArray *probe_device; + /* source elements */ GstElement *v4l2_src; GstElement *mjpg_demux; |