Expose colorbalance controls as object properties (like we do on xvimagesink).
Make them controlable.
libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
$(GST_BASE_CFLAGS) \
+ $(GST_CONTROLLER_CFLAGS) \
$(GST_CFLAGS) \
$(X_CFLAGS) \
$(LIBV4L2_CFLAGS) \
libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
$(GST_BASE_LIBS) \
- $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_MAJORMINOR) \
+ $(GST_CONTROLLER_LIBS) \
+ $(GST_PLUGINS_BASE_LIBS) \
+ -lgstvideo-$(GST_MAJORMINOR) \
-lgstinterfaces-$(GST_MAJORMINOR) \
$(GST_LIBS) \
$(xv_libs) \
#include "gst/gst-i18n-plugin.h"
#include <gst/gst.h>
+#include <gst/controller/gstcontroller.h>
#include "gstv4l2object.h"
#include "gstv4l2src.h"
GST_DEBUG_CATEGORY_INIT (v4l2_debug, "v4l2", 0, "V4L2 API calls");
GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
+ /* initialize gst controller library */
+ gst_controller_init (NULL, NULL);
+
if (!gst_element_register (plugin, "v4l2src", GST_RANK_PRIMARY,
GST_TYPE_V4L2SRC) ||
!gst_element_register (plugin, "v4l2sink", GST_RANK_NONE,
g_param_spec_flags ("flags", "Flags", "Device type flags",
GST_TYPE_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (gobject_class, PROP_BRIGHTNESS,
+ g_param_spec_int ("brightness", "Brightness",
+ "Picture brightness, or more precisely, the black level", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ g_object_class_install_property (gobject_class, PROP_CONTRAST,
+ g_param_spec_int ("contrast", "Contrast",
+ "Picture contrast or luma gain", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ g_object_class_install_property (gobject_class, PROP_SATURATION,
+ g_param_spec_int ("saturation", "Saturation",
+ "Picture color saturation or chroma gain", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
+ g_object_class_install_property (gobject_class, PROP_HUE,
+ g_param_spec_int ("hue", "Hue",
+ "Hue or color balance", G_MININT,
+ G_MAXINT, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_CONTROLLABLE));
}
GstV4l2Object *
return TRUE;
}
+static gint
+gst_v4l2_object_prop_to_cid (guint prop_id)
+{
+ gint cid = -1;
+
+ switch (prop_id) {
+ case PROP_BRIGHTNESS:
+ cid = V4L2_CID_BRIGHTNESS;
+ break;
+ case PROP_CONTRAST:
+ cid = V4L2_CID_CONTRAST;
+ break;
+ case PROP_SATURATION:
+ cid = V4L2_CID_SATURATION;
+ break;
+ case PROP_HUE:
+ cid = V4L2_CID_HUE;
+ break;
+ default:
+ GST_WARNING ("unmapped property id: %d", prop_id);
+ }
+ return cid;
+}
+
gboolean
gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object,
g_free (v4l2object->videodev);
v4l2object->videodev = g_value_dup_string (value);
break;
+ case PROP_BRIGHTNESS:
+ case PROP_CONTRAST:
+ case PROP_SATURATION:
+ case PROP_HUE:
+ {
+ gint cid = gst_v4l2_object_prop_to_cid (prop_id);
+
+ if (cid != -1) {
+ if (GST_V4L2_IS_OPEN (v4l2object)) {
+ gst_v4l2_set_attribute (v4l2object, cid, g_value_get_int (value));
+ }
+ }
+ return TRUE;
+ }
+ break;
#if 0
case PROP_NORM:
if (GST_V4L2_IS_OPEN (v4l2object)) {
g_value_set_flags (value, flags);
break;
}
+ case PROP_BRIGHTNESS:
+ case PROP_CONTRAST:
+ case PROP_SATURATION:
+ case PROP_HUE:
+ {
+ gint cid = gst_v4l2_object_prop_to_cid (prop_id);
+
+ if (cid != -1) {
+ if (GST_V4L2_IS_OPEN (v4l2object)) {
+ gint v;
+ if (gst_v4l2_get_attribute (v4l2object, cid, &v)) {
+ g_value_set_int (value, v);
+ }
+ }
+ }
+ return TRUE;
+ }
+ break;
default:
return FALSE;
break;
#include <gst/gst.h>
#include <gst/base/gstpushsrc.h>
+#include <gst/controller/gstcontroller.h>
#include <gst/interfaces/propertyprobe.h>
PROP_DEVICE, \
PROP_DEVICE_NAME, \
PROP_DEVICE_FD, \
- PROP_FLAGS
+ PROP_FLAGS, \
+ PROP_BRIGHTNESS, \
+ PROP_CONTRAST, \
+ PROP_SATURATION, \
+ PROP_HUE
/* create/destroy */
GstV4l2Object * gst_v4l2_object_new (GstElement * element,
/* we want our own v4l2 type of fourcc codes */
if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
&h, &fps_n, &fps_d, &size)) {
- GST_DEBUG_OBJECT (v4l2src,
+ GST_INFO_OBJECT (v4l2src,
"can't get capture format from caps %" GST_PTR_FORMAT, caps);
return FALSE;
}
v4l2src->offset = 0;
+ /* activate settings for first frame */
+ v4l2src->ctrl_time = 0;
+ gst_object_sync_values (G_OBJECT (src), v4l2src->ctrl_time);
+
return TRUE;
}
GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset;
/* timestamps, LOCK to get clock and base time. */
+ /* FIXME: element clock and base_time is rarely changing */
GST_OBJECT_LOCK (v4l2src);
if ((clock = GST_ELEMENT_CLOCK (v4l2src))) {
/* we have a clock, get base time and ref clock */
}
}
+ /* activate settings for next frame */
+ if (GST_CLOCK_TIME_IS_VALID (v4l2src->duration)) {
+ v4l2src->ctrl_time += v4l2src->duration;
+ } else {
+ /* this is not very good (as it should be the next timestamp),
+ * still good enough for linear fades (as long as it is not -1)
+ */
+ v4l2src->ctrl_time = timestamp;
+ }
+ gst_object_sync_values (G_OBJECT (src), v4l2src->ctrl_time);
+ GST_INFO_OBJECT (src, "sync to %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (v4l2src->ctrl_time));
+
/* FIXME: use the timestamp from the buffer itself! */
GST_BUFFER_TIMESTAMP (*buf) = timestamp;
GST_BUFFER_DURATION (*buf) = v4l2src->duration;
gint fps_d, fps_n; /* framerate if device is open */
GstClockTime duration; /* duration of one frame */
+ GstClockTime ctrl_time;
+
GstV4l2SrcGetFunc get_frame;
};