mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
v4l2src: add controlable colorbalance parameters
Expose colorbalance controls as object properties (like we do on xvimagesink). Make them controlable.
This commit is contained in:
parent
d8a27ebe3e
commit
a08d4a5447
6 changed files with 113 additions and 3 deletions
|
@ -23,6 +23,7 @@ libgstvideo4linux2_la_SOURCES = gstv4l2.c \
|
||||||
|
|
||||||
libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
|
libgstvideo4linux2_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) \
|
||||||
$(GST_BASE_CFLAGS) \
|
$(GST_BASE_CFLAGS) \
|
||||||
|
$(GST_CONTROLLER_CFLAGS) \
|
||||||
$(GST_CFLAGS) \
|
$(GST_CFLAGS) \
|
||||||
$(X_CFLAGS) \
|
$(X_CFLAGS) \
|
||||||
$(LIBV4L2_CFLAGS) \
|
$(LIBV4L2_CFLAGS) \
|
||||||
|
@ -33,7 +34,9 @@ libgstvideo4linux2_la_LIBTOOLFLAGS = --tag=disable-static
|
||||||
|
|
||||||
libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
|
libgstvideo4linux2_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
|
||||||
$(GST_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) \
|
-lgstinterfaces-$(GST_MAJORMINOR) \
|
||||||
$(GST_LIBS) \
|
$(GST_LIBS) \
|
||||||
$(xv_libs) \
|
$(xv_libs) \
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "gst/gst-i18n-plugin.h"
|
#include "gst/gst-i18n-plugin.h"
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/controller/gstcontroller.h>
|
||||||
|
|
||||||
#include "gstv4l2object.h"
|
#include "gstv4l2object.h"
|
||||||
#include "gstv4l2src.h"
|
#include "gstv4l2src.h"
|
||||||
|
@ -46,6 +47,9 @@ plugin_init (GstPlugin * plugin)
|
||||||
GST_DEBUG_CATEGORY_INIT (v4l2_debug, "v4l2", 0, "V4L2 API calls");
|
GST_DEBUG_CATEGORY_INIT (v4l2_debug, "v4l2", 0, "V4L2 API calls");
|
||||||
GST_DEBUG_CATEGORY_GET (GST_CAT_PERFORMANCE, "GST_PERFORMANCE");
|
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,
|
if (!gst_element_register (plugin, "v4l2src", GST_RANK_PRIMARY,
|
||||||
GST_TYPE_V4L2SRC) ||
|
GST_TYPE_V4L2SRC) ||
|
||||||
!gst_element_register (plugin, "v4l2sink", GST_RANK_NONE,
|
!gst_element_register (plugin, "v4l2sink", GST_RANK_NONE,
|
||||||
|
|
|
@ -328,6 +328,27 @@ gst_v4l2_object_install_properties_helper (GObjectClass * gobject_class,
|
||||||
g_param_spec_flags ("flags", "Flags", "Device type flags",
|
g_param_spec_flags ("flags", "Flags", "Device type flags",
|
||||||
GST_TYPE_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS,
|
GST_TYPE_V4L2_DEVICE_FLAGS, DEFAULT_PROP_FLAGS,
|
||||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
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 *
|
GstV4l2Object *
|
||||||
|
@ -405,6 +426,30 @@ gst_v4l2_object_clear_format_list (GstV4l2Object * v4l2object)
|
||||||
return TRUE;
|
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
|
gboolean
|
||||||
gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object,
|
gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object,
|
||||||
|
@ -415,6 +460,21 @@ gst_v4l2_object_set_property_helper (GstV4l2Object * v4l2object,
|
||||||
g_free (v4l2object->videodev);
|
g_free (v4l2object->videodev);
|
||||||
v4l2object->videodev = g_value_dup_string (value);
|
v4l2object->videodev = g_value_dup_string (value);
|
||||||
break;
|
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
|
#if 0
|
||||||
case PROP_NORM:
|
case PROP_NORM:
|
||||||
if (GST_V4L2_IS_OPEN (v4l2object)) {
|
if (GST_V4L2_IS_OPEN (v4l2object)) {
|
||||||
|
@ -518,6 +578,24 @@ gst_v4l2_object_get_property_helper (GstV4l2Object * v4l2object,
|
||||||
g_value_set_flags (value, flags);
|
g_value_set_flags (value, flags);
|
||||||
break;
|
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:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/base/gstpushsrc.h>
|
#include <gst/base/gstpushsrc.h>
|
||||||
|
#include <gst/controller/gstcontroller.h>
|
||||||
|
|
||||||
#include <gst/interfaces/propertyprobe.h>
|
#include <gst/interfaces/propertyprobe.h>
|
||||||
|
|
||||||
|
@ -132,7 +133,11 @@ GType gst_v4l2_object_get_type (void);
|
||||||
PROP_DEVICE, \
|
PROP_DEVICE, \
|
||||||
PROP_DEVICE_NAME, \
|
PROP_DEVICE_NAME, \
|
||||||
PROP_DEVICE_FD, \
|
PROP_DEVICE_FD, \
|
||||||
PROP_FLAGS
|
PROP_FLAGS, \
|
||||||
|
PROP_BRIGHTNESS, \
|
||||||
|
PROP_CONTRAST, \
|
||||||
|
PROP_SATURATION, \
|
||||||
|
PROP_HUE
|
||||||
|
|
||||||
/* create/destroy */
|
/* create/destroy */
|
||||||
GstV4l2Object * gst_v4l2_object_new (GstElement * element,
|
GstV4l2Object * gst_v4l2_object_new (GstElement * element,
|
||||||
|
|
|
@ -626,7 +626,7 @@ gst_v4l2src_set_caps (GstBaseSrc * src, GstCaps * caps)
|
||||||
/* we want our own v4l2 type of fourcc codes */
|
/* we want our own v4l2 type of fourcc codes */
|
||||||
if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
|
if (!gst_v4l2_object_get_caps_info (v4l2src->v4l2object, caps, &format, &w,
|
||||||
&h, &fps_n, &fps_d, &size)) {
|
&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);
|
"can't get capture format from caps %" GST_PTR_FORMAT, caps);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -723,6 +723,10 @@ gst_v4l2src_start (GstBaseSrc * src)
|
||||||
|
|
||||||
v4l2src->offset = 0;
|
v4l2src->offset = 0;
|
||||||
|
|
||||||
|
/* activate settings for first frame */
|
||||||
|
v4l2src->ctrl_time = 0;
|
||||||
|
gst_object_sync_values (G_OBJECT (src), v4l2src->ctrl_time);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,6 +949,7 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
|
||||||
GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset;
|
GST_BUFFER_OFFSET_END (*buf) = v4l2src->offset;
|
||||||
|
|
||||||
/* timestamps, LOCK to get clock and base time. */
|
/* timestamps, LOCK to get clock and base time. */
|
||||||
|
/* FIXME: element clock and base_time is rarely changing */
|
||||||
GST_OBJECT_LOCK (v4l2src);
|
GST_OBJECT_LOCK (v4l2src);
|
||||||
if ((clock = GST_ELEMENT_CLOCK (v4l2src))) {
|
if ((clock = GST_ELEMENT_CLOCK (v4l2src))) {
|
||||||
/* we have a clock, get base time and ref clock */
|
/* we have a clock, get base time and ref clock */
|
||||||
|
@ -970,6 +975,19 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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! */
|
/* FIXME: use the timestamp from the buffer itself! */
|
||||||
GST_BUFFER_TIMESTAMP (*buf) = timestamp;
|
GST_BUFFER_TIMESTAMP (*buf) = timestamp;
|
||||||
GST_BUFFER_DURATION (*buf) = v4l2src->duration;
|
GST_BUFFER_DURATION (*buf) = v4l2src->duration;
|
||||||
|
|
|
@ -84,6 +84,8 @@ struct _GstV4l2Src
|
||||||
gint fps_d, fps_n; /* framerate if device is open */
|
gint fps_d, fps_n; /* framerate if device is open */
|
||||||
GstClockTime duration; /* duration of one frame */
|
GstClockTime duration; /* duration of one frame */
|
||||||
|
|
||||||
|
GstClockTime ctrl_time;
|
||||||
|
|
||||||
GstV4l2SrcGetFunc get_frame;
|
GstV4l2SrcGetFunc get_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue