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:
Ronald S. Bultje 2003-03-02 21:58:52 +00:00
parent 8bfd482d89
commit 33bfd20100
8 changed files with 227 additions and 212 deletions

View file

@ -3,7 +3,8 @@ plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
plugin_LTLIBRARIES = libgstv4lelement.la libgstv4lsrc.la \ plugin_LTLIBRARIES = libgstv4lelement.la libgstv4lsrc.la \
libgstv4lmjpegsrc.la libgstv4lmjpegsink.la libgstv4lmjpegsrc.la libgstv4lmjpegsink.la
libgstv4lelement_la_SOURCES = gstv4lelement.c v4l_calls.c v4l-overlay_calls.c libgstv4lelement_la_SOURCES = gstv4lelement.c v4l_calls.c \
v4l-overlay_calls.c gstv4lelement-marshal.c
libgstv4lelement_la_CFLAGS = $(GST_CFLAGS) libgstv4lelement_la_CFLAGS = $(GST_CFLAGS)
libgstv4lelement_la_LIBADD = libgstv4lelement_la_LIBADD =
libgstv4lelement_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) libgstv4lelement_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
@ -26,4 +27,33 @@ libgstv4lmjpegsink_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
noinst_HEADERS = gstv4lelement.h v4l_calls.h \ noinst_HEADERS = gstv4lelement.h v4l_calls.h \
gstv4lsrc.h v4lsrc_calls.h \ gstv4lsrc.h v4lsrc_calls.h \
gstv4lmjpegsrc.h v4lmjpegsrc_calls.h \ gstv4lmjpegsrc.h v4lmjpegsrc_calls.h \
gstv4lmjpegsink.h v4lmjpegsink_calls.h videodev_mjpeg.h gstv4lmjpegsink.h v4lmjpegsink_calls.h \
videodev_mjpeg.h gstv4lelement-marshal.h
EXTRA_libgstv4lelement_la_SOURCES = \
gstv4lelement-marshal.list
BUILT_SOURCES = \
gstv4lelement-marshal.c \
gstv4lelement-marshal.h
gstv4lelement-marshal.h: gstv4lelement-marshal.list
glib-genmarshal --header --prefix=gstv4l_cclosure_marshal $(srcdir)/gstv4lelement-marshal.list > gstv4lelement-marshal.h.tmp
mv gstv4lelement-marshal.h.tmp gstv4lelement-marshal.h
gstv4lelement-marshal.c: gstv4lelement-marshal.list
echo "#include \"glib.h\"" > gstv4lelement-marshal.c.tmp
echo "#include \"glib-object.h\"" >> gstv4lelement-marshal.c.tmp
echo "#include \"gstv4lelement-marshal.h\"" >> gstv4lelement-marshal.c.tmp
glib-genmarshal --body --prefix=gstv4l_cclosure_marshal $(srcdir)/gstv4lelement-marshal.list >> gstv4lelement-marshal.c.tmp
mv gstv4lelement-marshal.c.tmp gstv4lelement-marshal.c
# Don't want the generated marshal files in the dist
dist-hook:
rm -f $(distdir)/gstv4lelement-marshal.c
rm -f $(distdir)/gstv4lelement-marshal.h
# Clean generated files
distclean-local:
rm -f $(top_builddir)/src/element/gstv4lelement-marshal.c
rm -f $(top_builddir)/src/element/gstv4lelement-marshal.h

View file

@ -3,6 +3,7 @@ TODO list (short term):
* fix clocking issues by using gst clock for v4lsrc and by using it * fix clocking issues by using gst clock for v4lsrc and by using it
as a correction for v4lmjpegsrc/v4l2src (pause brokenness etc.) as a correction for v4lmjpegsrc/v4l2src (pause brokenness etc.)
* v4lsrc/v4lmjpegsrc/v4l2src: fix interlacing (not handled at all...) * v4lsrc/v4lmjpegsrc/v4l2src: fix interlacing (not handled at all...)
* v4lsrc - add a property for capture formats?
TODO list (long term): TODO list (long term):
====================== ======================

View file

@ -0,0 +1,3 @@
BOOLEAN:INT,INT,INT,INT,POINTER,INT
BOOLEAN:STRING,POINTER
BOOLEAN:STRING,INT

View file

@ -17,7 +17,9 @@
* Boston, MA 02111-1307, USA. * Boston, MA 02111-1307, USA.
*/ */
#include <string.h>
#include "v4l_calls.h" #include "v4l_calls.h"
#include "gstv4lelement-marshal.h"
/* elementfactory information */ /* elementfactory information */
static GstElementDetails gst_v4lelement_details = { static GstElementDetails gst_v4lelement_details = {
@ -35,6 +37,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
}; };
@ -47,13 +52,7 @@ enum {
ARG_HAS_TUNER, ARG_HAS_TUNER,
ARG_FREQUENCY, ARG_FREQUENCY,
ARG_HAS_AUDIO, ARG_HAS_AUDIO,
ARG_MUTE, ARG_ATTRIBUTES,
ARG_MODE,
ARG_VOLUME,
ARG_HUE,
ARG_BRIGHTNESS,
ARG_CONTRAST,
ARG_SATURATION,
ARG_DEVICE, ARG_DEVICE,
ARG_DEVICE_NAME, ARG_DEVICE_NAME,
ARG_DEVICE_IS_CAPTURE, ARG_DEVICE_IS_CAPTURE,
@ -63,7 +62,6 @@ enum {
ARG_DEVICE_IS_MPEG_CAPTURE, ARG_DEVICE_IS_MPEG_CAPTURE,
ARG_DEVICE_IS_MPEG_PLAYBACK, ARG_DEVICE_IS_MPEG_PLAYBACK,
ARG_DISPLAY, ARG_DISPLAY,
ARG_VIDEOWINDOW,
ARG_DO_OVERLAY, ARG_DO_OVERLAY,
ARG_SIGNAL, ARG_SIGNAL,
}; };
@ -112,6 +110,65 @@ gst_v4lelement_get_type (void)
} }
static gboolean
gst_v4l_get_attribute (GstElement *element,
const gchar *name,
int *value)
{
int n;
GstV4lElement *v4lelement;
g_return_val_if_fail(element != NULL && name != NULL && value != NULL, FALSE);
g_return_val_if_fail(GST_IS_V4LELEMENT(element), FALSE);
v4lelement = GST_V4LELEMENT(element);
for (n=0;picture_name[n]!=NULL;n++)
{
if (!strcmp(picture_name[n], name))
return gst_v4l_get_picture(v4lelement, n, value);
}
for (n=0;audio_name[n]!=NULL;n++)
{
if (!strcmp(audio_name[n], name))
return gst_v4l_get_audio(v4lelement, n, value);
}
gst_element_error(element, "Unknown attribute %s", name);
return FALSE;
}
static gboolean
gst_v4l_set_attribute (GstElement *element,
const gchar *name,
const int value)
{
int n;
GstV4lElement *v4lelement;
g_return_val_if_fail(element != NULL && name != NULL, FALSE);
g_return_val_if_fail(GST_IS_V4LELEMENT(element), FALSE);
v4lelement = GST_V4LELEMENT(element);
for (n=0;picture_name[n]!=NULL;n++)
{
if (!strcmp(picture_name[n], name))
return gst_v4l_set_picture(v4lelement, n, value);
}
for (n=0;audio_name[n]!=NULL;n++)
{
if (!strcmp(audio_name[n], name))
return gst_v4l_set_audio(v4lelement, n, value);
}
gst_element_error(element, "Unknown attribute %s", name);
return FALSE;
}
static void static void
gst_v4lelement_class_init (GstV4lElementClass *klass) gst_v4lelement_class_init (GstV4lElementClass *klass)
@ -150,28 +207,6 @@ gst_v4lelement_class_init (GstV4lElementClass *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_MUTE,
g_param_spec_boolean("mute","mute","mute",
0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VOLUME,
g_param_spec_int("volume","volume","volume",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MODE,
g_param_spec_int("mode","mode","mode",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HUE,
g_param_spec_int("hue","hue","hue",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BRIGHTNESS,
g_param_spec_int("brightness","brightness","brightness",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CONTRAST,
g_param_spec_int("contrast","contrast","contrast",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SATURATION,
g_param_spec_int("saturation","saturation","saturation",
G_MININT,G_MAXINT,0,G_PARAM_READWRITE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE, g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE,
g_param_spec_string("device","device","device", g_param_spec_string("device","device","device",
@ -207,9 +242,37 @@ gst_v4lelement_class_init (GstV4lElementClass *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_v4lelement_signals[SIGNAL_SET_VIDEOWINDOW] =
g_signal_new ("set_videowindow",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(GstV4lElementClass, set_videowindow),
NULL, NULL,
gstv4l_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_v4l_set_window;
gst_v4lelement_signals[SIGNAL_GET_ATTRIBUTE] =
g_signal_new ("get_attribute",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(GstV4lElementClass, get_attribute),
NULL, NULL,
gstv4l_cclosure_marshal_BOOLEAN__STRING_POINTER,
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_POINTER);
klass->get_attribute = gst_v4l_get_attribute;
gst_v4lelement_signals[SIGNAL_SET_ATTRIBUTE] =
g_signal_new ("set_attribute",
G_TYPE_FROM_CLASS(klass),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET(GstV4lElementClass, set_attribute),
NULL, NULL,
gstv4l_cclosure_marshal_BOOLEAN__STRING_INT,
G_TYPE_BOOLEAN, 2, G_TYPE_STRING, G_TYPE_INT);
klass->set_attribute = gst_v4l_set_attribute;
/* signals */ /* signals */
gst_v4lelement_signals[SIGNAL_OPEN] = gst_v4lelement_signals[SIGNAL_OPEN] =
@ -244,14 +307,9 @@ gst_v4lelement_init (GstV4lElement *v4lelement)
v4lelement->frequency = 0; v4lelement->frequency = 0;
v4lelement->mute = -1; v4lelement->norm_names = NULL;
v4lelement->volume = -1; v4lelement->input_names = NULL;
v4lelement->mode = -1; v4lelement->control_specs = NULL;
v4lelement->brightness = -1;
v4lelement->hue = -1;
v4lelement->contrast = -1;
v4lelement->saturation = -1;
} }
@ -293,67 +351,10 @@ gst_v4lelement_set_property (GObject *object,
break; break;
case ARG_FREQUENCY: case ARG_FREQUENCY:
v4lelement->frequency = g_value_get_ulong(value); v4lelement->frequency = g_value_get_ulong(value);
if (gst_v4l_has_tuner(v4lelement)){ if (gst_v4l_has_tuner(v4lelement)) {
if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency)){ if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency)){
return; return;
} }
}
break;
case ARG_MUTE:
v4lelement->mute = g_value_get_boolean(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (gst_v4l_has_audio(v4lelement))
if (!gst_v4l_set_audio(v4lelement, V4L_AUDIO_MUTE, v4lelement->mute))
return;
}
break;
case ARG_MODE:
v4lelement->mode = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_audio(v4lelement, V4L_AUDIO_MODE, v4lelement->mode))
return;
}
break;
case ARG_VOLUME:
v4lelement->volume = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_audio(v4lelement, V4L_AUDIO_VOLUME, v4lelement->volume))
return;
}
break;
case ARG_HUE:
v4lelement->hue = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_picture(v4lelement, V4L_PICTURE_HUE, v4lelement->hue))
return;
}
break;
case ARG_BRIGHTNESS:
v4lelement->brightness = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_picture(v4lelement, V4L_PICTURE_BRIGHTNESS, v4lelement->brightness))
return;
}
break;
case ARG_CONTRAST:
v4lelement->contrast = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_picture(v4lelement, V4L_PICTURE_CONTRAST, v4lelement->contrast))
return;
}
break;
case ARG_SATURATION:
v4lelement->saturation = g_value_get_int(value);
if (GST_V4L_IS_OPEN(v4lelement))
{
if (!gst_v4l_set_picture(v4lelement, V4L_PICTURE_SATURATION, v4lelement->saturation))
return;
} }
break; break;
case ARG_DEVICE: case ARG_DEVICE:
@ -369,16 +370,6 @@ gst_v4lelement_set_property (GObject *object,
if (v4lelement->display) g_free(v4lelement->display); if (v4lelement->display) g_free(v4lelement->display);
v4lelement->display = g_strdup(g_value_get_string(value)); v4lelement->display = g_strdup(g_value_get_string(value));
break; break;
case ARG_VIDEOWINDOW:
if (GST_V4L_IS_OPEN(v4lelement))
{
GByteArray *array = (GByteArray *) g_value_get_pointer(value);
struct video_clip *clips = (struct video_clip *) array->data;
gst_v4l_set_window(v4lelement,
clips->x, clips->y, clips->width, clips->height,
&clips[1], array->len/sizeof(struct video_clip)-1);
}
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -420,7 +411,7 @@ gst_v4lelement_get_property (GObject *object,
break; break;
case ARG_NORM_NAMES: case ARG_NORM_NAMES:
for (temp_i=0;norm_name[temp_i]!=NULL;temp_i++) for (temp_i=0;norm_name[temp_i]!=NULL;temp_i++)
list = g_list_append(list, (gpointer)g_strdup(norm_name[temp_i])); list = g_list_append(list, (gpointer)norm_name[temp_i]);
g_value_set_pointer(value, (gpointer)list); g_value_set_pointer(value, (gpointer)list);
break; break;
case ARG_HAS_TUNER: case ARG_HAS_TUNER:
@ -447,52 +438,14 @@ gst_v4lelement_get_property (GObject *object,
if (gst_v4l_has_audio(v4lelement)) if (gst_v4l_has_audio(v4lelement))
g_value_set_boolean(value, TRUE); g_value_set_boolean(value, TRUE);
break; break;
case ARG_MUTE:
if (GST_V4L_IS_OPEN(v4lelement))
if (gst_v4l_has_audio(v4lelement))
gst_v4l_get_audio(v4lelement, V4L_AUDIO_MUTE, &temp_i);
g_value_set_boolean(value, temp_i?TRUE:FALSE);
break;
case ARG_MODE:
if (GST_V4L_IS_OPEN(v4lelement))
if (gst_v4l_has_tuner(v4lelement))
gst_v4l_get_audio(v4lelement, V4L_AUDIO_MODE, &temp_i);
g_value_set_int(value, temp_i);
break;
case ARG_VOLUME:
if (GST_V4L_IS_OPEN(v4lelement))
if (gst_v4l_has_tuner(v4lelement))
gst_v4l_get_audio(v4lelement, V4L_AUDIO_VOLUME, &temp_i);
g_value_set_int(value, temp_i);
break;
case ARG_HUE:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_get_picture(v4lelement, V4L_PICTURE_HUE, &temp_i);
g_value_set_int(value, temp_i);
break;
case ARG_BRIGHTNESS:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_get_picture(v4lelement, V4L_PICTURE_BRIGHTNESS, &temp_i);
g_value_set_int(value, temp_i);
break;
case ARG_CONTRAST:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_get_picture(v4lelement, V4L_PICTURE_CONTRAST, &temp_i);
g_value_set_int(value, temp_i);
break;
case ARG_SATURATION:
if (GST_V4L_IS_OPEN(v4lelement))
gst_v4l_get_picture(v4lelement, V4L_PICTURE_SATURATION, &temp_i);
g_value_set_int(value, temp_i);
break;
case ARG_DEVICE: case ARG_DEVICE:
g_value_set_string(value, g_strdup(v4lelement->videodev?v4lelement->videodev:"/dev/video")); g_value_set_string(value, v4lelement->videodev?v4lelement->videodev:"/dev/video");
break; break;
case ARG_DEVICE_NAME: case ARG_DEVICE_NAME:
if (GST_V4L_IS_OPEN(v4lelement)) if (GST_V4L_IS_OPEN(v4lelement))
g_value_set_string(value, g_strdup(v4lelement->vcap.name)); g_value_set_string(value, v4lelement->vcap.name);
else else
g_value_set_string(value, g_strdup("None")); g_value_set_string(value, "None");
break; break;
case ARG_DEVICE_IS_CAPTURE: case ARG_DEVICE_IS_CAPTURE:
g_value_set_boolean(value, FALSE); g_value_set_boolean(value, FALSE);
@ -547,8 +500,6 @@ gst_v4lelement_change_state (GstElement *element)
{ {
case GST_STATE_NULL_TO_READY: case GST_STATE_NULL_TO_READY:
{ {
int n, temp;
if (v4lelement->display) if (v4lelement->display)
gst_v4l_set_overlay(v4lelement, v4lelement->display); gst_v4l_set_overlay(v4lelement, v4lelement->display);
@ -573,41 +524,6 @@ gst_v4lelement_change_state (GstElement *element)
return GST_STATE_FAILURE; return GST_STATE_FAILURE;
} }
} }
for (n=V4L_AUDIO_VOLUME;n<=V4L_AUDIO_MODE;n++)
{
switch (n)
{
case V4L_AUDIO_MUTE: temp = v4lelement->mute; break;
case V4L_AUDIO_VOLUME: temp = v4lelement->volume; break;
case V4L_AUDIO_MODE: temp = v4lelement->mode; break;
default: temp = 0; g_assert_not_reached ();
}
if (temp >= 0 && gst_v4l_has_audio(v4lelement))
{
if (!gst_v4l_set_audio(v4lelement, n, temp)) {
gst_v4l_close(v4lelement);
return GST_STATE_FAILURE;
}
}
}
for (n=V4L_PICTURE_HUE;n<=V4L_PICTURE_SATURATION;n++)
{
switch (n)
{
case V4L_PICTURE_HUE: temp = v4lelement->hue; break;
case V4L_PICTURE_BRIGHTNESS: temp = v4lelement->brightness; break;
case V4L_PICTURE_SATURATION: temp = v4lelement->saturation; break;
case V4L_PICTURE_CONTRAST: temp = v4lelement->contrast; break;
default: temp = 0; g_assert_not_reached ();
}
if (temp >= 0)
{
if (!gst_v4l_set_picture(v4lelement, n, temp)) {
gst_v4l_close(v4lelement);
return GST_STATE_FAILURE;
}
}
}
g_signal_emit(G_OBJECT(v4lelement), g_signal_emit(G_OBJECT(v4lelement),
gst_v4lelement_signals[SIGNAL_OPEN], 0, gst_v4lelement_signals[SIGNAL_OPEN], 0,

View file

@ -65,17 +65,15 @@ struct _GstV4lElement {
/* some more info about the current input's capabilities */ /* some more info about the current input's capabilities */
struct video_channel vchan; struct video_channel vchan;
/* lists... */
GList *control_specs;
GList *norm_names;
GList *input_names;
/* caching values */ /* caching values */
gint channel; gint channel;
gint norm; gint norm;
gulong frequency; gulong frequency;
gint8 mute;
gint volume;
gint mode;
gint brightness;
gint hue;
gint contrast;
gint saturation;
gchar *display; gchar *display;
}; };
@ -83,10 +81,25 @@ struct _GstV4lElementClass {
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,
gint y,
gint w,
gint h,
struct video_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);
}; };
GType gst_v4lelement_get_type(void); GType gst_v4lelement_get_type(void);

View file

@ -80,7 +80,7 @@ gst_v4l_set_overlay (GstV4lElement *v4lelement,
******************************************************/ ******************************************************/
gboolean gboolean
gst_v4l_set_window (GstV4lElement *v4lelement, gst_v4l_set_window (GstElement *element,
gint x, gint x,
gint y, gint y,
gint w, gint w,
@ -88,6 +88,7 @@ gst_v4l_set_window (GstV4lElement *v4lelement,
struct video_clip *clips, struct video_clip *clips,
gint num_clips) gint num_clips)
{ {
GstV4lElement *v4lelement = GST_V4LELEMENT(element);
struct video_window vwin; struct video_window vwin;
DEBUG("setting video window to position (x,y/wxh) = %d,%d/%dx%d", DEBUG("setting video window to position (x,y/wxh) = %d,%d/%dx%d",

View file

@ -32,11 +32,27 @@
"V4L: " format, ##args) "V4L: " format, ##args)
char *picture_name[] = { "Hue", "Brightness", "Contrast", "Saturation", NULL }; const char *picture_name[] = {
"Hue",
"Brightness",
"Contrast",
"Saturation",
NULL
};
char *audio_name[] = { "Volume", "Mute", "Mode", NULL }; const char *audio_name[] = {
"Volume",
"Mute",
"Mode",
NULL
};
char *norm_name[] = { "PAL", "NTSC", "SECAM", NULL }; const char *norm_name[] = {
"PAL",
"NTSC",
"SECAM",
NULL
};
/****************************************************** /******************************************************
* gst_v4l_get_capabilities(): * gst_v4l_get_capabilities():
@ -71,6 +87,9 @@ gst_v4l_get_capabilities (GstV4lElement *v4lelement)
gboolean gboolean
gst_v4l_open (GstV4lElement *v4lelement) gst_v4l_open (GstV4lElement *v4lelement)
{ {
int num;
GParamSpec *spec;
DEBUG("opening device %s", v4lelement->videodev); DEBUG("opening device %s", v4lelement->videodev);
GST_V4L_CHECK_NOT_OPEN(v4lelement); GST_V4L_CHECK_NOT_OPEN(v4lelement);
GST_V4L_CHECK_NOT_ACTIVE(v4lelement); GST_V4L_CHECK_NOT_ACTIVE(v4lelement);
@ -100,6 +119,23 @@ gst_v4l_open (GstV4lElement *v4lelement)
gst_info("Opened device \'%s\' (\'%s\') successfully\n", gst_info("Opened device \'%s\' (\'%s\') successfully\n",
v4lelement->vcap.name, v4lelement->videodev); v4lelement->vcap.name, v4lelement->videodev);
for (num=0;norm_name[num]!=NULL;num++)
v4lelement->norm_names = g_list_append(v4lelement->norm_names, (gpointer)norm_name[num]);
v4lelement->input_names = gst_v4l_get_chan_names(v4lelement);
for (num=0;picture_name[num]!=NULL;num++)
{
spec = g_param_spec_int(picture_name[num], picture_name[num],
picture_name[num], 0, 65535, 32768,
G_PARAM_READWRITE);
v4lelement->control_specs = g_list_append(v4lelement->control_specs, spec);
}
spec = g_param_spec_boolean("mute", "mute", "mute", TRUE, G_PARAM_READWRITE);
v4lelement->control_specs = g_list_append(v4lelement->control_specs, spec);
spec = g_param_spec_int("volume", "volume", "volume",
0, 65535, 0, G_PARAM_READWRITE);
v4lelement->control_specs = g_list_append(v4lelement->control_specs, spec);
return TRUE; return TRUE;
} }
@ -120,6 +156,21 @@ gst_v4l_close (GstV4lElement *v4lelement)
close(v4lelement->video_fd); close(v4lelement->video_fd);
v4lelement->video_fd = -1; v4lelement->video_fd = -1;
while (g_list_length(v4lelement->input_names) > 0)
{
gpointer data = g_list_nth_data(v4lelement->input_names, 0);
v4lelement->input_names = g_list_remove(v4lelement->input_names, data);
g_free(data);
}
g_list_free(v4lelement->norm_names);
v4lelement->norm_names = NULL;
while (g_list_length(v4lelement->control_specs) > 0)
{
gpointer data = g_list_nth_data(v4lelement->control_specs, 0);
v4lelement->control_specs = g_list_remove(v4lelement->control_specs, data);
g_param_spec_unref(G_PARAM_SPEC(data));
}
return TRUE; return TRUE;
} }

View file

@ -85,23 +85,23 @@ extern "C" {
typedef enum { typedef enum {
V4L_PICTURE_HUE, V4L_PICTURE_HUE = 0,
V4L_PICTURE_BRIGHTNESS, V4L_PICTURE_BRIGHTNESS,
V4L_PICTURE_CONTRAST, V4L_PICTURE_CONTRAST,
V4L_PICTURE_SATURATION, V4L_PICTURE_SATURATION,
} GstV4lPictureType; } GstV4lPictureType;
extern char *picture_name[]; extern const char *picture_name[];
typedef enum { typedef enum {
V4L_AUDIO_VOLUME, V4L_AUDIO_VOLUME = 0,
V4L_AUDIO_MUTE, V4L_AUDIO_MUTE,
V4L_AUDIO_MODE, /* stereo, mono, ... (see videodev.h) */ V4L_AUDIO_MODE, /* stereo, mono, ... (see videodev.h) */
} GstV4lAudioType; } GstV4lAudioType;
extern char *audio_name[]; extern const char *audio_name[];
extern char *norm_name[]; extern const char *norm_name[];
/* open/close the device */ /* open/close the device */
@ -131,7 +131,7 @@ gboolean gst_v4l_set_audio (GstV4lElement *v4lelement, GstV4lAudioType type
/* overlay */ /* overlay */
gboolean gst_v4l_set_overlay (GstV4lElement *v4lelement, gchar *display); gboolean gst_v4l_set_overlay (GstV4lElement *v4lelement, gchar *display);
gboolean gst_v4l_set_window (GstV4lElement *v4lelement, gint x, gint y, gboolean gst_v4l_set_window (GstElement *element, gint x, gint y,
gint w, gint h, gint w, gint h,
struct video_clip *clips, gint num_clips); struct video_clip *clips, gint num_clips);
gboolean gst_v4l_enable_overlay (GstV4lElement *v4lelement, gboolean enable); gboolean gst_v4l_enable_overlay (GstV4lElement *v4lelement, gboolean enable);