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)
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
--- /dev/null
+BOOLEAN:INT,INT,INT,INT,POINTER,INT
+BOOLEAN:STRING,INT
+BOOLEAN:STRING,POINTER
#endif
#include "v4l2_calls.h"
+#include "gstv4l2element-marshal.h"
/* elementfactory details */
static GstElementDetails gst_v4l2element_details = {
/* FILL ME */
SIGNAL_OPEN,
SIGNAL_CLOSE,
+ SIGNAL_SET_VIDEOWINDOW,
+ SIGNAL_GET_ATTRIBUTE,
+ SIGNAL_SET_ATTRIBUTE,
LAST_SIGNAL
};
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,
};
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,
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] =
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;
}
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)
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)))
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));
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))
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))
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))
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) &&
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;
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 */
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);
};
ARG_HEIGHT,
ARG_PALETTE,
ARG_PALETTE_NAMES,
- ARG_FOURCC,
- ARG_FOURCC_LIST,
ARG_NUMBUFS,
ARG_BUFSIZE
};
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",
v4l2src->breq.count = 0;
v4l2src->formats = NULL;
+ v4l2src->format_list = NULL;
}
}
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);
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:
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;
******************************************************/
gboolean
-gst_v4l2_set_window (GstV4l2Element *v4l2element,
+gst_v4l2_set_window (GstElement *element,
gint x,
gint y,
gint w,
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);
inpptr = g_malloc(sizeof(input));
memcpy(inpptr, &input, sizeof(input));
v4l2element->inputs = g_list_append(v4l2element->inputs, inpptr);
+
+ v4l2element->input_names = g_list_append(v4l2element->input_names, inpptr->name);
}
/* outputs */
outptr = g_malloc(sizeof(output));
memcpy(outptr, &output, sizeof(output));
v4l2element->outputs = g_list_append(v4l2element->outputs, outptr);
+
+ v4l2element->output_names = g_list_append(v4l2element->output_names, outptr->name);
}
/* norms... */
stdptr = g_malloc(sizeof(standard));
memcpy(stdptr, &standard, sizeof(standard));
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) */
for (n=V4L2_CID_BASE;;n++) {
struct v4l2_queryctrl control, *ctrlptr;
GList *menus = NULL;
+ GParamSpec *spec = NULL;
/* hacky... */
if (n == V4L2_CID_LASTP1)
n = V4L2_CID_PRIVATE_BASE;
}
}
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;
v4l2element->inputs = g_list_remove(v4l2element->inputs, data);
g_free(data);
}
+ g_list_free(v4l2element->input_names);
+ v4l2element->input_names = NULL;
while (g_list_length(v4l2element->outputs) > 0) {
gpointer data = g_list_nth_data(v4l2element->outputs, 0);
v4l2element->outputs = g_list_remove(v4l2element->outputs, data);
g_free(data);
}
+ g_list_free(v4l2element->output_names);
+ v4l2element->output_names = NULL;
while (g_list_length(v4l2element->norms) > 0) {
gpointer data = g_list_nth_data(v4l2element->norms, 0);
v4l2element->norms = g_list_remove(v4l2element->norms, data);
g_free(data);
}
+ g_list_free(v4l2element->norm_names);
+ v4l2element->norm_names = NULL;
while (g_list_length(v4l2element->controls) > 0) {
gpointer data = g_list_nth_data(v4l2element->controls, 0);
v4l2element->controls = g_list_remove(v4l2element->controls, 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));
+ }
}
}
-/******************************************************
- * 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()
* Get the input of the current device
}
-/******************************************************
- * 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()
* Get the output of the current device
/******************************************************
- * gst_v4l2_get_output_names()
- * 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():
+ * gst_v4l2_has_tuner():
* Check whether the device has a tuner
* return value: TRUE if it has a tuner, else FALSE
******************************************************/
/******************************************************
- * gst_v4l_get_frequency():
+ * gst_v4l2_get_frequency():
* get the current frequency
* return value: TRUE on success, FALSE on error
******************************************************/
/******************************************************
- * gst_v4l_set_frequency():
+ * gst_v4l2_set_frequency():
* set frequency
* return value: TRUE on success, FALSE on error
******************************************************/
/******************************************************
- * gst_v4l_signal_strength():
+ * gst_v4l2_signal_strength():
* get the strength of the signal on the current input
* return value: TRUE on success, FALSE on error
******************************************************/
/******************************************************
- * gst_v4l_has_audio():
+ * gst_v4l2_has_audio():
* Check whether the device has audio capabilities
* return value: TRUE if it has a tuner, else FALSE
******************************************************/
/******************************************************
- * gst_v4l_get_attributes():
- * get a list of attributes available on this device
- * return value: the list
+ * gst_v4l2_control_name_to_num():
+ * convert name to num (-1 if nothing)
******************************************************/
-GList *
-gst_v4l2_get_attributes (GstV4l2Element *v4l2element)
+static gint
+gst_v4l2_control_name_to_num (GstV4l2Element *v4l2element,
+ const gchar *name)
{
- gint i;
- GList *list = NULL;
-
- DEBUG("getting a list of available attributes");
-
- for (i=0;i<g_list_length(v4l2element->controls);i++) {
- struct v4l2_queryctrl *control = (struct v4l2_queryctrl *) g_list_nth_data(v4l2element->controls, i);
- 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;
+ GList *item;
+
+ for (item = v4l2element->controls; item != NULL; item = item->next) {
+ struct v4l2_queryctrl *ctrl = item->data;
+ if (!strcmp(ctrl->name, name))
+ return ctrl->id;
}
- return list;
+ return -1;
}
/******************************************************
- * gst_v4l_get_attribute():
+ * gst_v4l2_get_attribute():
* try to get the value of one specific attribute
* return value: TRUE on success, FALSE on error
******************************************************/
gboolean
-gst_v4l2_get_attribute (GstV4l2Element *v4l2element,
- gint attribute_num,
- gint *value)
+gst_v4l2_get_attribute (GstElement *element,
+ const gchar *name,
+ int *value)
{
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);
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),
- "Invalid control ID %d", attribute_num);
+ "Invalid control %s", name);
return FALSE;
}
if (ioctl(v4l2element->video_fd, VIDIOC_G_CTRL, &control) < 0) {
gst_element_error(GST_ELEMENT(v4l2element),
- "Failed to get value for control %d on device %s: %s",
- attribute_num, v4l2element->device, g_strerror(errno));
+ "Failed to get value for control %s (%d) on device %s: %s",
+ name, attribute_num, v4l2element->device, g_strerror(errno));
return FALSE;
}
/******************************************************
- * gst_v4l_set_attribute():
+ * gst_v4l2_set_attribute():
* try to set the value of one specific attribute
* return value: TRUE on success, FALSE on error
******************************************************/
gboolean
-gst_v4l2_set_attribute (GstV4l2Element *v4l2element,
- gint attribute_num,
- gint value)
+gst_v4l2_set_attribute (GstElement *element,
+ const gchar *name,
+ const int value)
{
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);
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),
- "Invalid control ID %d", attribute_num);
+ "Invalid control %s", name);
return FALSE;
}
if (ioctl(v4l2element->video_fd, VIDIOC_S_CTRL, &control) < 0) {
gst_element_error(GST_ELEMENT(v4l2element),
- "Failed to set value %d for control %d on device %s: %s",
- value, attribute_num, v4l2element->device, g_strerror(errno));
+ "Failed to set value %d for control %s (%d) on device %s: %s",
+ value, name, attribute_num, v4l2element->device, g_strerror(errno));
return FALSE;
}
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,
/* 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,
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;
v4l2src->formats = g_list_remove(v4l2src->formats, data);
g_free(data);
}
+ g_list_free(v4l2src->format_list);
+ v4l2src->format_list = NULL;
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;
-}
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__ */