Commit 1a8a2ef6 authored by Ronald S. Bultje's avatar Ronald S. Bultje

Unification of the way to speak to v4l2 and v4l elements... Also fix a...

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
parent fd90de31
......@@ -4,7 +4,7 @@ plugin_LTLIBRARIES = \
libgstv4l2element.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_LIBADD =
libgstv4l2element_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
......@@ -15,4 +15,32 @@ libgstv4l2src_la_LIBADD = libgstv4l2element.la
libgstv4l2src_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
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
BOOLEAN:INT,INT,INT,INT,POINTER,INT
BOOLEAN:STRING,INT
BOOLEAN:STRING,POINTER
......@@ -22,6 +22,7 @@
#endif
#include "v4l2_calls.h"
#include "gstv4l2element-marshal.h"
/* elementfactory details */
static GstElementDetails gst_v4l2element_details = {
......@@ -39,6 +40,9 @@ enum {
/* FILL ME */
SIGNAL_OPEN,
SIGNAL_CLOSE,
SIGNAL_SET_VIDEOWINDOW,
SIGNAL_GET_ATTRIBUTE,
SIGNAL_SET_ATTRIBUTE,
LAST_SIGNAL
};
......@@ -54,15 +58,13 @@ enum {
ARG_FREQUENCY,
ARG_SIGNAL_STRENGTH,
ARG_HAS_AUDIO,
ARG_ATTRIBUTE,
ARG_ATTRIBUTE_SETS,
ARG_ATTRIBUTES,
ARG_DEVICE,
ARG_DEVICE_NAME,
ARG_DEVICE_HAS_CAPTURE,
ARG_DEVICE_HAS_OVERLAY,
ARG_DEVICE_HAS_PLAYBACK,
ARG_DISPLAY,
ARG_VIDEOWINDOW,
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_param_spec_boolean("has_audio","has_audio","has_audio",
0,G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ATTRIBUTE,
g_param_spec_pointer("attribute","attribute","attribute",
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_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ATTRIBUTES,
g_param_spec_pointer("attributes","attributes","attributes",
G_PARAM_READABLE));
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_param_spec_boolean("do_overlay","do_overlay","do_overlay",
0,G_PARAM_WRITABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VIDEOWINDOW,
g_param_spec_pointer("videowindow","videowindow","videowindow",
G_PARAM_WRITABLE));
/* actions */
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 */
gst_v4l2element_signals[SIGNAL_OPEN] =
......@@ -220,9 +247,14 @@ gst_v4l2element_init (GstV4l2Element *v4l2element)
v4l2element->frequency = 0;
v4l2element->controls = NULL;
v4l2element->menus = NULL;
v4l2element->control_specs = NULL;
v4l2element->outputs = NULL;
v4l2element->output_names = NULL;
v4l2element->inputs = NULL;
v4l2element->input_names = NULL;
v4l2element->norms = NULL;
v4l2element->norm_names = NULL;
}
......@@ -267,13 +299,6 @@ gst_v4l2element_set_property (GObject *object,
return;
}
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:
if (!GST_V4L2_IS_OPEN(v4l2element)) {
if (v4l2element->device)
......@@ -285,15 +310,6 @@ gst_v4l2element_set_property (GObject *object,
if (!gst_v4l2_set_display(v4l2element, g_value_get_string(value)))
return;
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:
if (GST_V4L2_IS_OPEN(v4l2element)) {
if (!gst_v4l2_enable_overlay(v4l2element, g_value_get_boolean(value)))
......@@ -316,7 +332,6 @@ gst_v4l2element_get_property (GObject *object,
GstV4l2Element *v4l2element;
gint temp_i = 0;
gulong temp_ul = 0;
GList *list = NULL;
/* it's not null if we got it, but it might not be ours */
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);
break;
case ARG_CHANNEL_NAMES:
if (GST_V4L2_IS_OPEN(v4l2element))
list = gst_v4l2_get_input_names(v4l2element);
g_value_set_pointer(value, list);
g_value_set_pointer(value, v4l2element->input_names);
break;
case ARG_OUTPUT:
if (GST_V4L2_IS_OPEN(v4l2element))
......@@ -339,9 +352,7 @@ gst_v4l2element_get_property (GObject *object,
g_value_set_int(value, temp_i);
break;
case ARG_OUTPUT_NAMES:
if (GST_V4L2_IS_OPEN(v4l2element))
list = gst_v4l2_get_output_names(v4l2element);
g_value_set_pointer(value, list);
g_value_set_pointer(value, v4l2element->output_names);
break;
case ARG_NORM:
if (GST_V4L2_IS_OPEN(v4l2element))
......@@ -349,9 +360,7 @@ gst_v4l2element_get_property (GObject *object,
g_value_set_int(value, temp_i);
break;
case ARG_NORM_NAMES:
if (GST_V4L2_IS_OPEN(v4l2element))
list = gst_v4l2_get_norm_names(v4l2element);
g_value_set_pointer(value, list);
g_value_set_pointer(value, v4l2element->norm_names);
break;
case ARG_HAS_TUNER:
if (GST_V4L2_IS_OPEN(v4l2element))
......@@ -373,23 +382,15 @@ gst_v4l2element_get_property (GObject *object,
temp_i = gst_v4l2_has_audio(v4l2element);
g_value_set_boolean(value, temp_i>0?TRUE:FALSE);
break;
case ARG_ATTRIBUTE:
if (GST_V4L2_IS_OPEN(v4l2element))
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);
case ARG_ATTRIBUTES:
g_value_set_pointer(value, v4l2element->control_specs);
break;
case ARG_DEVICE:
g_value_set_string(value, g_strdup(v4l2element->device));
g_value_set_string(value, v4l2element->device);
break;
case ARG_DEVICE_NAME:
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;
case ARG_DEVICE_HAS_CAPTURE:
if (GST_V4L2_IS_OPEN(v4l2element) &&
......
......@@ -41,28 +41,6 @@
typedef struct _GstV4l2Element GstV4l2Element;
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 {
GstElement element;
......@@ -79,10 +57,10 @@ struct _GstV4l2Element {
struct v4l2_capability vcap;
/* the toys available to us */
GList /*v4l2_input*/ *inputs;
GList /*v4l2_output*/ *outputs;
GList /*v4l2_enumstd*/ *norms;
GList /*v4l2_queryctrl*/ *controls;
GList /*v4l2_input*/ *inputs, *input_names;
GList /*v4l2_output*/ *outputs, *output_names;
GList /*v4l2_enumstd*/ *norms, *norm_names;
GList /*v4l2_queryctrl*/ *controls, *control_specs;
GList /*GList:v4l2_querymenu*/ *menus;
/* caching values */
......@@ -96,10 +74,25 @@ struct _GstV4l2ElementClass {
GstElementClass parent_class;
/* signals */
void (*open) (GstElement *element,
const gchar *device);
void (*close) (GstElement *element,
const gchar *device);
void (*open) (GstElement *element,
const gchar *device);
void (*close) (GstElement *element,
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_PALETTE,
ARG_PALETTE_NAMES,
ARG_FOURCC,
ARG_FOURCC_LIST,
ARG_NUMBUFS,
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_param_spec_pointer("palette_name","palette_name","palette_name",
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_param_spec_int("num_buffers","num_buffers","num_buffers",
......@@ -201,6 +193,7 @@ gst_v4l2src_init (GstV4l2Src *v4l2src)
v4l2src->breq.count = 0;
v4l2src->formats = NULL;
v4l2src->format_list = NULL;
}
......@@ -742,19 +735,6 @@ gst_v4l2src_set_property (GObject *object,
}
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:
if (!GST_V4L2_IS_ACTIVE(GST_V4L2ELEMENT(v4l2src))) {
v4l2src->breq.count = g_value_get_int(value);
......@@ -793,18 +773,7 @@ gst_v4l2src_get_property (GObject *object,
break;
case ARG_PALETTE_NAMES:
g_value_set_pointer(value, gst_v4l2src_get_format_list(v4l2src));
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));
g_value_set_pointer(value, v4l2src->format_list);
break;
case ARG_NUMBUFS:
......
......@@ -45,7 +45,7 @@ struct _GstV4l2Src {
GstPad *srcpad;
/* internal lists */
GList /*v4l2_fmtdesc*/ *formats; /* list of available capture formats */
GList /*v4l2_fmtdesc*/ *formats, *format_list; /* list of available capture formats */
/* buffer properties */
struct v4l2_buffer bufsettings;
......
......@@ -81,7 +81,7 @@ gst_v4l2_set_display (GstV4l2Element *v4l2element,
******************************************************/
gboolean
gst_v4l2_set_window (GstV4l2Element *v4l2element,
gst_v4l2_set_window (GstElement *element,
gint x,
gint y,
gint w,
......@@ -90,6 +90,7 @@ gst_v4l2_set_window (GstV4l2Element *v4l2element,
gint num_clips)
{
struct v4l2_format fmt;
GstV4l2Element *v4l2element = GST_V4L2ELEMENT(element);
DEBUG("trying to set video window to %dx%d,%d,%d", x,y,w,h);
GST_V4L2_CHECK_OVERLAY(v4l2element);
......
This diff is collapsed.
......@@ -89,17 +89,14 @@ gboolean gst_v4l2_get_norm (GstV4l2Element *v4l2element,
gint *norm);
gboolean gst_v4l2_set_norm (GstV4l2Element *v4l2element,
gint norm);
GList * gst_v4l2_get_norm_names (GstV4l2Element *v4l2element);
gboolean gst_v4l2_get_input (GstV4l2Element *v4l2element,
gint *input);
gboolean gst_v4l2_set_input (GstV4l2Element *v4l2element,
gint input);
GList * gst_v4l2_get_input_names (GstV4l2Element *v4l2element);
gboolean gst_v4l2_get_output (GstV4l2Element *v4l2element,
gint *output);
gboolean gst_v4l2_set_output (GstV4l2Element *v4l2element,
gint output);
GList * gst_v4l2_get_output_names (GstV4l2Element *v4l2element);
/* frequency control */
gboolean gst_v4l2_has_tuner (GstV4l2Element *v4l2element,
......@@ -113,18 +110,17 @@ gboolean gst_v4l2_signal_strength (GstV4l2Element *v4l2element,
/* attribute control */
gboolean gst_v4l2_has_audio (GstV4l2Element *v4l2element);
GList * gst_v4l2_get_attributes (GstV4l2Element *v4l2element);
gboolean gst_v4l2_get_attribute (GstV4l2Element *v4l2element,
gint attribute_num,
gint *value);
gboolean gst_v4l2_set_attribute (GstV4l2Element *v4l2element,
gint attribute_num,
gint value);
gboolean gst_v4l2_get_attribute (GstElement *element,
const char *attribute,
int *value);
gboolean gst_v4l2_set_attribute (GstElement *element,
const char *attribute,
const int value);
/* overlay */
gboolean gst_v4l2_set_display (GstV4l2Element *v4l2element,
const gchar *display);
gboolean gst_v4l2_set_window (GstV4l2Element *v4l2element,
gboolean gst_v4l2_set_window (GstElement *element,
gint x, gint y,
gint w, gint h,
struct v4l2_clip *clips,
......
......@@ -72,6 +72,8 @@ gst_v4l2src_fill_format_list (GstV4l2Src *v4l2src)
fmtptr = g_malloc(sizeof(format));
memcpy(fmtptr, &format, sizeof(format));
v4l2src->formats = g_list_append(v4l2src->formats, fmtptr);
v4l2src->format_list = g_list_append(v4l2src->format_list, fmtptr->description);
}
return TRUE;
......@@ -92,6 +94,8 @@ gst_v4l2src_empty_format_list (GstV4l2Src *v4l2src)
v4l2src->formats = g_list_remove(v4l2src->formats, data);
g_free(data);
}
g_list_free(v4l2src->format_list);
v4l2src->format_list = NULL;
return TRUE;
}
......@@ -399,49 +403,3 @@ gst_v4l2src_capture_deinit (GstV4l2Src *v4l2src)
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_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__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment