mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-07 07:58:51 +00:00
Unification of the way to speak to v4l2 and v4l elements... Also fix a segfautl when doing gst-inspect v4l2src
Original commit message from CVS: Unification of the way to speak to v4l2 and v4l elements... Also fix a segfautl when doing gst-inspect v4l2src
This commit is contained in:
parent
fd90de3113
commit
1a8a2ef6e4
11 changed files with 212 additions and 327 deletions
|
@ -4,7 +4,7 @@ plugin_LTLIBRARIES = \
|
||||||
libgstv4l2element.la \
|
libgstv4l2element.la \
|
||||||
libgstv4l2src.la
|
libgstv4l2src.la
|
||||||
|
|
||||||
libgstv4l2element_la_SOURCES = gstv4l2element.c v4l2_calls.c v4l2-overlay_calls.c
|
libgstv4l2element_la_SOURCES = gstv4l2element.c v4l2_calls.c v4l2-overlay_calls.c gstv4l2element-marshal.c
|
||||||
libgstv4l2element_la_CFLAGS = $(GST_CFLAGS)
|
libgstv4l2element_la_CFLAGS = $(GST_CFLAGS)
|
||||||
libgstv4l2element_la_LIBADD =
|
libgstv4l2element_la_LIBADD =
|
||||||
libgstv4l2element_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstv4l2element_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
|
@ -15,4 +15,32 @@ libgstv4l2src_la_LIBADD = libgstv4l2element.la
|
||||||
libgstv4l2src_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstv4l2src_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
|
|
||||||
noinst_HEADERS = gstv4l2element.h v4l2_calls.h \
|
noinst_HEADERS = gstv4l2element.h v4l2_calls.h \
|
||||||
gstv4l2src.h v4l2src_calls.h
|
gstv4l2src.h v4l2src_calls.h gstv4l2element-marshal.h
|
||||||
|
|
||||||
|
EXTRA_libgstv4l2element_la_SOURCES = \
|
||||||
|
gstv4l2element-marshal.list
|
||||||
|
|
||||||
|
BUILT_SOURCES = \
|
||||||
|
gstv4l2element-marshal.c \
|
||||||
|
gstv4l2element-marshal.h
|
||||||
|
|
||||||
|
gstv4l2element-marshal.h: gstv4l2element-marshal.list
|
||||||
|
glib-genmarshal --header --prefix=gstv4l2_cclosure_marshal $(srcdir)/gstv4l2element-marshal.list > gstv4l2element-marshal.h.tmp
|
||||||
|
mv gstv4l2element-marshal.h.tmp gstv4l2element-marshal.h
|
||||||
|
|
||||||
|
gstv4l2element-marshal.c: gstv4l2element-marshal.list
|
||||||
|
echo "#include \"glib.h\"" > gstv4l2element-marshal.c.tmp
|
||||||
|
echo "#include \"glib-object.h\"" >> gstv4l2element-marshal.c.tmp
|
||||||
|
echo "#include \"gstv4l2element-marshal.h\"" >> gstv4l2element-marshal.c.tmp
|
||||||
|
glib-genmarshal --body --prefix=gstv4l2_cclosure_marshal $(srcdir)/gstv4l2element-marshal.list >> gstv4l2element-marshal.c.tmp
|
||||||
|
mv gstv4l2element-marshal.c.tmp gstv4l2element-marshal.c
|
||||||
|
|
||||||
|
# Don't want the generated marshal files in the dist
|
||||||
|
dist-hook:
|
||||||
|
rm -f $(distdir)/gstv4l2element-marshal.c
|
||||||
|
rm -f $(distdir)/gstv4l2element-marshal.h
|
||||||
|
|
||||||
|
# Clean generated files
|
||||||
|
distclean-local:
|
||||||
|
rm -f $(top_builddir)/src/element/gstv4l2element-marshal.c
|
||||||
|
rm -f $(top_builddir)/src/element/gstv4l2element-marshal.h
|
||||||
|
|
3
sys/v4l2/gstv4l2element-marshal.list
Normal file
3
sys/v4l2/gstv4l2element-marshal.list
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
BOOLEAN:INT,INT,INT,INT,POINTER,INT
|
||||||
|
BOOLEAN:STRING,INT
|
||||||
|
BOOLEAN:STRING,POINTER
|
|
@ -22,6 +22,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "v4l2_calls.h"
|
#include "v4l2_calls.h"
|
||||||
|
#include "gstv4l2element-marshal.h"
|
||||||
|
|
||||||
/* elementfactory details */
|
/* elementfactory details */
|
||||||
static GstElementDetails gst_v4l2element_details = {
|
static GstElementDetails gst_v4l2element_details = {
|
||||||
|
@ -39,6 +40,9 @@ enum {
|
||||||
/* FILL ME */
|
/* FILL ME */
|
||||||
SIGNAL_OPEN,
|
SIGNAL_OPEN,
|
||||||
SIGNAL_CLOSE,
|
SIGNAL_CLOSE,
|
||||||
|
SIGNAL_SET_VIDEOWINDOW,
|
||||||
|
SIGNAL_GET_ATTRIBUTE,
|
||||||
|
SIGNAL_SET_ATTRIBUTE,
|
||||||
LAST_SIGNAL
|
LAST_SIGNAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -54,15 +58,13 @@ enum {
|
||||||
ARG_FREQUENCY,
|
ARG_FREQUENCY,
|
||||||
ARG_SIGNAL_STRENGTH,
|
ARG_SIGNAL_STRENGTH,
|
||||||
ARG_HAS_AUDIO,
|
ARG_HAS_AUDIO,
|
||||||
ARG_ATTRIBUTE,
|
ARG_ATTRIBUTES,
|
||||||
ARG_ATTRIBUTE_SETS,
|
|
||||||
ARG_DEVICE,
|
ARG_DEVICE,
|
||||||
ARG_DEVICE_NAME,
|
ARG_DEVICE_NAME,
|
||||||
ARG_DEVICE_HAS_CAPTURE,
|
ARG_DEVICE_HAS_CAPTURE,
|
||||||
ARG_DEVICE_HAS_OVERLAY,
|
ARG_DEVICE_HAS_OVERLAY,
|
||||||
ARG_DEVICE_HAS_PLAYBACK,
|
ARG_DEVICE_HAS_PLAYBACK,
|
||||||
ARG_DISPLAY,
|
ARG_DISPLAY,
|
||||||
ARG_VIDEOWINDOW,
|
|
||||||
ARG_DO_OVERLAY,
|
ARG_DO_OVERLAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -153,11 +155,8 @@ gst_v4l2element_class_init (GstV4l2ElementClass *klass)
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HAS_AUDIO,
|
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HAS_AUDIO,
|
||||||
g_param_spec_boolean("has_audio","has_audio","has_audio",
|
g_param_spec_boolean("has_audio","has_audio","has_audio",
|
||||||
0,G_PARAM_READABLE));
|
0,G_PARAM_READABLE));
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ATTRIBUTE,
|
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ATTRIBUTES,
|
||||||
g_param_spec_pointer("attribute","attribute","attribute",
|
g_param_spec_pointer("attributes","attributes","attributes",
|
||||||
G_PARAM_READWRITE));
|
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ATTRIBUTE_SETS,
|
|
||||||
g_param_spec_pointer("attribute_sets","attribute_sets","attribute_sets",
|
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
|
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
|
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
|
||||||
|
@ -183,9 +182,37 @@ gst_v4l2element_class_init (GstV4l2ElementClass *klass)
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DO_OVERLAY,
|
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DO_OVERLAY,
|
||||||
g_param_spec_boolean("do_overlay","do_overlay","do_overlay",
|
g_param_spec_boolean("do_overlay","do_overlay","do_overlay",
|
||||||
0,G_PARAM_WRITABLE));
|
0,G_PARAM_WRITABLE));
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VIDEOWINDOW,
|
|
||||||
g_param_spec_pointer("videowindow","videowindow","videowindow",
|
/* actions */
|
||||||
G_PARAM_WRITABLE));
|
gst_v4l2element_signals[SIGNAL_SET_VIDEOWINDOW] =
|
||||||
|
g_signal_new ("set_videowindow",
|
||||||
|
G_TYPE_FROM_CLASS(klass),
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET(GstV4l2ElementClass, set_videowindow),
|
||||||
|
NULL, NULL,
|
||||||
|
gstv4l2_cclosure_marshal_BOOLEAN__INT_INT_INT_INT_POINTER_INT,
|
||||||
|
G_TYPE_BOOLEAN, 6,
|
||||||
|
G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT,
|
||||||
|
G_TYPE_POINTER, G_TYPE_INT);
|
||||||
|
klass->set_videowindow = gst_v4l2_set_window;
|
||||||
|
gst_v4l2element_signals[SIGNAL_GET_ATTRIBUTE] =
|
||||||
|
g_signal_new ("get_attribute",
|
||||||
|
G_TYPE_FROM_CLASS(klass),
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET(GstV4l2ElementClass, get_attribute),
|
||||||
|
NULL, NULL,
|
||||||
|
gstv4l2_cclosure_marshal_BOOLEAN__STRING_POINTER,
|
||||||
|
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_POINTER);
|
||||||
|
klass->get_attribute = gst_v4l2_get_attribute;
|
||||||
|
gst_v4l2element_signals[SIGNAL_SET_ATTRIBUTE] =
|
||||||
|
g_signal_new ("set_attribute",
|
||||||
|
G_TYPE_FROM_CLASS(klass),
|
||||||
|
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
|
||||||
|
G_STRUCT_OFFSET(GstV4l2ElementClass, set_attribute),
|
||||||
|
NULL, NULL,
|
||||||
|
gstv4l2_cclosure_marshal_BOOLEAN__STRING_INT,
|
||||||
|
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_INT);
|
||||||
|
klass->set_attribute = gst_v4l2_set_attribute;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
gst_v4l2element_signals[SIGNAL_OPEN] =
|
gst_v4l2element_signals[SIGNAL_OPEN] =
|
||||||
|
@ -220,9 +247,14 @@ gst_v4l2element_init (GstV4l2Element *v4l2element)
|
||||||
v4l2element->frequency = 0;
|
v4l2element->frequency = 0;
|
||||||
|
|
||||||
v4l2element->controls = NULL;
|
v4l2element->controls = NULL;
|
||||||
|
v4l2element->menus = NULL;
|
||||||
|
v4l2element->control_specs = NULL;
|
||||||
v4l2element->outputs = NULL;
|
v4l2element->outputs = NULL;
|
||||||
|
v4l2element->output_names = NULL;
|
||||||
v4l2element->inputs = NULL;
|
v4l2element->inputs = NULL;
|
||||||
|
v4l2element->input_names = NULL;
|
||||||
v4l2element->norms = NULL;
|
v4l2element->norms = NULL;
|
||||||
|
v4l2element->norm_names = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -267,13 +299,6 @@ gst_v4l2element_set_property (GObject *object,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ARG_ATTRIBUTE:
|
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element)) {
|
|
||||||
gst_v4l2_set_attribute(v4l2element,
|
|
||||||
((GstV4l2Attribute*)g_value_get_pointer(value))->index,
|
|
||||||
((GstV4l2Attribute*)g_value_get_pointer(value))->value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARG_DEVICE:
|
case ARG_DEVICE:
|
||||||
if (!GST_V4L2_IS_OPEN(v4l2element)) {
|
if (!GST_V4L2_IS_OPEN(v4l2element)) {
|
||||||
if (v4l2element->device)
|
if (v4l2element->device)
|
||||||
|
@ -285,15 +310,6 @@ gst_v4l2element_set_property (GObject *object,
|
||||||
if (!gst_v4l2_set_display(v4l2element, g_value_get_string(value)))
|
if (!gst_v4l2_set_display(v4l2element, g_value_get_string(value)))
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case ARG_VIDEOWINDOW:
|
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element)) {
|
|
||||||
GByteArray *array = (GByteArray *) g_value_get_pointer(value);
|
|
||||||
struct v4l2_clip *clips = (struct v4l2_clip *) array->data;
|
|
||||||
gst_v4l2_set_window(v4l2element,
|
|
||||||
clips->c.left, clips->c.top, clips->c.width, clips->c.height,
|
|
||||||
&clips[1], array->len/sizeof(struct v4l2_clip)-1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARG_DO_OVERLAY:
|
case ARG_DO_OVERLAY:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element)) {
|
if (GST_V4L2_IS_OPEN(v4l2element)) {
|
||||||
if (!gst_v4l2_enable_overlay(v4l2element, g_value_get_boolean(value)))
|
if (!gst_v4l2_enable_overlay(v4l2element, g_value_get_boolean(value)))
|
||||||
|
@ -316,7 +332,6 @@ gst_v4l2element_get_property (GObject *object,
|
||||||
GstV4l2Element *v4l2element;
|
GstV4l2Element *v4l2element;
|
||||||
gint temp_i = 0;
|
gint temp_i = 0;
|
||||||
gulong temp_ul = 0;
|
gulong temp_ul = 0;
|
||||||
GList *list = NULL;
|
|
||||||
|
|
||||||
/* it's not null if we got it, but it might not be ours */
|
/* it's not null if we got it, but it might not be ours */
|
||||||
g_return_if_fail(GST_IS_V4L2ELEMENT(object));
|
g_return_if_fail(GST_IS_V4L2ELEMENT(object));
|
||||||
|
@ -329,9 +344,7 @@ gst_v4l2element_get_property (GObject *object,
|
||||||
g_value_set_int(value, temp_i);
|
g_value_set_int(value, temp_i);
|
||||||
break;
|
break;
|
||||||
case ARG_CHANNEL_NAMES:
|
case ARG_CHANNEL_NAMES:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
g_value_set_pointer(value, v4l2element->input_names);
|
||||||
list = gst_v4l2_get_input_names(v4l2element);
|
|
||||||
g_value_set_pointer(value, list);
|
|
||||||
break;
|
break;
|
||||||
case ARG_OUTPUT:
|
case ARG_OUTPUT:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||||
|
@ -339,9 +352,7 @@ gst_v4l2element_get_property (GObject *object,
|
||||||
g_value_set_int(value, temp_i);
|
g_value_set_int(value, temp_i);
|
||||||
break;
|
break;
|
||||||
case ARG_OUTPUT_NAMES:
|
case ARG_OUTPUT_NAMES:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
g_value_set_pointer(value, v4l2element->output_names);
|
||||||
list = gst_v4l2_get_output_names(v4l2element);
|
|
||||||
g_value_set_pointer(value, list);
|
|
||||||
break;
|
break;
|
||||||
case ARG_NORM:
|
case ARG_NORM:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||||
|
@ -349,9 +360,7 @@ gst_v4l2element_get_property (GObject *object,
|
||||||
g_value_set_int(value, temp_i);
|
g_value_set_int(value, temp_i);
|
||||||
break;
|
break;
|
||||||
case ARG_NORM_NAMES:
|
case ARG_NORM_NAMES:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
g_value_set_pointer(value, v4l2element->norm_names);
|
||||||
list = gst_v4l2_get_norm_names(v4l2element);
|
|
||||||
g_value_set_pointer(value, list);
|
|
||||||
break;
|
break;
|
||||||
case ARG_HAS_TUNER:
|
case ARG_HAS_TUNER:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||||
|
@ -373,23 +382,15 @@ gst_v4l2element_get_property (GObject *object,
|
||||||
temp_i = gst_v4l2_has_audio(v4l2element);
|
temp_i = gst_v4l2_has_audio(v4l2element);
|
||||||
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
|
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
|
||||||
break;
|
break;
|
||||||
case ARG_ATTRIBUTE:
|
case ARG_ATTRIBUTES:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
g_value_set_pointer(value, v4l2element->control_specs);
|
||||||
gst_v4l2_get_attribute(v4l2element,
|
|
||||||
((GstV4l2Attribute*)g_value_get_pointer(value))->index, &temp_i);
|
|
||||||
((GstV4l2Attribute*)g_value_get_pointer(value))->value = temp_i;
|
|
||||||
break;
|
|
||||||
case ARG_ATTRIBUTE_SETS:
|
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
|
||||||
list = gst_v4l2_get_attributes(v4l2element);
|
|
||||||
g_value_set_pointer(value, list);
|
|
||||||
break;
|
break;
|
||||||
case ARG_DEVICE:
|
case ARG_DEVICE:
|
||||||
g_value_set_string(value, g_strdup(v4l2element->device));
|
g_value_set_string(value, v4l2element->device);
|
||||||
break;
|
break;
|
||||||
case ARG_DEVICE_NAME:
|
case ARG_DEVICE_NAME:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element))
|
if (GST_V4L2_IS_OPEN(v4l2element))
|
||||||
g_value_set_string(value, g_strdup(v4l2element->vcap.card));
|
g_value_set_string(value, v4l2element->vcap.card);
|
||||||
break;
|
break;
|
||||||
case ARG_DEVICE_HAS_CAPTURE:
|
case ARG_DEVICE_HAS_CAPTURE:
|
||||||
if (GST_V4L2_IS_OPEN(v4l2element) &&
|
if (GST_V4L2_IS_OPEN(v4l2element) &&
|
||||||
|
|
|
@ -41,28 +41,6 @@
|
||||||
typedef struct _GstV4l2Element GstV4l2Element;
|
typedef struct _GstV4l2Element GstV4l2Element;
|
||||||
typedef struct _GstV4l2ElementClass GstV4l2ElementClass;
|
typedef struct _GstV4l2ElementClass GstV4l2ElementClass;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_INTEGER = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_BOOLEAN = V4L2_CTRL_TYPE_BOOLEAN,
|
|
||||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_MENU = V4L2_CTRL_TYPE_MENU,
|
|
||||||
GST_V4L2_ATTRIBUTE_VALUE_TYPE_BUTTON = V4L2_CTRL_TYPE_BUTTON,
|
|
||||||
} GstV4l2AttributeValueType;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GST_V4L2_ATTRIBUTE_TYPE_VIDEO,
|
|
||||||
GST_V4L2_ATTRIBUTE_TYPE_AUDIO,
|
|
||||||
GST_V4L2_ATTRIBUTE_TYPE_OTHER,
|
|
||||||
} GstV4l2AttributeType;
|
|
||||||
|
|
||||||
typedef struct _GstV4l2Attribute {
|
|
||||||
gint index;
|
|
||||||
gchar *name;
|
|
||||||
GstV4l2AttributeType type;
|
|
||||||
GstV4l2AttributeValueType val_type;
|
|
||||||
gint min, max, value;
|
|
||||||
GList *list_items; /* in case of 'list' */
|
|
||||||
} GstV4l2Attribute;
|
|
||||||
|
|
||||||
struct _GstV4l2Element {
|
struct _GstV4l2Element {
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
|
@ -79,10 +57,10 @@ struct _GstV4l2Element {
|
||||||
struct v4l2_capability vcap;
|
struct v4l2_capability vcap;
|
||||||
|
|
||||||
/* the toys available to us */
|
/* the toys available to us */
|
||||||
GList /*v4l2_input*/ *inputs;
|
GList /*v4l2_input*/ *inputs, *input_names;
|
||||||
GList /*v4l2_output*/ *outputs;
|
GList /*v4l2_output*/ *outputs, *output_names;
|
||||||
GList /*v4l2_enumstd*/ *norms;
|
GList /*v4l2_enumstd*/ *norms, *norm_names;
|
||||||
GList /*v4l2_queryctrl*/ *controls;
|
GList /*v4l2_queryctrl*/ *controls, *control_specs;
|
||||||
GList /*GList:v4l2_querymenu*/ *menus;
|
GList /*GList:v4l2_querymenu*/ *menus;
|
||||||
|
|
||||||
/* caching values */
|
/* caching values */
|
||||||
|
@ -96,10 +74,25 @@ struct _GstV4l2ElementClass {
|
||||||
GstElementClass parent_class;
|
GstElementClass parent_class;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (*open) (GstElement *element,
|
void (*open) (GstElement *element,
|
||||||
const gchar *device);
|
const gchar *device);
|
||||||
void (*close) (GstElement *element,
|
void (*close) (GstElement *element,
|
||||||
const gchar *device);
|
const gchar *device);
|
||||||
|
|
||||||
|
/* actions */
|
||||||
|
gboolean (*set_videowindow) (GstElement *element,
|
||||||
|
gint x_offset,
|
||||||
|
gint y_offset,
|
||||||
|
gint height,
|
||||||
|
gint width,
|
||||||
|
struct v4l2_clip *clips,
|
||||||
|
gint num_clips);
|
||||||
|
gboolean (*get_attribute) (GstElement *element,
|
||||||
|
const gchar *attr_name,
|
||||||
|
int *value);
|
||||||
|
gboolean (*set_attribute) (GstElement *element,
|
||||||
|
const gchar *attr_name,
|
||||||
|
const int value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,6 @@ enum {
|
||||||
ARG_HEIGHT,
|
ARG_HEIGHT,
|
||||||
ARG_PALETTE,
|
ARG_PALETTE,
|
||||||
ARG_PALETTE_NAMES,
|
ARG_PALETTE_NAMES,
|
||||||
ARG_FOURCC,
|
|
||||||
ARG_FOURCC_LIST,
|
|
||||||
ARG_NUMBUFS,
|
ARG_NUMBUFS,
|
||||||
ARG_BUFSIZE
|
ARG_BUFSIZE
|
||||||
};
|
};
|
||||||
|
@ -154,12 +152,6 @@ gst_v4l2src_class_init (GstV4l2SrcClass *klass)
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PALETTE_NAMES,
|
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PALETTE_NAMES,
|
||||||
g_param_spec_pointer("palette_name","palette_name","palette_name",
|
g_param_spec_pointer("palette_name","palette_name","palette_name",
|
||||||
G_PARAM_READABLE));
|
G_PARAM_READABLE));
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FOURCC,
|
|
||||||
g_param_spec_string("fourcc","fourcc","fourcc",
|
|
||||||
NULL,G_PARAM_READWRITE));
|
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FOURCC_LIST,
|
|
||||||
g_param_spec_pointer("fourcc_list","fourcc_list","fourcc_list",
|
|
||||||
G_PARAM_READABLE));
|
|
||||||
|
|
||||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUMBUFS,
|
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NUMBUFS,
|
||||||
g_param_spec_int("num_buffers","num_buffers","num_buffers",
|
g_param_spec_int("num_buffers","num_buffers","num_buffers",
|
||||||
|
@ -201,6 +193,7 @@ gst_v4l2src_init (GstV4l2Src *v4l2src)
|
||||||
v4l2src->breq.count = 0;
|
v4l2src->breq.count = 0;
|
||||||
|
|
||||||
v4l2src->formats = NULL;
|
v4l2src->formats = NULL;
|
||||||
|
v4l2src->format_list = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -742,19 +735,6 @@ gst_v4l2src_set_property (GObject *object,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_FOURCC:
|
|
||||||
if (!GST_V4L2_IS_ACTIVE(GST_V4L2ELEMENT(v4l2src))) {
|
|
||||||
gint i;
|
|
||||||
const gchar *formatstr = g_value_get_string(value);
|
|
||||||
guint32 fourcc = GST_MAKE_FOURCC(formatstr[0],formatstr[1],formatstr[2],formatstr[3]);
|
|
||||||
for (i=0;i<g_list_length(v4l2src->formats);i++) {
|
|
||||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, i);
|
|
||||||
if (fmt->pixelformat == fourcc)
|
|
||||||
v4l2src->palette = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ARG_NUMBUFS:
|
case ARG_NUMBUFS:
|
||||||
if (!GST_V4L2_IS_ACTIVE(GST_V4L2ELEMENT(v4l2src))) {
|
if (!GST_V4L2_IS_ACTIVE(GST_V4L2ELEMENT(v4l2src))) {
|
||||||
v4l2src->breq.count = g_value_get_int(value);
|
v4l2src->breq.count = g_value_get_int(value);
|
||||||
|
@ -793,18 +773,7 @@ gst_v4l2src_get_property (GObject *object,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_PALETTE_NAMES:
|
case ARG_PALETTE_NAMES:
|
||||||
g_value_set_pointer(value, gst_v4l2src_get_format_list(v4l2src));
|
g_value_set_pointer(value, v4l2src->format_list);
|
||||||
break;
|
|
||||||
|
|
||||||
case ARG_FOURCC: {
|
|
||||||
struct v4l2_fmtdesc *fmt = g_list_nth_data(v4l2src->formats, v4l2src->palette);
|
|
||||||
guint32 print_format = GUINT32_FROM_LE(fmt->pixelformat);
|
|
||||||
gchar *print_format_str = (gchar *) &print_format;
|
|
||||||
g_value_set_string(value, g_strndup(print_format_str, 4));
|
|
||||||
break; }
|
|
||||||
|
|
||||||
case ARG_FOURCC_LIST:
|
|
||||||
g_value_set_pointer(value, gst_v4l2src_get_fourcc_list(v4l2src));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARG_NUMBUFS:
|
case ARG_NUMBUFS:
|
||||||
|
|
|
@ -45,7 +45,7 @@ struct _GstV4l2Src {
|
||||||
GstPad *srcpad;
|
GstPad *srcpad;
|
||||||
|
|
||||||
/* internal lists */
|
/* internal lists */
|
||||||
GList /*v4l2_fmtdesc*/ *formats; /* list of available capture formats */
|
GList /*v4l2_fmtdesc*/ *formats, *format_list; /* list of available capture formats */
|
||||||
|
|
||||||
/* buffer properties */
|
/* buffer properties */
|
||||||
struct v4l2_buffer bufsettings;
|
struct v4l2_buffer bufsettings;
|
||||||
|
|
|
@ -81,7 +81,7 @@ gst_v4l2_set_display (GstV4l2Element *v4l2element,
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_set_window (GstV4l2Element *v4l2element,
|
gst_v4l2_set_window (GstElement *element,
|
||||||
gint x,
|
gint x,
|
||||||
gint y,
|
gint y,
|
||||||
gint w,
|
gint w,
|
||||||
|
@ -90,6 +90,7 @@ gst_v4l2_set_window (GstV4l2Element *v4l2element,
|
||||||
gint num_clips)
|
gint num_clips)
|
||||||
{
|
{
|
||||||
struct v4l2_format fmt;
|
struct v4l2_format fmt;
|
||||||
|
GstV4l2Element *v4l2element = GST_V4L2ELEMENT(element);
|
||||||
|
|
||||||
DEBUG("trying to set video window to %dx%d,%d,%d", x,y,w,h);
|
DEBUG("trying to set video window to %dx%d,%d,%d", x,y,w,h);
|
||||||
GST_V4L2_CHECK_OVERLAY(v4l2element);
|
GST_V4L2_CHECK_OVERLAY(v4l2element);
|
||||||
|
|
|
@ -90,6 +90,8 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
||||||
inpptr = g_malloc(sizeof(input));
|
inpptr = g_malloc(sizeof(input));
|
||||||
memcpy(inpptr, &input, sizeof(input));
|
memcpy(inpptr, &input, sizeof(input));
|
||||||
v4l2element->inputs = g_list_append(v4l2element->inputs, inpptr);
|
v4l2element->inputs = g_list_append(v4l2element->inputs, inpptr);
|
||||||
|
|
||||||
|
v4l2element->input_names = g_list_append(v4l2element->input_names, inpptr->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* outputs */
|
/* outputs */
|
||||||
|
@ -109,6 +111,8 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
||||||
outptr = g_malloc(sizeof(output));
|
outptr = g_malloc(sizeof(output));
|
||||||
memcpy(outptr, &output, sizeof(output));
|
memcpy(outptr, &output, sizeof(output));
|
||||||
v4l2element->outputs = g_list_append(v4l2element->outputs, outptr);
|
v4l2element->outputs = g_list_append(v4l2element->outputs, outptr);
|
||||||
|
|
||||||
|
v4l2element->output_names = g_list_append(v4l2element->output_names, outptr->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* norms... */
|
/* norms... */
|
||||||
|
@ -128,12 +132,15 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
||||||
stdptr = g_malloc(sizeof(standard));
|
stdptr = g_malloc(sizeof(standard));
|
||||||
memcpy(stdptr, &standard, sizeof(standard));
|
memcpy(stdptr, &standard, sizeof(standard));
|
||||||
v4l2element->norms = g_list_append(v4l2element->norms, stdptr);
|
v4l2element->norms = g_list_append(v4l2element->norms, stdptr);
|
||||||
|
|
||||||
|
v4l2element->norm_names = g_list_append(v4l2element->norm_names, stdptr->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and lastly, controls+menus (if appropriate) */
|
/* and lastly, controls+menus (if appropriate) */
|
||||||
for (n=V4L2_CID_BASE;;n++) {
|
for (n=V4L2_CID_BASE;;n++) {
|
||||||
struct v4l2_queryctrl control, *ctrlptr;
|
struct v4l2_queryctrl control, *ctrlptr;
|
||||||
GList *menus = NULL;
|
GList *menus = NULL;
|
||||||
|
GParamSpec *spec = NULL;
|
||||||
/* hacky... */
|
/* hacky... */
|
||||||
if (n == V4L2_CID_LASTP1)
|
if (n == V4L2_CID_LASTP1)
|
||||||
n = V4L2_CID_PRIVATE_BASE;
|
n = V4L2_CID_PRIVATE_BASE;
|
||||||
|
@ -178,6 +185,30 @@ gst_v4l2_fill_lists (GstV4l2Element *v4l2element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v4l2element->menus = g_list_append(v4l2element->menus, menus);
|
v4l2element->menus = g_list_append(v4l2element->menus, menus);
|
||||||
|
|
||||||
|
switch (control.type) {
|
||||||
|
case V4L2_CTRL_TYPE_INTEGER:
|
||||||
|
spec = g_param_spec_int(ctrlptr->name, ctrlptr->name,
|
||||||
|
ctrlptr->name, ctrlptr->minimum, ctrlptr->maximum,
|
||||||
|
ctrlptr->default_value, G_PARAM_READWRITE);
|
||||||
|
break;
|
||||||
|
case V4L2_CTRL_TYPE_BOOLEAN:
|
||||||
|
spec = g_param_spec_boolean(ctrlptr->name, ctrlptr->name,
|
||||||
|
ctrlptr->name, ctrlptr->default_value,
|
||||||
|
G_PARAM_READWRITE);
|
||||||
|
break;
|
||||||
|
case V4L2_CTRL_TYPE_MENU:
|
||||||
|
/* hacky... we abuse pointer for 'no value' */
|
||||||
|
spec = g_param_spec_pointer(ctrlptr->name, ctrlptr->name,
|
||||||
|
ctrlptr->name, G_PARAM_WRITABLE);
|
||||||
|
break;
|
||||||
|
case V4L2_CTRL_TYPE_BUTTON:
|
||||||
|
/* help?!? */
|
||||||
|
spec = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
v4l2element->control_specs = g_list_append(v4l2element->control_specs, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -195,16 +226,22 @@ gst_v4l2_empty_lists (GstV4l2Element *v4l2element)
|
||||||
v4l2element->inputs = g_list_remove(v4l2element->inputs, data);
|
v4l2element->inputs = g_list_remove(v4l2element->inputs, data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
g_list_free(v4l2element->input_names);
|
||||||
|
v4l2element->input_names = NULL;
|
||||||
while (g_list_length(v4l2element->outputs) > 0) {
|
while (g_list_length(v4l2element->outputs) > 0) {
|
||||||
gpointer data = g_list_nth_data(v4l2element->outputs, 0);
|
gpointer data = g_list_nth_data(v4l2element->outputs, 0);
|
||||||
v4l2element->outputs = g_list_remove(v4l2element->outputs, data);
|
v4l2element->outputs = g_list_remove(v4l2element->outputs, data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
g_list_free(v4l2element->output_names);
|
||||||
|
v4l2element->output_names = NULL;
|
||||||
while (g_list_length(v4l2element->norms) > 0) {
|
while (g_list_length(v4l2element->norms) > 0) {
|
||||||
gpointer data = g_list_nth_data(v4l2element->norms, 0);
|
gpointer data = g_list_nth_data(v4l2element->norms, 0);
|
||||||
v4l2element->norms = g_list_remove(v4l2element->norms, data);
|
v4l2element->norms = g_list_remove(v4l2element->norms, data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
g_list_free(v4l2element->norm_names);
|
||||||
|
v4l2element->norm_names = NULL;
|
||||||
while (g_list_length(v4l2element->controls) > 0) {
|
while (g_list_length(v4l2element->controls) > 0) {
|
||||||
gpointer data = g_list_nth_data(v4l2element->controls, 0);
|
gpointer data = g_list_nth_data(v4l2element->controls, 0);
|
||||||
v4l2element->controls = g_list_remove(v4l2element->controls, data);
|
v4l2element->controls = g_list_remove(v4l2element->controls, data);
|
||||||
|
@ -220,6 +257,11 @@ gst_v4l2_empty_lists (GstV4l2Element *v4l2element)
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (g_list_length(v4l2element->control_specs) > 0) {
|
||||||
|
gpointer data = g_list_nth_data(v4l2element->control_specs, 0);
|
||||||
|
v4l2element->control_specs = g_list_remove(v4l2element->control_specs, data);
|
||||||
|
g_param_spec_unref(G_PARAM_SPEC(data));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -375,29 +417,6 @@ gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2_get_norm_names()
|
|
||||||
* Get the list of available norms
|
|
||||||
* return value: the list
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
GList *
|
|
||||||
gst_v4l2_get_norm_names (GstV4l2Element *v4l2element)
|
|
||||||
{
|
|
||||||
GList *names = NULL;
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
DEBUG("getting a list of norm names");
|
|
||||||
|
|
||||||
for (n=0;n<g_list_length(v4l2element->norms);n++) {
|
|
||||||
struct v4l2_standard *standard = (struct v4l2_standard *) g_list_nth_data(v4l2element->norms, n);
|
|
||||||
names = g_list_append(names, g_strdup(standard->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l2_get_input()
|
* gst_v4l2_get_input()
|
||||||
* Get the input of the current device
|
* Get the input of the current device
|
||||||
|
@ -458,29 +477,6 @@ gst_v4l2_set_input (GstV4l2Element *v4l2element,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2_get_input_names()
|
|
||||||
* Get the list of available input channels
|
|
||||||
* return value: the list
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
GList *
|
|
||||||
gst_v4l2_get_input_names (GstV4l2Element *v4l2element)
|
|
||||||
{
|
|
||||||
GList *names = NULL;
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
DEBUG("getting a list of input names");
|
|
||||||
|
|
||||||
for (n=0;n<g_list_length(v4l2element->inputs);n++) {
|
|
||||||
struct v4l2_input *input = (struct v4l2_input *) g_list_nth_data(v4l2element->inputs, n);
|
|
||||||
names = g_list_append(names, g_strdup(input->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l2_get_output()
|
* gst_v4l2_get_output()
|
||||||
* Get the output of the current device
|
* Get the output of the current device
|
||||||
|
@ -542,30 +538,7 @@ gst_v4l2_set_output (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l2_get_output_names()
|
* gst_v4l2_has_tuner():
|
||||||
* Get the list of available output channels
|
|
||||||
* return value: the list, or NULL on error
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
GList *
|
|
||||||
gst_v4l2_get_output_names (GstV4l2Element *v4l2element)
|
|
||||||
{
|
|
||||||
GList *names = NULL;
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
DEBUG("getting a list of output names");
|
|
||||||
|
|
||||||
for (n=0;n<g_list_length(v4l2element->outputs);n++) {
|
|
||||||
struct v4l2_output *output = (struct v4l2_output *) g_list_nth_data(v4l2element->outputs, n);
|
|
||||||
names = g_list_append(names, g_strdup(output->name));
|
|
||||||
}
|
|
||||||
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l_has_tuner():
|
|
||||||
* Check whether the device has a tuner
|
* Check whether the device has a tuner
|
||||||
* return value: TRUE if it has a tuner, else FALSE
|
* return value: TRUE if it has a tuner, else FALSE
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
@ -595,7 +568,7 @@ gst_v4l2_has_tuner (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_get_frequency():
|
* gst_v4l2_get_frequency():
|
||||||
* get the current frequency
|
* get the current frequency
|
||||||
* return value: TRUE on success, FALSE on error
|
* return value: TRUE on success, FALSE on error
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
@ -628,7 +601,7 @@ gst_v4l2_get_frequency (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_set_frequency():
|
* gst_v4l2_set_frequency():
|
||||||
* set frequency
|
* set frequency
|
||||||
* return value: TRUE on success, FALSE on error
|
* return value: TRUE on success, FALSE on error
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
@ -661,7 +634,7 @@ gst_v4l2_set_frequency (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_signal_strength():
|
* gst_v4l2_signal_strength():
|
||||||
* get the strength of the signal on the current input
|
* get the strength of the signal on the current input
|
||||||
* return value: TRUE on success, FALSE on error
|
* return value: TRUE on success, FALSE on error
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
@ -689,7 +662,7 @@ gst_v4l2_signal_strength (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_has_audio():
|
* gst_v4l2_has_audio():
|
||||||
* Check whether the device has audio capabilities
|
* Check whether the device has audio capabilities
|
||||||
* return value: TRUE if it has a tuner, else FALSE
|
* return value: TRUE if it has a tuner, else FALSE
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
@ -713,96 +686,53 @@ gst_v4l2_has_audio (GstV4l2Element *v4l2element)
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_get_attributes():
|
* gst_v4l2_control_name_to_num():
|
||||||
* get a list of attributes available on this device
|
* convert name to num (-1 if nothing)
|
||||||
* return value: the list
|
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
|
||||||
GList *
|
static gint
|
||||||
gst_v4l2_get_attributes (GstV4l2Element *v4l2element)
|
gst_v4l2_control_name_to_num (GstV4l2Element *v4l2element,
|
||||||
|
const gchar *name)
|
||||||
{
|
{
|
||||||
gint i;
|
GList *item;
|
||||||
GList *list = NULL;
|
|
||||||
|
|
||||||
DEBUG("getting a list of available attributes");
|
for (item = v4l2element->controls; item != NULL; item = item->next) {
|
||||||
|
struct v4l2_queryctrl *ctrl = item->data;
|
||||||
for (i=0;i<g_list_length(v4l2element->controls);i++) {
|
if (!strcmp(ctrl->name, name))
|
||||||
struct v4l2_queryctrl *control = (struct v4l2_queryctrl *) g_list_nth_data(v4l2element->controls, i);
|
return ctrl->id;
|
||||||
GstV4l2Attribute* attribute = g_malloc(sizeof(GstV4l2Attribute));
|
|
||||||
attribute->name = g_strdup(control->name);
|
|
||||||
attribute->index = i;
|
|
||||||
attribute->list_items = NULL;
|
|
||||||
attribute->val_type = control->type;
|
|
||||||
if (control->type == V4L2_CTRL_TYPE_MENU) {
|
|
||||||
/* list items */
|
|
||||||
gint n;
|
|
||||||
GList *menus = (GList *) g_list_nth_data(v4l2element->menus, i);
|
|
||||||
for (n=0;n<g_list_length(menus);n++) {
|
|
||||||
struct v4l2_querymenu *menu = g_list_nth_data(menus, n);
|
|
||||||
attribute->list_items = g_list_append(attribute->list_items,
|
|
||||||
g_strdup(menu->name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (control->id) {
|
|
||||||
case V4L2_CID_BRIGHTNESS:
|
|
||||||
case V4L2_CID_CONTRAST:
|
|
||||||
case V4L2_CID_SATURATION:
|
|
||||||
case V4L2_CID_HUE:
|
|
||||||
case V4L2_CID_BLACK_LEVEL:
|
|
||||||
case V4L2_CID_AUTO_WHITE_BALANCE:
|
|
||||||
case V4L2_CID_DO_WHITE_BALANCE:
|
|
||||||
case V4L2_CID_RED_BALANCE:
|
|
||||||
case V4L2_CID_BLUE_BALANCE:
|
|
||||||
case V4L2_CID_GAMMA:
|
|
||||||
case V4L2_CID_EXPOSURE:
|
|
||||||
case V4L2_CID_AUTOGAIN:
|
|
||||||
case V4L2_CID_GAIN:
|
|
||||||
case V4L2_CID_HFLIP:
|
|
||||||
case V4L2_CID_VFLIP:
|
|
||||||
case V4L2_CID_HCENTER:
|
|
||||||
case V4L2_CID_VCENTER:
|
|
||||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_VIDEO;
|
|
||||||
break;
|
|
||||||
case V4L2_CID_AUDIO_VOLUME:
|
|
||||||
case V4L2_CID_AUDIO_BALANCE:
|
|
||||||
case V4L2_CID_AUDIO_BASS:
|
|
||||||
case V4L2_CID_AUDIO_TREBLE:
|
|
||||||
case V4L2_CID_AUDIO_MUTE:
|
|
||||||
case V4L2_CID_AUDIO_LOUDNESS:
|
|
||||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_AUDIO;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
attribute->type = GST_V4L2_ATTRIBUTE_TYPE_OTHER;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gst_v4l2_get_attribute(v4l2element, i, &attribute->value);
|
|
||||||
attribute->min = control->minimum;
|
|
||||||
attribute->max = control->maximum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return list;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_get_attribute():
|
* gst_v4l2_get_attribute():
|
||||||
* try to get the value of one specific attribute
|
* try to get the value of one specific attribute
|
||||||
* return value: TRUE on success, FALSE on error
|
* return value: TRUE on success, FALSE on error
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_get_attribute (GstV4l2Element *v4l2element,
|
gst_v4l2_get_attribute (GstElement *element,
|
||||||
gint attribute_num,
|
const gchar *name,
|
||||||
gint *value)
|
int *value)
|
||||||
{
|
{
|
||||||
struct v4l2_control control;
|
struct v4l2_control control;
|
||||||
|
GstV4l2Element *v4l2element;
|
||||||
|
gint attribute_num = -1;
|
||||||
|
|
||||||
|
g_return_val_if_fail(element != NULL && name != NULL && value != NULL, FALSE);
|
||||||
|
g_return_val_if_fail(GST_IS_V4L2ELEMENT(element), FALSE);
|
||||||
|
v4l2element = GST_V4L2ELEMENT(element);
|
||||||
|
|
||||||
DEBUG("getting value of attribute %d", attribute_num);
|
DEBUG("getting value of attribute %d", attribute_num);
|
||||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||||
|
|
||||||
if (attribute_num < 0 || attribute_num >= g_list_length(v4l2element->controls)) {
|
attribute_num = gst_v4l2_control_name_to_num(v4l2element, name);
|
||||||
|
|
||||||
|
if (attribute_num < 0) {
|
||||||
gst_element_error(GST_ELEMENT(v4l2element),
|
gst_element_error(GST_ELEMENT(v4l2element),
|
||||||
"Invalid control ID %d", attribute_num);
|
"Invalid control %s", name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -810,8 +740,8 @@ gst_v4l2_get_attribute (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
if (ioctl(v4l2element->video_fd, VIDIOC_G_CTRL, &control) < 0) {
|
if (ioctl(v4l2element->video_fd, VIDIOC_G_CTRL, &control) < 0) {
|
||||||
gst_element_error(GST_ELEMENT(v4l2element),
|
gst_element_error(GST_ELEMENT(v4l2element),
|
||||||
"Failed to get value for control %d on device %s: %s",
|
"Failed to get value for control %s (%d) on device %s: %s",
|
||||||
attribute_num, v4l2element->device, g_strerror(errno));
|
name, attribute_num, v4l2element->device, g_strerror(errno));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,24 +752,32 @@ gst_v4l2_get_attribute (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* gst_v4l_set_attribute():
|
* gst_v4l2_set_attribute():
|
||||||
* try to set the value of one specific attribute
|
* try to set the value of one specific attribute
|
||||||
* return value: TRUE on success, FALSE on error
|
* return value: TRUE on success, FALSE on error
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_v4l2_set_attribute (GstV4l2Element *v4l2element,
|
gst_v4l2_set_attribute (GstElement *element,
|
||||||
gint attribute_num,
|
const gchar *name,
|
||||||
gint value)
|
const int value)
|
||||||
{
|
{
|
||||||
struct v4l2_control control;
|
struct v4l2_control control;
|
||||||
|
GstV4l2Element *v4l2element;
|
||||||
|
gint attribute_num = -1;
|
||||||
|
|
||||||
|
g_return_val_if_fail(element != NULL && name != NULL, FALSE);
|
||||||
|
g_return_val_if_fail(GST_IS_V4L2ELEMENT(element), FALSE);
|
||||||
|
v4l2element = GST_V4L2ELEMENT(element);
|
||||||
|
|
||||||
DEBUG("setting value of attribute %d to %d", attribute_num, value);
|
DEBUG("setting value of attribute %d to %d", attribute_num, value);
|
||||||
GST_V4L2_CHECK_OPEN(v4l2element);
|
GST_V4L2_CHECK_OPEN(v4l2element);
|
||||||
|
|
||||||
if (attribute_num < 0 || attribute_num >= g_list_length(v4l2element->controls)) {
|
attribute_num = gst_v4l2_control_name_to_num(v4l2element, name);
|
||||||
|
|
||||||
|
if (attribute_num < 0) {
|
||||||
gst_element_error(GST_ELEMENT(v4l2element),
|
gst_element_error(GST_ELEMENT(v4l2element),
|
||||||
"Invalid control ID %d", attribute_num);
|
"Invalid control %s", name);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,8 +786,8 @@ gst_v4l2_set_attribute (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
if (ioctl(v4l2element->video_fd, VIDIOC_S_CTRL, &control) < 0) {
|
if (ioctl(v4l2element->video_fd, VIDIOC_S_CTRL, &control) < 0) {
|
||||||
gst_element_error(GST_ELEMENT(v4l2element),
|
gst_element_error(GST_ELEMENT(v4l2element),
|
||||||
"Failed to set value %d for control %d on device %s: %s",
|
"Failed to set value %d for control %s (%d) on device %s: %s",
|
||||||
value, attribute_num, v4l2element->device, g_strerror(errno));
|
value, name, attribute_num, v4l2element->device, g_strerror(errno));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,17 +89,14 @@ gboolean gst_v4l2_get_norm (GstV4l2Element *v4l2element,
|
||||||
gint *norm);
|
gint *norm);
|
||||||
gboolean gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_norm (GstV4l2Element *v4l2element,
|
||||||
gint norm);
|
gint norm);
|
||||||
GList * gst_v4l2_get_norm_names (GstV4l2Element *v4l2element);
|
|
||||||
gboolean gst_v4l2_get_input (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_get_input (GstV4l2Element *v4l2element,
|
||||||
gint *input);
|
gint *input);
|
||||||
gboolean gst_v4l2_set_input (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_input (GstV4l2Element *v4l2element,
|
||||||
gint input);
|
gint input);
|
||||||
GList * gst_v4l2_get_input_names (GstV4l2Element *v4l2element);
|
|
||||||
gboolean gst_v4l2_get_output (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_get_output (GstV4l2Element *v4l2element,
|
||||||
gint *output);
|
gint *output);
|
||||||
gboolean gst_v4l2_set_output (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_output (GstV4l2Element *v4l2element,
|
||||||
gint output);
|
gint output);
|
||||||
GList * gst_v4l2_get_output_names (GstV4l2Element *v4l2element);
|
|
||||||
|
|
||||||
/* frequency control */
|
/* frequency control */
|
||||||
gboolean gst_v4l2_has_tuner (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_has_tuner (GstV4l2Element *v4l2element,
|
||||||
|
@ -113,18 +110,17 @@ gboolean gst_v4l2_signal_strength (GstV4l2Element *v4l2element,
|
||||||
|
|
||||||
/* attribute control */
|
/* attribute control */
|
||||||
gboolean gst_v4l2_has_audio (GstV4l2Element *v4l2element);
|
gboolean gst_v4l2_has_audio (GstV4l2Element *v4l2element);
|
||||||
GList * gst_v4l2_get_attributes (GstV4l2Element *v4l2element);
|
gboolean gst_v4l2_get_attribute (GstElement *element,
|
||||||
gboolean gst_v4l2_get_attribute (GstV4l2Element *v4l2element,
|
const char *attribute,
|
||||||
gint attribute_num,
|
int *value);
|
||||||
gint *value);
|
gboolean gst_v4l2_set_attribute (GstElement *element,
|
||||||
gboolean gst_v4l2_set_attribute (GstV4l2Element *v4l2element,
|
const char *attribute,
|
||||||
gint attribute_num,
|
const int value);
|
||||||
gint value);
|
|
||||||
|
|
||||||
/* overlay */
|
/* overlay */
|
||||||
gboolean gst_v4l2_set_display (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_display (GstV4l2Element *v4l2element,
|
||||||
const gchar *display);
|
const gchar *display);
|
||||||
gboolean gst_v4l2_set_window (GstV4l2Element *v4l2element,
|
gboolean gst_v4l2_set_window (GstElement *element,
|
||||||
gint x, gint y,
|
gint x, gint y,
|
||||||
gint w, gint h,
|
gint w, gint h,
|
||||||
struct v4l2_clip *clips,
|
struct v4l2_clip *clips,
|
||||||
|
|
|
@ -72,6 +72,8 @@ gst_v4l2src_fill_format_list (GstV4l2Src *v4l2src)
|
||||||
fmtptr = g_malloc(sizeof(format));
|
fmtptr = g_malloc(sizeof(format));
|
||||||
memcpy(fmtptr, &format, sizeof(format));
|
memcpy(fmtptr, &format, sizeof(format));
|
||||||
v4l2src->formats = g_list_append(v4l2src->formats, fmtptr);
|
v4l2src->formats = g_list_append(v4l2src->formats, fmtptr);
|
||||||
|
|
||||||
|
v4l2src->format_list = g_list_append(v4l2src->format_list, fmtptr->description);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -92,6 +94,8 @@ gst_v4l2src_empty_format_list (GstV4l2Src *v4l2src)
|
||||||
v4l2src->formats = g_list_remove(v4l2src->formats, data);
|
v4l2src->formats = g_list_remove(v4l2src->formats, data);
|
||||||
g_free(data);
|
g_free(data);
|
||||||
}
|
}
|
||||||
|
g_list_free(v4l2src->format_list);
|
||||||
|
v4l2src->format_list = NULL;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -399,49 +403,3 @@ gst_v4l2src_capture_deinit (GstV4l2Src *v4l2src)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2src_get_fourcc_list():
|
|
||||||
* create a list of all available fourccs
|
|
||||||
* return value: the list
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
GList *
|
|
||||||
gst_v4l2src_get_fourcc_list (GstV4l2Src *v4l2src)
|
|
||||||
{
|
|
||||||
GList *list = NULL;
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
for (n=0;n<g_list_length(v4l2src->formats);n++) {
|
|
||||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, n);
|
|
||||||
guint32 print_format = GUINT32_FROM_LE(fmt->pixelformat);
|
|
||||||
gchar *print_format_str = (gchar *) &print_format;
|
|
||||||
|
|
||||||
list = g_list_append(list, g_strndup(print_format_str, 4));
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************
|
|
||||||
* gst_v4l2src_get_format_list():
|
|
||||||
* create a list of all available capture formats
|
|
||||||
* return value: the list
|
|
||||||
******************************************************/
|
|
||||||
|
|
||||||
GList *
|
|
||||||
gst_v4l2src_get_format_list (GstV4l2Src *v4l2src)
|
|
||||||
{
|
|
||||||
GList *list = NULL;
|
|
||||||
gint n;
|
|
||||||
|
|
||||||
for (n=0;n<g_list_length(v4l2src->formats);n++) {
|
|
||||||
struct v4l2_fmtdesc *fmt = (struct v4l2_fmtdesc *) g_list_nth_data(v4l2src->formats, n);
|
|
||||||
|
|
||||||
list = g_list_append(list, g_strdup(fmt->description));
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
|
@ -40,8 +40,6 @@ gboolean gst_v4l2src_capture_deinit (GstV4l2Src *v4l2src);
|
||||||
|
|
||||||
gboolean gst_v4l2src_fill_format_list (GstV4l2Src *v4l2src);
|
gboolean gst_v4l2src_fill_format_list (GstV4l2Src *v4l2src);
|
||||||
gboolean gst_v4l2src_empty_format_list (GstV4l2Src *v4l2src);
|
gboolean gst_v4l2src_empty_format_list (GstV4l2Src *v4l2src);
|
||||||
GList * gst_v4l2src_get_fourcc_list (GstV4l2Src *v4l2src);
|
|
||||||
GList * gst_v4l2src_get_format_list (GstV4l2Src *v4l2src);
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __V4L2_SRC_CALLS_H__ */
|
#endif /* __V4L2_SRC_CALLS_H__ */
|
||||||
|
|
Loading…
Reference in a new issue