From 0f124a569d2cb0296489bcc2e6406dea03633de8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 10 Oct 2003 12:47:41 +0000 Subject: [PATCH] Some interface implementations for video4linux/video4linux2 plugins: a Tuner interface, with which one can select inp... Original commit message from CVS: Some interface implementations for video4linux/video4linux2 plugins: * a Tuner interface, with which one can select inputs and stations. Audio work is underway here, but unfinished. * A Xoverlay interface with which one can do simple overlay. Similar to the API of the v4l/Xv XFree86 extension. Widget implementation for GTK-2.0 coming up in the sandbox. * Colorbalance - for adapting colors (brightness, contrast, etc.) - pretty basic and maybe somewhat overdesigned. But it'll do for now. Apart from these interfaces, there's also a loadable library 'xwindowlistener' that listenes to X for the movement of a window and the overlap of other windows. This is partly copied from xawtv (and thus partly GPL :(), but it's needed for the xoverlay interface implementation in the v4l/v4l2 elements. Lastly, some small changes to remove redundant properties from the v4l/v4l2 elements since these can be done much simpler. Comments appreciated! --- configure.ac | 4 + gst-libs/gst/Makefile.am | 22 +- gst-libs/gst/colorbalance/Makefile.am | 15 + gst-libs/gst/colorbalance/colorbalance.c | 103 +++ gst-libs/gst/colorbalance/colorbalance.h | 73 ++ .../gst/colorbalance/colorbalancechannel.c | 104 +++ .../gst/colorbalance/colorbalancechannel.h | 62 ++ gst-libs/gst/interfaces/colorbalance.c | 103 +++ gst-libs/gst/interfaces/colorbalance.h | 73 ++ gst-libs/gst/interfaces/colorbalancechannel.c | 104 +++ gst-libs/gst/interfaces/colorbalancechannel.h | 62 ++ gst-libs/gst/interfaces/tuner.c | 190 +++++ gst-libs/gst/interfaces/tuner.h | 96 +++ gst-libs/gst/interfaces/tunerchannel.c | 114 +++ gst-libs/gst/interfaces/tunerchannel.h | 77 ++ gst-libs/gst/interfaces/tunernorm.c | 95 +++ gst-libs/gst/interfaces/tunernorm.h | 55 ++ gst-libs/gst/interfaces/xoverlay.c | 74 ++ gst-libs/gst/interfaces/xoverlay.h | 61 ++ gst-libs/gst/tuner/Makefile.am | 17 + gst-libs/gst/tuner/tuner.c | 190 +++++ gst-libs/gst/tuner/tuner.h | 96 +++ gst-libs/gst/tuner/tunerchannel.c | 114 +++ gst-libs/gst/tuner/tunerchannel.h | 77 ++ gst-libs/gst/tuner/tunernorm.c | 95 +++ gst-libs/gst/tuner/tunernorm.h | 55 ++ gst-libs/gst/xoverlay/Makefile.am | 11 + gst-libs/gst/xoverlay/xoverlay.c | 74 ++ gst-libs/gst/xoverlay/xoverlay.h | 61 ++ gst-libs/gst/xwindowlistener/Makefile.am | 11 + .../gst/xwindowlistener/xwindowlistener.c | 656 ++++++++++++++++++ .../gst/xwindowlistener/xwindowlistener.h | 116 ++++ sys/v4l/gstv4lcolorbalance.c | 151 ++++ sys/v4l/gstv4lcolorbalance.h | 58 ++ sys/v4l/gstv4lelement-marshal.list | 3 - sys/v4l/gstv4lelement.c | 504 +++++--------- sys/v4l/gstv4lelement.h | 25 +- sys/v4l/gstv4lmjpegsink.c | 12 +- sys/v4l/gstv4lmjpegsrc.c | 34 +- sys/v4l/gstv4ltuner.c | 341 +++++++++ sys/v4l/gstv4ltuner.h | 83 +++ sys/v4l/gstv4lxoverlay.c | 126 ++++ sys/v4l/gstv4lxoverlay.h | 42 ++ sys/v4l/v4l-overlay_calls.c | 20 +- sys/v4l/v4l_calls.c | 204 +++--- sys/v4l/v4l_calls.h | 60 +- sys/v4l/v4lmjpegsrc_calls.c | 96 --- sys/v4l/v4lmjpegsrc_calls.h | 15 - 48 files changed, 4206 insertions(+), 628 deletions(-) create mode 100644 gst-libs/gst/colorbalance/Makefile.am create mode 100644 gst-libs/gst/colorbalance/colorbalance.c create mode 100644 gst-libs/gst/colorbalance/colorbalance.h create mode 100644 gst-libs/gst/colorbalance/colorbalancechannel.c create mode 100644 gst-libs/gst/colorbalance/colorbalancechannel.h create mode 100644 gst-libs/gst/interfaces/colorbalance.c create mode 100644 gst-libs/gst/interfaces/colorbalance.h create mode 100644 gst-libs/gst/interfaces/colorbalancechannel.c create mode 100644 gst-libs/gst/interfaces/colorbalancechannel.h create mode 100644 gst-libs/gst/interfaces/tuner.c create mode 100644 gst-libs/gst/interfaces/tuner.h create mode 100644 gst-libs/gst/interfaces/tunerchannel.c create mode 100644 gst-libs/gst/interfaces/tunerchannel.h create mode 100644 gst-libs/gst/interfaces/tunernorm.c create mode 100644 gst-libs/gst/interfaces/tunernorm.h create mode 100644 gst-libs/gst/interfaces/xoverlay.c create mode 100644 gst-libs/gst/interfaces/xoverlay.h create mode 100644 gst-libs/gst/tuner/Makefile.am create mode 100644 gst-libs/gst/tuner/tuner.c create mode 100644 gst-libs/gst/tuner/tuner.h create mode 100644 gst-libs/gst/tuner/tunerchannel.c create mode 100644 gst-libs/gst/tuner/tunerchannel.h create mode 100644 gst-libs/gst/tuner/tunernorm.c create mode 100644 gst-libs/gst/tuner/tunernorm.h create mode 100644 gst-libs/gst/xoverlay/Makefile.am create mode 100644 gst-libs/gst/xoverlay/xoverlay.c create mode 100644 gst-libs/gst/xoverlay/xoverlay.h create mode 100644 gst-libs/gst/xwindowlistener/Makefile.am create mode 100644 gst-libs/gst/xwindowlistener/xwindowlistener.c create mode 100644 gst-libs/gst/xwindowlistener/xwindowlistener.h create mode 100644 sys/v4l/gstv4lcolorbalance.c create mode 100644 sys/v4l/gstv4lcolorbalance.h delete mode 100644 sys/v4l/gstv4lelement-marshal.list create mode 100644 sys/v4l/gstv4ltuner.c create mode 100644 sys/v4l/gstv4ltuner.h create mode 100644 sys/v4l/gstv4lxoverlay.c create mode 100644 sys/v4l/gstv4lxoverlay.h diff --git a/configure.ac b/configure.ac index 5bcb93ac67..765bac4ccc 100644 --- a/configure.ac +++ b/configure.ac @@ -1287,6 +1287,7 @@ ext/xvid/Makefile gst-libs/Makefile gst-libs/gst/Makefile gst-libs/gst/audio/Makefile +gst-libs/gst/colorbalance/Makefile gst-libs/gst/floatcast/Makefile gst-libs/gst/gconf/Makefile gst-libs/gst/idct/Makefile @@ -1296,7 +1297,10 @@ gst-libs/gst/navigation/Makefile gst-libs/gst/play/Makefile gst-libs/gst/resample/Makefile gst-libs/gst/riff/Makefile +gst-libs/gst/tuner/Makefile gst-libs/gst/video/Makefile +gst-libs/gst/xoverlay/Makefile +gst-libs/gst/xwindowlistener/Makefile gst-libs/ext/Makefile gst-libs/ext/ffmpeg/Makefile gst-libs/ext/mplex/Makefile diff --git a/gst-libs/gst/Makefile.am b/gst-libs/gst/Makefile.am index 04acada7fe..06f12a07f8 100644 --- a/gst-libs/gst/Makefile.am +++ b/gst-libs/gst/Makefile.am @@ -4,10 +4,20 @@ else GCONF_DIR= endif -SUBDIRS = audio idct resample riff floatcast \ - $(GCONF_DIR) media-info mixer \ - navigation play video +if USE_XFREE +X_DIR=xwindowlistener +else +X_DIR= +endif -DIST_SUBDIRS = audio idct resample riff floatcast \ - gconf media-info mixer navigation \ - play video +SUBDIRS = audio colorbalance floatcast \ + $(GCONF_DIR) idct media-info \ + mixer navigation play \ + resample riff tuner video \ + xoverlay $(X_DIR) + +DIST_SUBDIRS = audio colorbalance floatcast \ + gconf idct media-info \ + mixer navigation play \ + resample riff tuner video \ + xoverlay xwindowlistener diff --git a/gst-libs/gst/colorbalance/Makefile.am b/gst-libs/gst/colorbalance/Makefile.am new file mode 100644 index 0000000000..cbd94c91a7 --- /dev/null +++ b/gst-libs/gst/colorbalance/Makefile.am @@ -0,0 +1,15 @@ +libgstinterfacesincludedir = \ + $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/colorbalance + +libgstinterfacesinclude_HEADERS = \ + colorbalance.h \ + colorbalancechannel.h + +lib_LTLIBRARIES = libgstcolorbalance.la + +libgstcolorbalance_la_SOURCES = \ + colorbalance.c \ + colorbalancechannel.c +libgstcolorbalance_la_LIBADD = +libgstcolorbalance_la_CFLAGS = $(GST_CFLAGS) $(GST_OPT_CFLAGS) +libgstcolorbalance_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst-libs/gst/colorbalance/colorbalance.c b/gst-libs/gst/colorbalance/colorbalance.c new file mode 100644 index 0000000000..829cf5f636 --- /dev/null +++ b/gst-libs/gst/colorbalance/colorbalance.c @@ -0,0 +1,103 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * colorbalance.c: image color balance interface design + * virtual class function wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "colorbalance.h" + +static void gst_color_balance_class_init (GstColorBalanceClass *klass); + +GType +gst_color_balance_get_type (void) +{ + static GType gst_color_balance_type = 0; + + if (!gst_color_balance_type) { + static const GTypeInfo gst_color_balance_info = { + sizeof (GstColorBalanceClass), + (GBaseInitFunc) gst_color_balance_class_init, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE, + "GstColorBalance", + &gst_color_balance_info, 0); + g_type_interface_add_prerequisite (gst_color_balance_type, + GST_TYPE_INTERFACE); + } + + return gst_color_balance_type; +} + +static void +gst_color_balance_class_init (GstColorBalanceClass *klass) +{ + /* default virtual functions */ + klass->list_channels = NULL; + klass->set_value = NULL; + klass->get_value = NULL; +} + +const GList * +gst_color_balance_list_channels (GstColorBalance *balance) +{ + GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); + + if (klass->list_channels) { + return klass->list_channels (balance); + } + + return NULL; +} + +void +gst_color_balance_set_value (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value) +{ + GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); + + if (klass->set_value) { + klass->set_value (balance, channel, value); + } +} + +gint +gst_color_balance_get_value (GstColorBalance *balance, + GstColorBalanceChannel *channel) +{ + GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); + + if (klass->get_value) { + return klass->get_value (balance, channel); + } + + return channel->min_value; +} diff --git a/gst-libs/gst/colorbalance/colorbalance.h b/gst-libs/gst/colorbalance/colorbalance.h new file mode 100644 index 0000000000..2b9d27d3af --- /dev/null +++ b/gst-libs/gst/colorbalance/colorbalance.h @@ -0,0 +1,73 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * color-balance.h: image color balance interface design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_COLOR_BALANCE_H__ +#define __GST_COLOR_BALANCE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_COLOR_BALANCE \ + (gst_color_balance_get_type ()) +#define GST_COLOR_BALANCE(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_COLOR_BALANCE, \ + GstColorBalance)) +#define GST_COLOR_BALANCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_COLOR_BALANCE, \ + GstColorBalanceClass)) +#define GST_IS_COLOR_BALANCE(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE)) +#define GST_IS_COLOR_BALANCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE)) +#define GST_COLOR_BALANCE_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceClass)) + +typedef struct _GstColorBalance GstColorBalance; + +typedef struct _GstColorBalanceClass { + GTypeInterface klass; + + /* virtual functions */ + const GList * (* list_channels) (GstColorBalance *balance); + + void (* set_value) (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value); + gint (* get_value) (GstColorBalance *balance, + GstColorBalanceChannel *channel); +} GstColorBalanceClass; + +GType gst_color_balance_get_type (void); + +/* virtual class function wrappers */ +const GList * + gst_color_balance_list_channels (GstColorBalance *balance); +void gst_color_balance_set_value (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value); +gint gst_color_balance_get_value (GstColorBalance *balance, + GstColorBalanceChannel *channel); + +G_END_DECLS + +#endif /* __GST_COLOR_BALANCE_H__ */ diff --git a/gst-libs/gst/colorbalance/colorbalancechannel.c b/gst-libs/gst/colorbalance/colorbalancechannel.c new file mode 100644 index 0000000000..8241bfe70b --- /dev/null +++ b/gst-libs/gst/colorbalance/colorbalancechannel.c @@ -0,0 +1,104 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * colorbalancechannel.c: colorbalance channel object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "colorbalancechannel.h" + +enum { + /* FILL ME */ + SIGNAL_VALUE_CHANGED, + LAST_SIGNAL +}; + +static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass); +static void gst_color_balance_channel_init (GstColorBalanceChannel *balance); +static void gst_color_balance_channel_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; +static guint signals[LAST_SIGNAL] = { 0 }; + +GType +gst_color_balance_channel_get_type (void) +{ + static GType gst_color_balance_channel_type = 0; + + if (!gst_color_balance_channel_type) { + static const GTypeInfo color_balance_channel_info = { + sizeof (GstColorBalanceChannelClass), + NULL, + NULL, + (GClassInitFunc) gst_color_balance_channel_class_init, + NULL, + NULL, + sizeof (GstColorBalanceChannel), + 0, + (GInstanceInitFunc) gst_color_balance_channel_init, + NULL + }; + + gst_color_balance_channel_type = + g_type_register_static (G_TYPE_OBJECT, + "GstColorBalanceChannel", + &color_balance_channel_info, 0); + } + + return gst_color_balance_channel_type; +} + +static void +gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + signals[SIGNAL_VALUE_CHANGED] = + g_signal_new ("value_changed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstColorBalanceChannelClass, + value_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + + object_klass->dispose = gst_color_balance_channel_dispose; +} + +static void +gst_color_balance_channel_init (GstColorBalanceChannel *channel) +{ + channel->label = NULL; + channel->min_value = channel->max_value = 0; +} + +static void +gst_color_balance_channel_dispose (GObject *object) +{ + GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object); + + if (channel->label) + g_free (channel->label); + + if (parent_class->dispose) + parent_class->dispose (object); +} diff --git a/gst-libs/gst/colorbalance/colorbalancechannel.h b/gst-libs/gst/colorbalance/colorbalancechannel.h new file mode 100644 index 0000000000..5f738ecb84 --- /dev/null +++ b/gst-libs/gst/colorbalance/colorbalancechannel.h @@ -0,0 +1,62 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * colorbalancechannel.h: individual channel object + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_COLOR_BALANCE_CHANNEL_H__ +#define __GST_COLOR_BALANCE_CHANNEL_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_COLOR_BALANCE_CHANNEL \ + (gst_color_balance_channel_get_type ()) +#define GST_COLOR_BALANCE_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL, \ + GstColorBalanceChannel)) +#define GST_COLOR_BALANCE_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL, \ + GstColorBalanceChannelClass)) +#define GST_IS_COLOR_BALANCE_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL)) +#define GST_IS_COLOR_BALANCE_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL)) + +typedef struct _GstColorBalanceChannel { + GObject parent; + + gchar *label; + gint min_value, + max_value; +} GstColorBalanceChannel; + +typedef struct _GstColorBalanceChannelClass { + GObjectClass parent; + + /* signals */ + void (* value_changed) (GstColorBalanceChannel *channel, + gint value); +} GstColorBalanceChannelClass; + +GType gst_color_balance_channel_get_type (void); + +G_END_DECLS + +#endif /* __GST_COLOR_BALANCE_CHANNEL_H__ */ diff --git a/gst-libs/gst/interfaces/colorbalance.c b/gst-libs/gst/interfaces/colorbalance.c new file mode 100644 index 0000000000..829cf5f636 --- /dev/null +++ b/gst-libs/gst/interfaces/colorbalance.c @@ -0,0 +1,103 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * colorbalance.c: image color balance interface design + * virtual class function wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "colorbalance.h" + +static void gst_color_balance_class_init (GstColorBalanceClass *klass); + +GType +gst_color_balance_get_type (void) +{ + static GType gst_color_balance_type = 0; + + if (!gst_color_balance_type) { + static const GTypeInfo gst_color_balance_info = { + sizeof (GstColorBalanceClass), + (GBaseInitFunc) gst_color_balance_class_init, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + gst_color_balance_type = g_type_register_static (G_TYPE_INTERFACE, + "GstColorBalance", + &gst_color_balance_info, 0); + g_type_interface_add_prerequisite (gst_color_balance_type, + GST_TYPE_INTERFACE); + } + + return gst_color_balance_type; +} + +static void +gst_color_balance_class_init (GstColorBalanceClass *klass) +{ + /* default virtual functions */ + klass->list_channels = NULL; + klass->set_value = NULL; + klass->get_value = NULL; +} + +const GList * +gst_color_balance_list_channels (GstColorBalance *balance) +{ + GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); + + if (klass->list_channels) { + return klass->list_channels (balance); + } + + return NULL; +} + +void +gst_color_balance_set_value (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value) +{ + GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); + + if (klass->set_value) { + klass->set_value (balance, channel, value); + } +} + +gint +gst_color_balance_get_value (GstColorBalance *balance, + GstColorBalanceChannel *channel) +{ + GstColorBalanceClass *klass = GST_COLOR_BALANCE_GET_CLASS (balance); + + if (klass->get_value) { + return klass->get_value (balance, channel); + } + + return channel->min_value; +} diff --git a/gst-libs/gst/interfaces/colorbalance.h b/gst-libs/gst/interfaces/colorbalance.h new file mode 100644 index 0000000000..2b9d27d3af --- /dev/null +++ b/gst-libs/gst/interfaces/colorbalance.h @@ -0,0 +1,73 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * color-balance.h: image color balance interface design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_COLOR_BALANCE_H__ +#define __GST_COLOR_BALANCE_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_COLOR_BALANCE \ + (gst_color_balance_get_type ()) +#define GST_COLOR_BALANCE(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_COLOR_BALANCE, \ + GstColorBalance)) +#define GST_COLOR_BALANCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_COLOR_BALANCE, \ + GstColorBalanceClass)) +#define GST_IS_COLOR_BALANCE(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE)) +#define GST_IS_COLOR_BALANCE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE)) +#define GST_COLOR_BALANCE_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_COLOR_BALANCE, GstColorBalanceClass)) + +typedef struct _GstColorBalance GstColorBalance; + +typedef struct _GstColorBalanceClass { + GTypeInterface klass; + + /* virtual functions */ + const GList * (* list_channels) (GstColorBalance *balance); + + void (* set_value) (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value); + gint (* get_value) (GstColorBalance *balance, + GstColorBalanceChannel *channel); +} GstColorBalanceClass; + +GType gst_color_balance_get_type (void); + +/* virtual class function wrappers */ +const GList * + gst_color_balance_list_channels (GstColorBalance *balance); +void gst_color_balance_set_value (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value); +gint gst_color_balance_get_value (GstColorBalance *balance, + GstColorBalanceChannel *channel); + +G_END_DECLS + +#endif /* __GST_COLOR_BALANCE_H__ */ diff --git a/gst-libs/gst/interfaces/colorbalancechannel.c b/gst-libs/gst/interfaces/colorbalancechannel.c new file mode 100644 index 0000000000..8241bfe70b --- /dev/null +++ b/gst-libs/gst/interfaces/colorbalancechannel.c @@ -0,0 +1,104 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * colorbalancechannel.c: colorbalance channel object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "colorbalancechannel.h" + +enum { + /* FILL ME */ + SIGNAL_VALUE_CHANGED, + LAST_SIGNAL +}; + +static void gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass); +static void gst_color_balance_channel_init (GstColorBalanceChannel *balance); +static void gst_color_balance_channel_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; +static guint signals[LAST_SIGNAL] = { 0 }; + +GType +gst_color_balance_channel_get_type (void) +{ + static GType gst_color_balance_channel_type = 0; + + if (!gst_color_balance_channel_type) { + static const GTypeInfo color_balance_channel_info = { + sizeof (GstColorBalanceChannelClass), + NULL, + NULL, + (GClassInitFunc) gst_color_balance_channel_class_init, + NULL, + NULL, + sizeof (GstColorBalanceChannel), + 0, + (GInstanceInitFunc) gst_color_balance_channel_init, + NULL + }; + + gst_color_balance_channel_type = + g_type_register_static (G_TYPE_OBJECT, + "GstColorBalanceChannel", + &color_balance_channel_info, 0); + } + + return gst_color_balance_channel_type; +} + +static void +gst_color_balance_channel_class_init (GstColorBalanceChannelClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + signals[SIGNAL_VALUE_CHANGED] = + g_signal_new ("value_changed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstColorBalanceChannelClass, + value_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + + object_klass->dispose = gst_color_balance_channel_dispose; +} + +static void +gst_color_balance_channel_init (GstColorBalanceChannel *channel) +{ + channel->label = NULL; + channel->min_value = channel->max_value = 0; +} + +static void +gst_color_balance_channel_dispose (GObject *object) +{ + GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (object); + + if (channel->label) + g_free (channel->label); + + if (parent_class->dispose) + parent_class->dispose (object); +} diff --git a/gst-libs/gst/interfaces/colorbalancechannel.h b/gst-libs/gst/interfaces/colorbalancechannel.h new file mode 100644 index 0000000000..5f738ecb84 --- /dev/null +++ b/gst-libs/gst/interfaces/colorbalancechannel.h @@ -0,0 +1,62 @@ +/* GStreamer Color Balance + * Copyright (C) 2003 Ronald Bultje + * + * colorbalancechannel.h: individual channel object + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_COLOR_BALANCE_CHANNEL_H__ +#define __GST_COLOR_BALANCE_CHANNEL_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_COLOR_BALANCE_CHANNEL \ + (gst_color_balance_channel_get_type ()) +#define GST_COLOR_BALANCE_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL, \ + GstColorBalanceChannel)) +#define GST_COLOR_BALANCE_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL, \ + GstColorBalanceChannelClass)) +#define GST_IS_COLOR_BALANCE_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_COLOR_BALANCE_CHANNEL)) +#define GST_IS_COLOR_BALANCE_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_COLOR_BALANCE_CHANNEL)) + +typedef struct _GstColorBalanceChannel { + GObject parent; + + gchar *label; + gint min_value, + max_value; +} GstColorBalanceChannel; + +typedef struct _GstColorBalanceChannelClass { + GObjectClass parent; + + /* signals */ + void (* value_changed) (GstColorBalanceChannel *channel, + gint value); +} GstColorBalanceChannelClass; + +GType gst_color_balance_channel_get_type (void); + +G_END_DECLS + +#endif /* __GST_COLOR_BALANCE_CHANNEL_H__ */ diff --git a/gst-libs/gst/interfaces/tuner.c b/gst-libs/gst/interfaces/tuner.c new file mode 100644 index 0000000000..43dda8d0e1 --- /dev/null +++ b/gst-libs/gst/interfaces/tuner.c @@ -0,0 +1,190 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tuner.c: tuner design virtual class function wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tuner.h" + +static void gst_tuner_class_init (GstTunerClass *klass); + +GType +gst_tuner_get_type (void) +{ + static GType gst_tuner_type = 0; + + if (!gst_tuner_type) { + static const GTypeInfo gst_tuner_info = { + sizeof (GstTunerClass), + (GBaseInitFunc) gst_tuner_class_init, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + gst_tuner_type = g_type_register_static (G_TYPE_INTERFACE, + "GstTuner", + &gst_tuner_info, 0); + g_type_interface_add_prerequisite (gst_tuner_type, + GST_TYPE_INTERFACE); + } + + return gst_tuner_type; +} + +static void +gst_tuner_class_init (GstTunerClass *klass) +{ + /* default virtual functions */ + klass->list_channels = NULL; + klass->set_channel = NULL; + klass->get_channel = NULL; + + klass->list_norms = NULL; + klass->set_norm = NULL; + klass->get_norm = NULL; + + klass->set_frequency = NULL; + klass->get_frequency = NULL; + klass->signal_strength = NULL; +} + +const GList * +gst_tuner_list_channels (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->list_channels) { + return klass->list_channels (tuner); + } + + return NULL; +} + +void +gst_tuner_set_channel (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->set_channel) { + klass->set_channel (tuner, channel); + } +} + +const GstTunerChannel * +gst_tuner_get_channel (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->get_channel) { + return klass->get_channel (tuner); + } + + return NULL; +} + +const GList * +gst_tuner_list_norms (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->list_norms) { + return klass->list_norms (tuner); + } + + return NULL; +} + +void +gst_tuner_set_norm (GstTuner *tuner, + GstTunerNorm *norm) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->set_norm) { + klass->set_norm (tuner, norm); + } +} + +const GstTunerNorm * +gst_tuner_get_norm (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->get_norm) { + return klass->get_norm (tuner); + } + + return NULL; +} + +void +gst_tuner_set_frequency (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY)); + + if (klass->set_frequency) { + klass->set_frequency (tuner, channel, frequency); + } +} + +gulong +gst_tuner_get_frequency (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY), 0); + + if (klass->get_frequency) { + return klass->get_frequency (tuner, channel); + } + + return 0; +} + +gint +gst_tuner_signal_strength (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY), 0); + + if (klass->signal_strength) { + return klass->signal_strength (tuner, channel); + } + + return 0; +} diff --git a/gst-libs/gst/interfaces/tuner.h b/gst-libs/gst/interfaces/tuner.h new file mode 100644 index 0000000000..1cd51e1118 --- /dev/null +++ b/gst-libs/gst/interfaces/tuner.h @@ -0,0 +1,96 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tuner.h: tuner interface design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_TUNER_H__ +#define __GST_TUNER_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TUNER \ + (gst_tuner_get_type ()) +#define GST_TUNER(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER, GstTuner)) +#define GST_TUNER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER, GstTunerClass)) +#define GST_IS_TUNER(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER)) +#define GST_IS_TUNER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER)) +#define GST_TUNER_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TUNER, GstTunerClass)) + +typedef struct _GstTuner GstTuner; + +typedef struct _GstTunerClass { + GTypeInterface klass; + + /* virtual functions */ + const GList * (* list_channels) (GstTuner *tuner); + void (* set_channel) (GstTuner *tuner, + GstTunerChannel *channel); + const GstTunerChannel * + (* get_channel) (GstTuner *tuner); + + const GList * (* list_norms) (GstTuner *tuner); + void (* set_norm) (GstTuner *tuner, + GstTunerNorm *norm); + const GstTunerNorm * + (* get_norm) (GstTuner *tuner); + + void (* set_frequency) (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency); + gulong (* get_frequency) (GstTuner *tuner, + GstTunerChannel *channel); + gint (* signal_strength) (GstTuner *tuner, + GstTunerChannel *channel); +} GstTunerClass; + +GType gst_tuner_get_type (void); + +/* virtual class function wrappers */ +const GList * gst_tuner_list_channels (GstTuner *tuner); +void gst_tuner_set_channel (GstTuner *tuner, + GstTunerChannel *channel); +const GstTunerChannel * + gst_tuner_get_channel (GstTuner *tuner); + +const GList * gst_tuner_list_norms (GstTuner *tuner); +void gst_tuner_set_norm (GstTuner *tuner, + GstTunerNorm *channel); +const GstTunerNorm * + gst_tuner_get_norm (GstTuner *tuner); + +void gst_tuner_set_frequency (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency); +gulong gst_tuner_get_frequency (GstTuner *tuner, + GstTunerChannel *channel); +gint gst_tuner_signal_strength (GstTuner *tuner, + GstTunerChannel *channel); + +G_END_DECLS + +#endif /* __GST_TUNER_H__ */ diff --git a/gst-libs/gst/interfaces/tunerchannel.c b/gst-libs/gst/interfaces/tunerchannel.c new file mode 100644 index 0000000000..aa98978eb9 --- /dev/null +++ b/gst-libs/gst/interfaces/tunerchannel.c @@ -0,0 +1,114 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunerchannel.c: tuner channel object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tunerchannel.h" + +enum { + /* FILL ME */ + SIGNAL_FREQUENCY_CHANGED, + SIGNAL_SIGNAL_CHANGED, + LAST_SIGNAL +}; + +static void gst_tuner_channel_class_init (GstTunerChannelClass *klass); +static void gst_tuner_channel_init (GstTunerChannel *channel); +static void gst_tuner_channel_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; +static guint signals[LAST_SIGNAL] = { 0 }; + +GType +gst_tuner_channel_get_type (void) +{ + static GType gst_tuner_channel_type = 0; + + if (!gst_tuner_channel_type) { + static const GTypeInfo tuner_channel_info = { + sizeof (GstTunerChannelClass), + NULL, + NULL, + (GClassInitFunc) gst_tuner_channel_class_init, + NULL, + NULL, + sizeof (GstTunerChannel), + 0, + (GInstanceInitFunc) gst_tuner_channel_init, + NULL + }; + + gst_tuner_channel_type = + g_type_register_static (G_TYPE_OBJECT, + "GstTunerChannel", + &tuner_channel_info, 0); + } + + return gst_tuner_channel_type; +} + +static void +gst_tuner_channel_class_init (GstTunerChannelClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + signals[SIGNAL_FREQUENCY_CHANGED] = + g_signal_new ("frequency_changed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstTunerChannelClass, + frequency_changed), + NULL, NULL, g_cclosure_marshal_VOID__ULONG, + G_TYPE_NONE, 1, G_TYPE_ULONG); + signals[SIGNAL_SIGNAL_CHANGED] = + g_signal_new ("signal_changed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstTunerChannelClass, + signal_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + + object_klass->dispose = gst_tuner_channel_dispose; +} + +static void +gst_tuner_channel_init (GstTunerChannel *channel) +{ + channel->label = NULL; + channel->flags = 0; + channel->min_frequency = channel->max_frequency = 0; + channel->min_signal = channel->max_signal = 0; +} + +static void +gst_tuner_channel_dispose (GObject *object) +{ + GstTunerChannel *channel = GST_TUNER_CHANNEL (object); + + if (channel->label) + g_free (channel->label); + + if (parent_class->dispose) + parent_class->dispose (object); +} diff --git a/gst-libs/gst/interfaces/tunerchannel.h b/gst-libs/gst/interfaces/tunerchannel.h new file mode 100644 index 0000000000..b803145502 --- /dev/null +++ b/gst-libs/gst/interfaces/tunerchannel.h @@ -0,0 +1,77 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunerchannel.h: tuner channel object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_TUNER_CHANNEL_H__ +#define __GST_TUNER_CHANNEL_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TUNER_CHANNEL \ + (gst_tuner_channel_get_type ()) +#define GST_TUNER_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER_CHANNEL, \ + GstTunerChannel)) +#define GST_TUNER_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER_CHANNEL, \ + GstTunerChannelClass)) +#define GST_IS_TUNER_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_CHANNEL)) +#define GST_IS_TUNER_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_CHANNEL)) + +typedef enum { + GST_TUNER_CHANNEL_INPUT = (1<<0), + GST_TUNER_CHANNEL_OUTPUT = (1<<1), + GST_TUNER_CHANNEL_FREQUENCY = (1<<2), + GST_TUNER_CHANNEL_AUDIO = (1<<3), +} GstTunerChannelFlags; + +#define GST_TUNER_CHANNEL_HAS_FLAG(channel, flag) \ + ((channel)->flags & flag) + +typedef struct _GstTunerChannel { + GObject parent; + + gchar *label; + GstTunerChannelFlags flags; + gulong min_frequency, + max_frequency; + gint min_signal, + max_signal; +} GstTunerChannel; + +typedef struct _GstTunerChannelClass { + GObjectClass parent; + + /* signals */ + void (*frequency_changed) (GstTunerChannel *tuner, + gulong frequency); + void (*signal_changed) (GstTunerChannel *tuner, + gint signal); +} GstTunerChannelClass; + +GType gst_tuner_channel_get_type (void); + +G_END_DECLS + +#endif /* __GST_TUNER_CHANNEL_H__ */ diff --git a/gst-libs/gst/interfaces/tunernorm.c b/gst-libs/gst/interfaces/tunernorm.c new file mode 100644 index 0000000000..48d75de265 --- /dev/null +++ b/gst-libs/gst/interfaces/tunernorm.c @@ -0,0 +1,95 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunernorm.c: tuner norm object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tunernorm.h" + +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +static void gst_tuner_norm_class_init (GstTunerNormClass *klass); +static void gst_tuner_norm_init (GstTunerNorm *norm); +static void gst_tuner_norm_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; +/*static guint signals[LAST_SIGNAL] = { 0 };*/ + +GType +gst_tuner_norm_get_type (void) +{ + static GType gst_tuner_norm_type = 0; + + if (!gst_tuner_norm_type) { + static const GTypeInfo tuner_norm_info = { + sizeof (GstTunerNormClass), + NULL, + NULL, + (GClassInitFunc) gst_tuner_norm_class_init, + NULL, + NULL, + sizeof (GstTunerNorm), + 0, + (GInstanceInitFunc) gst_tuner_norm_init, + NULL + }; + + gst_tuner_norm_type = + g_type_register_static (G_TYPE_OBJECT, + "GstTunerNorm", + &tuner_norm_info, 0); + } + + return gst_tuner_norm_type; +} + +static void +gst_tuner_norm_class_init (GstTunerNormClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + object_klass->dispose = gst_tuner_norm_dispose; +} + +static void +gst_tuner_norm_init (GstTunerNorm *norm) +{ + norm->label = NULL; + norm->fps = 0.; +} + +static void +gst_tuner_norm_dispose (GObject *object) +{ + GstTunerNorm *norm = GST_TUNER_NORM (object); + + if (norm->label) + g_free (norm->label); + + if (parent_class->dispose) + parent_class->dispose (object); +} diff --git a/gst-libs/gst/interfaces/tunernorm.h b/gst-libs/gst/interfaces/tunernorm.h new file mode 100644 index 0000000000..3e6e801d78 --- /dev/null +++ b/gst-libs/gst/interfaces/tunernorm.h @@ -0,0 +1,55 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunernorm.h: tuner norm object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_TUNER_NORM_H__ +#define __GST_TUNER_NORM_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TUNER_NORM \ + (gst_tuner_norm_get_type ()) +#define GST_TUNER_NORM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER_NORM, GstTunerNorm)) +#define GST_TUNER_NORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER_NORM, GstTunerNormClass)) +#define GST_IS_TUNER_NORM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_NORM)) +#define GST_IS_TUNER_NORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_NORM)) + +typedef struct _GstTunerNorm { + GObject parent; + + gchar *label; + gfloat fps; +} GstTunerNorm; + +typedef struct _GstTunerNormClass { + GObjectClass parent; +} GstTunerNormClass; + +GType gst_tuner_norm_get_type (void); + +G_END_DECLS + +#endif /* __GST_TUNER_NORM_H__ */ diff --git a/gst-libs/gst/interfaces/xoverlay.c b/gst-libs/gst/interfaces/xoverlay.c new file mode 100644 index 0000000000..f0b4ebb5d6 --- /dev/null +++ b/gst-libs/gst/interfaces/xoverlay.c @@ -0,0 +1,74 @@ +/* GStreamer X-based Overlay + * Copyright (C) 2003 Ronald Bultje + * + * tv-mixer.c: tv-mixer design virtual class function wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xoverlay.h" + +static void gst_x_overlay_class_init (GstXOverlayClass *klass); + +GType +gst_x_overlay_get_type (void) +{ + static GType gst_x_overlay_type = 0; + + if (!gst_x_overlay_type) { + static const GTypeInfo gst_x_overlay_info = { + sizeof (GstXOverlayClass), + (GBaseInitFunc) gst_x_overlay_class_init, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + gst_x_overlay_type = g_type_register_static (G_TYPE_INTERFACE, + "GstXOverlay", + &gst_x_overlay_info, 0); + g_type_interface_add_prerequisite (gst_x_overlay_type, + GST_TYPE_INTERFACE); + } + + return gst_x_overlay_type; +} + +static void +gst_x_overlay_class_init (GstXOverlayClass *klass) +{ + /* default virtual functions */ + klass->set_xwindow_id = NULL; +} + +void +gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, + XID xwindow_id) +{ + GstXOverlayClass *klass = GST_X_OVERLAY_GET_CLASS (overlay); + + if (klass->set_xwindow_id) { + klass->set_xwindow_id (overlay, xwindow_id); + } +} diff --git a/gst-libs/gst/interfaces/xoverlay.h b/gst-libs/gst/interfaces/xoverlay.h new file mode 100644 index 0000000000..15258765bc --- /dev/null +++ b/gst-libs/gst/interfaces/xoverlay.h @@ -0,0 +1,61 @@ +/* GStreamer X-based Overlay + * Copyright (C) 2003 Ronald Bultje + * + * x-overlay.h: X-based overlay interface design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_X_OVERLAY_H__ +#define __GST_X_OVERLAY_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_X_OVERLAY \ + (gst_x_overlay_get_type ()) +#define GST_X_OVERLAY(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_X_OVERLAY, GstXOverlay)) +#define GST_X_OVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_X_OVERLAY, GstXOverlayClass)) +#define GST_IS_X_OVERLAY(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_X_OVERLAY)) +#define GST_IS_X_OVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_X_OVERLAY)) +#define GST_X_OVERLAY_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_X_OVERLAY, GstXOverlayClass)) + +typedef struct _GstXOverlay GstXOverlay; + +typedef struct _GstXOverlayClass { + GTypeInterface klass; + + /* virtual functions */ + void (* set_xwindow_id) (GstXOverlay *overlay, + XID xwindow_id); +} GstXOverlayClass; + +GType gst_x_overlay_get_type (void); + +/* virtual class function wrappers */ +void gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, + XID xwindow_id); + +G_END_DECLS + +#endif /* __GST_X_OVERLAY_H__ */ diff --git a/gst-libs/gst/tuner/Makefile.am b/gst-libs/gst/tuner/Makefile.am new file mode 100644 index 0000000000..e349eb32fd --- /dev/null +++ b/gst-libs/gst/tuner/Makefile.am @@ -0,0 +1,17 @@ +libgstinterfacesincludedir = \ + $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/tuner + +libgstinterfacesinclude_HEADERS = \ + tuner.h \ + tunernorm.h \ + tunerchannel.h + +lib_LTLIBRARIES = libgsttuner.la + +libgsttuner_la_SOURCES = \ + tuner.c \ + tunernorm.c \ + tunerchannel.c +libgsttuner_la_LIBADD = +libgsttuner_la_CFLAGS = $(GST_CFLAGS) $(GST_OPT_CFLAGS) +libgsttuner_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst-libs/gst/tuner/tuner.c b/gst-libs/gst/tuner/tuner.c new file mode 100644 index 0000000000..43dda8d0e1 --- /dev/null +++ b/gst-libs/gst/tuner/tuner.c @@ -0,0 +1,190 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tuner.c: tuner design virtual class function wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tuner.h" + +static void gst_tuner_class_init (GstTunerClass *klass); + +GType +gst_tuner_get_type (void) +{ + static GType gst_tuner_type = 0; + + if (!gst_tuner_type) { + static const GTypeInfo gst_tuner_info = { + sizeof (GstTunerClass), + (GBaseInitFunc) gst_tuner_class_init, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + gst_tuner_type = g_type_register_static (G_TYPE_INTERFACE, + "GstTuner", + &gst_tuner_info, 0); + g_type_interface_add_prerequisite (gst_tuner_type, + GST_TYPE_INTERFACE); + } + + return gst_tuner_type; +} + +static void +gst_tuner_class_init (GstTunerClass *klass) +{ + /* default virtual functions */ + klass->list_channels = NULL; + klass->set_channel = NULL; + klass->get_channel = NULL; + + klass->list_norms = NULL; + klass->set_norm = NULL; + klass->get_norm = NULL; + + klass->set_frequency = NULL; + klass->get_frequency = NULL; + klass->signal_strength = NULL; +} + +const GList * +gst_tuner_list_channels (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->list_channels) { + return klass->list_channels (tuner); + } + + return NULL; +} + +void +gst_tuner_set_channel (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->set_channel) { + klass->set_channel (tuner, channel); + } +} + +const GstTunerChannel * +gst_tuner_get_channel (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->get_channel) { + return klass->get_channel (tuner); + } + + return NULL; +} + +const GList * +gst_tuner_list_norms (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->list_norms) { + return klass->list_norms (tuner); + } + + return NULL; +} + +void +gst_tuner_set_norm (GstTuner *tuner, + GstTunerNorm *norm) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->set_norm) { + klass->set_norm (tuner, norm); + } +} + +const GstTunerNorm * +gst_tuner_get_norm (GstTuner *tuner) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + if (klass->get_norm) { + return klass->get_norm (tuner); + } + + return NULL; +} + +void +gst_tuner_set_frequency (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY)); + + if (klass->set_frequency) { + klass->set_frequency (tuner, channel, frequency); + } +} + +gulong +gst_tuner_get_frequency (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY), 0); + + if (klass->get_frequency) { + return klass->get_frequency (tuner, channel); + } + + return 0; +} + +gint +gst_tuner_signal_strength (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstTunerClass *klass = GST_TUNER_GET_CLASS (tuner); + + g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY), 0); + + if (klass->signal_strength) { + return klass->signal_strength (tuner, channel); + } + + return 0; +} diff --git a/gst-libs/gst/tuner/tuner.h b/gst-libs/gst/tuner/tuner.h new file mode 100644 index 0000000000..1cd51e1118 --- /dev/null +++ b/gst-libs/gst/tuner/tuner.h @@ -0,0 +1,96 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tuner.h: tuner interface design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_TUNER_H__ +#define __GST_TUNER_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TUNER \ + (gst_tuner_get_type ()) +#define GST_TUNER(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER, GstTuner)) +#define GST_TUNER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER, GstTunerClass)) +#define GST_IS_TUNER(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER)) +#define GST_IS_TUNER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER)) +#define GST_TUNER_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_TUNER, GstTunerClass)) + +typedef struct _GstTuner GstTuner; + +typedef struct _GstTunerClass { + GTypeInterface klass; + + /* virtual functions */ + const GList * (* list_channels) (GstTuner *tuner); + void (* set_channel) (GstTuner *tuner, + GstTunerChannel *channel); + const GstTunerChannel * + (* get_channel) (GstTuner *tuner); + + const GList * (* list_norms) (GstTuner *tuner); + void (* set_norm) (GstTuner *tuner, + GstTunerNorm *norm); + const GstTunerNorm * + (* get_norm) (GstTuner *tuner); + + void (* set_frequency) (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency); + gulong (* get_frequency) (GstTuner *tuner, + GstTunerChannel *channel); + gint (* signal_strength) (GstTuner *tuner, + GstTunerChannel *channel); +} GstTunerClass; + +GType gst_tuner_get_type (void); + +/* virtual class function wrappers */ +const GList * gst_tuner_list_channels (GstTuner *tuner); +void gst_tuner_set_channel (GstTuner *tuner, + GstTunerChannel *channel); +const GstTunerChannel * + gst_tuner_get_channel (GstTuner *tuner); + +const GList * gst_tuner_list_norms (GstTuner *tuner); +void gst_tuner_set_norm (GstTuner *tuner, + GstTunerNorm *channel); +const GstTunerNorm * + gst_tuner_get_norm (GstTuner *tuner); + +void gst_tuner_set_frequency (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency); +gulong gst_tuner_get_frequency (GstTuner *tuner, + GstTunerChannel *channel); +gint gst_tuner_signal_strength (GstTuner *tuner, + GstTunerChannel *channel); + +G_END_DECLS + +#endif /* __GST_TUNER_H__ */ diff --git a/gst-libs/gst/tuner/tunerchannel.c b/gst-libs/gst/tuner/tunerchannel.c new file mode 100644 index 0000000000..aa98978eb9 --- /dev/null +++ b/gst-libs/gst/tuner/tunerchannel.c @@ -0,0 +1,114 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunerchannel.c: tuner channel object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tunerchannel.h" + +enum { + /* FILL ME */ + SIGNAL_FREQUENCY_CHANGED, + SIGNAL_SIGNAL_CHANGED, + LAST_SIGNAL +}; + +static void gst_tuner_channel_class_init (GstTunerChannelClass *klass); +static void gst_tuner_channel_init (GstTunerChannel *channel); +static void gst_tuner_channel_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; +static guint signals[LAST_SIGNAL] = { 0 }; + +GType +gst_tuner_channel_get_type (void) +{ + static GType gst_tuner_channel_type = 0; + + if (!gst_tuner_channel_type) { + static const GTypeInfo tuner_channel_info = { + sizeof (GstTunerChannelClass), + NULL, + NULL, + (GClassInitFunc) gst_tuner_channel_class_init, + NULL, + NULL, + sizeof (GstTunerChannel), + 0, + (GInstanceInitFunc) gst_tuner_channel_init, + NULL + }; + + gst_tuner_channel_type = + g_type_register_static (G_TYPE_OBJECT, + "GstTunerChannel", + &tuner_channel_info, 0); + } + + return gst_tuner_channel_type; +} + +static void +gst_tuner_channel_class_init (GstTunerChannelClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + signals[SIGNAL_FREQUENCY_CHANGED] = + g_signal_new ("frequency_changed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstTunerChannelClass, + frequency_changed), + NULL, NULL, g_cclosure_marshal_VOID__ULONG, + G_TYPE_NONE, 1, G_TYPE_ULONG); + signals[SIGNAL_SIGNAL_CHANGED] = + g_signal_new ("signal_changed", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GstTunerChannelClass, + signal_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, G_TYPE_INT); + + object_klass->dispose = gst_tuner_channel_dispose; +} + +static void +gst_tuner_channel_init (GstTunerChannel *channel) +{ + channel->label = NULL; + channel->flags = 0; + channel->min_frequency = channel->max_frequency = 0; + channel->min_signal = channel->max_signal = 0; +} + +static void +gst_tuner_channel_dispose (GObject *object) +{ + GstTunerChannel *channel = GST_TUNER_CHANNEL (object); + + if (channel->label) + g_free (channel->label); + + if (parent_class->dispose) + parent_class->dispose (object); +} diff --git a/gst-libs/gst/tuner/tunerchannel.h b/gst-libs/gst/tuner/tunerchannel.h new file mode 100644 index 0000000000..b803145502 --- /dev/null +++ b/gst-libs/gst/tuner/tunerchannel.h @@ -0,0 +1,77 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunerchannel.h: tuner channel object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_TUNER_CHANNEL_H__ +#define __GST_TUNER_CHANNEL_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TUNER_CHANNEL \ + (gst_tuner_channel_get_type ()) +#define GST_TUNER_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER_CHANNEL, \ + GstTunerChannel)) +#define GST_TUNER_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER_CHANNEL, \ + GstTunerChannelClass)) +#define GST_IS_TUNER_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_CHANNEL)) +#define GST_IS_TUNER_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_CHANNEL)) + +typedef enum { + GST_TUNER_CHANNEL_INPUT = (1<<0), + GST_TUNER_CHANNEL_OUTPUT = (1<<1), + GST_TUNER_CHANNEL_FREQUENCY = (1<<2), + GST_TUNER_CHANNEL_AUDIO = (1<<3), +} GstTunerChannelFlags; + +#define GST_TUNER_CHANNEL_HAS_FLAG(channel, flag) \ + ((channel)->flags & flag) + +typedef struct _GstTunerChannel { + GObject parent; + + gchar *label; + GstTunerChannelFlags flags; + gulong min_frequency, + max_frequency; + gint min_signal, + max_signal; +} GstTunerChannel; + +typedef struct _GstTunerChannelClass { + GObjectClass parent; + + /* signals */ + void (*frequency_changed) (GstTunerChannel *tuner, + gulong frequency); + void (*signal_changed) (GstTunerChannel *tuner, + gint signal); +} GstTunerChannelClass; + +GType gst_tuner_channel_get_type (void); + +G_END_DECLS + +#endif /* __GST_TUNER_CHANNEL_H__ */ diff --git a/gst-libs/gst/tuner/tunernorm.c b/gst-libs/gst/tuner/tunernorm.c new file mode 100644 index 0000000000..48d75de265 --- /dev/null +++ b/gst-libs/gst/tuner/tunernorm.c @@ -0,0 +1,95 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunernorm.c: tuner norm object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tunernorm.h" + +enum { + /* FILL ME */ + LAST_SIGNAL +}; + +static void gst_tuner_norm_class_init (GstTunerNormClass *klass); +static void gst_tuner_norm_init (GstTunerNorm *norm); +static void gst_tuner_norm_dispose (GObject *object); + +static GObjectClass *parent_class = NULL; +/*static guint signals[LAST_SIGNAL] = { 0 };*/ + +GType +gst_tuner_norm_get_type (void) +{ + static GType gst_tuner_norm_type = 0; + + if (!gst_tuner_norm_type) { + static const GTypeInfo tuner_norm_info = { + sizeof (GstTunerNormClass), + NULL, + NULL, + (GClassInitFunc) gst_tuner_norm_class_init, + NULL, + NULL, + sizeof (GstTunerNorm), + 0, + (GInstanceInitFunc) gst_tuner_norm_init, + NULL + }; + + gst_tuner_norm_type = + g_type_register_static (G_TYPE_OBJECT, + "GstTunerNorm", + &tuner_norm_info, 0); + } + + return gst_tuner_norm_type; +} + +static void +gst_tuner_norm_class_init (GstTunerNormClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + object_klass->dispose = gst_tuner_norm_dispose; +} + +static void +gst_tuner_norm_init (GstTunerNorm *norm) +{ + norm->label = NULL; + norm->fps = 0.; +} + +static void +gst_tuner_norm_dispose (GObject *object) +{ + GstTunerNorm *norm = GST_TUNER_NORM (object); + + if (norm->label) + g_free (norm->label); + + if (parent_class->dispose) + parent_class->dispose (object); +} diff --git a/gst-libs/gst/tuner/tunernorm.h b/gst-libs/gst/tuner/tunernorm.h new file mode 100644 index 0000000000..3e6e801d78 --- /dev/null +++ b/gst-libs/gst/tuner/tunernorm.h @@ -0,0 +1,55 @@ +/* GStreamer Tuner + * Copyright (C) 2003 Ronald Bultje + * + * tunernorm.h: tuner norm object design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_TUNER_NORM_H__ +#define __GST_TUNER_NORM_H__ + +#include + +G_BEGIN_DECLS + +#define GST_TYPE_TUNER_NORM \ + (gst_tuner_norm_get_type ()) +#define GST_TUNER_NORM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TUNER_NORM, GstTunerNorm)) +#define GST_TUNER_NORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TUNER_NORM, GstTunerNormClass)) +#define GST_IS_TUNER_NORM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TUNER_NORM)) +#define GST_IS_TUNER_NORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TUNER_NORM)) + +typedef struct _GstTunerNorm { + GObject parent; + + gchar *label; + gfloat fps; +} GstTunerNorm; + +typedef struct _GstTunerNormClass { + GObjectClass parent; +} GstTunerNormClass; + +GType gst_tuner_norm_get_type (void); + +G_END_DECLS + +#endif /* __GST_TUNER_NORM_H__ */ diff --git a/gst-libs/gst/xoverlay/Makefile.am b/gst-libs/gst/xoverlay/Makefile.am new file mode 100644 index 0000000000..184d505fc6 --- /dev/null +++ b/gst-libs/gst/xoverlay/Makefile.am @@ -0,0 +1,11 @@ +libgstinterfacesincludedir = \ + $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/xoverlay + +libgstinterfacesinclude_HEADERS = xoverlay.h + +lib_LTLIBRARIES = libgstxoverlay.la + +libgstxoverlay_la_SOURCES = xoverlay.c +libgstxoverlay_la_LIBADD = +libgstxoverlay_la_CFLAGS = $(GST_CFLAGS) $(GST_OPT_CFLAGS) +libgstxoverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) diff --git a/gst-libs/gst/xoverlay/xoverlay.c b/gst-libs/gst/xoverlay/xoverlay.c new file mode 100644 index 0000000000..f0b4ebb5d6 --- /dev/null +++ b/gst-libs/gst/xoverlay/xoverlay.c @@ -0,0 +1,74 @@ +/* GStreamer X-based Overlay + * Copyright (C) 2003 Ronald Bultje + * + * tv-mixer.c: tv-mixer design virtual class function wrappers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xoverlay.h" + +static void gst_x_overlay_class_init (GstXOverlayClass *klass); + +GType +gst_x_overlay_get_type (void) +{ + static GType gst_x_overlay_type = 0; + + if (!gst_x_overlay_type) { + static const GTypeInfo gst_x_overlay_info = { + sizeof (GstXOverlayClass), + (GBaseInitFunc) gst_x_overlay_class_init, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + }; + + gst_x_overlay_type = g_type_register_static (G_TYPE_INTERFACE, + "GstXOverlay", + &gst_x_overlay_info, 0); + g_type_interface_add_prerequisite (gst_x_overlay_type, + GST_TYPE_INTERFACE); + } + + return gst_x_overlay_type; +} + +static void +gst_x_overlay_class_init (GstXOverlayClass *klass) +{ + /* default virtual functions */ + klass->set_xwindow_id = NULL; +} + +void +gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, + XID xwindow_id) +{ + GstXOverlayClass *klass = GST_X_OVERLAY_GET_CLASS (overlay); + + if (klass->set_xwindow_id) { + klass->set_xwindow_id (overlay, xwindow_id); + } +} diff --git a/gst-libs/gst/xoverlay/xoverlay.h b/gst-libs/gst/xoverlay/xoverlay.h new file mode 100644 index 0000000000..15258765bc --- /dev/null +++ b/gst-libs/gst/xoverlay/xoverlay.h @@ -0,0 +1,61 @@ +/* GStreamer X-based Overlay + * Copyright (C) 2003 Ronald Bultje + * + * x-overlay.h: X-based overlay interface design + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_X_OVERLAY_H__ +#define __GST_X_OVERLAY_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_X_OVERLAY \ + (gst_x_overlay_get_type ()) +#define GST_X_OVERLAY(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_X_OVERLAY, GstXOverlay)) +#define GST_X_OVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_X_OVERLAY, GstXOverlayClass)) +#define GST_IS_X_OVERLAY(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_X_OVERLAY)) +#define GST_IS_X_OVERLAY_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_X_OVERLAY)) +#define GST_X_OVERLAY_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_X_OVERLAY, GstXOverlayClass)) + +typedef struct _GstXOverlay GstXOverlay; + +typedef struct _GstXOverlayClass { + GTypeInterface klass; + + /* virtual functions */ + void (* set_xwindow_id) (GstXOverlay *overlay, + XID xwindow_id); +} GstXOverlayClass; + +GType gst_x_overlay_get_type (void); + +/* virtual class function wrappers */ +void gst_x_overlay_set_xwindow_id (GstXOverlay *overlay, + XID xwindow_id); + +G_END_DECLS + +#endif /* __GST_X_OVERLAY_H__ */ diff --git a/gst-libs/gst/xwindowlistener/Makefile.am b/gst-libs/gst/xwindowlistener/Makefile.am new file mode 100644 index 0000000000..a3a589ba3b --- /dev/null +++ b/gst-libs/gst/xwindowlistener/Makefile.am @@ -0,0 +1,11 @@ +librarydir = $(libdir)/gstreamer-@GST_MAJORMINOR@ + +library_LTLIBRARIES = libgstxwindowlistener.la + +libgstxwindowlistener_la_SOURCES = xwindowlistener.c + +libraryincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/xwindowlistener +libraryinclude_HEADERS = xwindowlistener.h + +libgstxwindowlistener_la_CFLAGS = $(GST_CFLAGS) $(X_CFLAGS) +libgstxwindowlistener_la_LIBADD = $(GST_LIBS) $(GST_PLUGIN_LIBS) $(X_LIBS) diff --git a/gst-libs/gst/xwindowlistener/xwindowlistener.c b/gst-libs/gst/xwindowlistener/xwindowlistener.c new file mode 100644 index 0000000000..0a400a53f0 --- /dev/null +++ b/gst-libs/gst/xwindowlistener/xwindowlistener.c @@ -0,0 +1,656 @@ +/* G-Streamer X11 Window event/motion listener + * Copyright (C) 2003 Ronald Bultje + * + * xwindowlistener.c: implementation of the object + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "xwindowlistener.h" + +#define NUM_CLIPS 1024 + +static void gst_x_window_listener_class_init (GstXWindowListenerClass *klass); +static void gst_x_window_listener_init (GstXWindowListener *xwin); +static void gst_x_window_listener_dispose (GObject *object); + +static void gst_xwin_start (GstXWindowListener *xwin); +static void gst_xwin_stop (GstXWindowListener *xwin); + +static GObjectClass *parent_class = NULL; + +GType +gst_x_window_listener_get_type (void) +{ + static GType x_window_listener_type = 0; + + if (!x_window_listener_type) { + static const GTypeInfo x_window_listener_info = { + sizeof (GstXWindowListenerClass), + NULL, + NULL, + (GClassInitFunc) gst_x_window_listener_class_init, + NULL, + NULL, + sizeof (GstXWindowListener), + 0, + (GInstanceInitFunc) gst_x_window_listener_init, + NULL + }; + + x_window_listener_type = + g_type_register_static (G_TYPE_OBJECT, + "GstXWindowListener", + &x_window_listener_info, 0); + } + + return x_window_listener_type; +} + +static void +gst_x_window_listener_class_init (GstXWindowListenerClass *klass) +{ + GObjectClass *object_klass = (GObjectClass *) klass; + + parent_class = g_type_class_ref (G_TYPE_OBJECT); + + object_klass->dispose = gst_x_window_listener_dispose; +} + +static void +gst_x_window_listener_init (GstXWindowListener *xwin) +{ + xwin->xwindow_id = 0; + xwin->display_name = NULL; + + xwin->map_window_func = NULL; + xwin->set_window_func = NULL; + + xwin->thread = NULL; +} + +static void +gst_x_window_listener_dispose (GObject *object) +{ + GstXWindowListener *xwin = GST_X_WINDOW_LISTENER (object); + + /* stop overlay */ + gst_x_window_listener_set_xid (xwin, 0); + + if (xwin->display_name) { + g_free (xwin->display_name); + } + + if (parent_class->dispose) { + parent_class->dispose (object); + } +} + +GstXWindowListener * +gst_x_window_listener_new (gchar *display, + MapWindowFunc map_window_func, + SetWindowFunc set_window_func, + gpointer private_data) +{ + GstXWindowListener *xwin = + g_object_new (GST_TYPE_X_WINDOW_LISTENER, NULL); + + xwin->display_name = g_strdup (display); + xwin->map_window_func = map_window_func; + xwin->set_window_func = set_window_func; + xwin->private_data = private_data; + + return xwin; +} + +void +gst_x_window_listener_set_xid (GstXWindowListener *xwin, + XID id) +{ + g_return_if_fail (xwin != NULL); + + if (id == xwin->xwindow_id) { + return; + } + + if (xwin->xwindow_id && xwin->thread) { + gst_xwin_stop (xwin); + } + + xwin->xwindow_id = id; + + if (xwin->xwindow_id && + xwin->display_name && + xwin->display_name[0] == ':') { + g_return_if_fail (xwin->map_window_func != NULL); + g_return_if_fail (xwin->set_window_func != NULL); + + gst_xwin_start (xwin); + } +} + +/* + * The following code works as follows: + * - the "client" (the one who uses this object) sets an XID + * - we add a child XWindow to this XID, and follow motion/events + * - after each event, we determine the position, size and clips + * - next, we call the per-instance virtual functions set by the client + * - and we do all this in an endless cycle + * + * Unfortunately, part of this code is inspired by XawTV, so the + * runtime license for this code as a whole will be GPL unless + * someone can rewrite this or ask permission to the original + * author (Gerd Knorr ) to let us re-license + * this piece of code to LGPL. + */ + +#define DEBUG(format, args...) \ + GST_DEBUG ("XWL: " format, ##args) + +static void +gst_xwin_set_overlay (GstXWindowListener *xwin, + gboolean on) +{ + xwin->map_window_func (xwin->private_data, on); + + /* remember me */ + xwin->ov_visible = on; +} + +static gboolean +gst_xwin_refresh (gpointer data) +{ + GstXWindowListener *xwin = GST_X_WINDOW_LISTENER (data); + Window win, tmp; + XSetWindowAttributes xswa; + XWindowAttributes attr; + + g_mutex_lock (xwin->main_lock); + + win = DefaultRootWindow (xwin->main_display); + XGetWindowAttributes (xwin->main_display, win, &attr); + + xwin->ov_refresh_id = 0; + + if (!xwin->ov_move && xwin->ov_map && + xwin->ov_visibility == VisibilityUnobscured) { + g_mutex_unlock (xwin->main_lock); + return FALSE; /* skip */ + } + + if (xwin->ov_map && + xwin->ov_visibility != VisibilityFullyObscured) { + xwin->ov_refresh = TRUE; + } + + xswa.override_redirect = True; + xswa.backing_store = NotUseful; + xswa.save_under = False; + tmp = XCreateWindow (xwin->main_display,win, 0, 0, + attr.width, attr.height, 0, + CopyFromParent, InputOutput, CopyFromParent, + (CWSaveUnder | CWBackingStore| CWOverrideRedirect ), + &xswa); + XMapWindow (xwin->main_display, tmp); + XUnmapWindow (xwin->main_display, tmp); + XDestroyWindow (xwin->main_display, tmp); + xwin->ov_move = FALSE; + + g_mutex_unlock (xwin->main_lock); + + /* once */ + return FALSE; +} + +static int +x11_error_dev_null (Display *display, + XErrorEvent *event) +{ + return 0; +} + +#define ADD_CLIP(_x, _y, _w, _h) \ + do { \ + GstXWindowClip *clip = &xwin->clips[xwin->num_clips++]; \ + clip->x_offset = _x; \ + clip->y_offset = _y; \ + clip->width = _w; \ + clip->height = _h; \ + clip->data = NULL; \ + } while (0); + +static void +gst_xwin_set_clips (GstXWindowListener *xwin) +{ + Window root, rroot, parent, *kids, me; + XWindowAttributes attr; + guint numkids; + gint i; + gint x1, y1, w1, h1; + void *old_handler; + + old_handler = XSetErrorHandler (x11_error_dev_null); + + if (xwin->num_clips != 0) + xwin->ov_conf = TRUE; + xwin->num_clips = 0; + + root = DefaultRootWindow (xwin->display); + XGetWindowAttributes (xwin->display, root, &attr); + + if (xwin->x < 0) + ADD_CLIP (0, 0, -xwin->x, xwin->h); + if (xwin->y < 0) + ADD_CLIP (0, 0, xwin->w, -xwin->y); + if ((xwin->x + xwin->w) > attr.width) + ADD_CLIP (attr.width - xwin->x, 0, xwin->w, xwin->h); + if ((xwin->y + xwin->h) > attr.height) + ADD_CLIP (0, attr.height - xwin->y, xwin->w, xwin->h); + + me = xwin->child; + while (1) { + XQueryTree (xwin->display, me, &rroot, &parent, &kids, &numkids); + if (numkids) + XFree (kids); + if (root == parent) + break; + me = parent; + } + + XQueryTree (xwin->display, root, &rroot, &parent, &kids, &numkids); + for (i = 0; i < numkids; i++) + if (kids[i] == me) + break; + + for (i++; i < numkids; i++) { + XGetWindowAttributes (xwin->display, kids[i], &attr); + if (attr.map_state != IsViewable) + continue; + + x1 = attr.x - xwin->x; + y1 = attr.y - xwin->y; + w1 = attr.width + 2 * attr.border_width; + h1 = attr.height + 2 * attr.border_width; + if (((x1 + w1) < 0) || (x1 > xwin->w) || + ((y1 + h1) < 0) || (y1 > xwin->h)) + continue; + + if (x1 < 0) + x1 = 0; + if (y1 < 0) + y1 = 0; + ADD_CLIP (x1, y1, w1, h1); + } + XFree (kids); + + if (xwin->num_clips != 0) + xwin->ov_conf = TRUE; + + XSetErrorHandler (old_handler); +} + + +static gboolean +gst_xwin_window (GstXWindowListener *xwin) +{ + if (xwin->ov_map && xwin->ov_wmmap && + xwin->ov_visibility != VisibilityFullyObscured) { + /* visible */ + if (xwin->ov_visibility == VisibilityPartiallyObscured) { + /* set clips */ + gst_xwin_set_clips (xwin); + } + + if (xwin->ov_conf) { + xwin->set_window_func (xwin->private_data, + xwin->x, xwin->y, + xwin->w, xwin->h, + xwin->clips, xwin->num_clips); + + if (!xwin->ov_visible) + gst_xwin_set_overlay (xwin, TRUE); + + g_mutex_lock (xwin->main_lock); + + if (xwin->ov_refresh_id) + g_source_remove (xwin->ov_refresh_id); + xwin->ov_refresh_id = + g_timeout_add (200, (GSourceFunc) gst_xwin_refresh, + (gpointer) xwin); + + xwin->ov_conf = FALSE; + + g_mutex_unlock (xwin->main_lock); + } + } else { + /* not visible */ + if (xwin->ov_conf && xwin->ov_visible) { + gst_xwin_set_overlay (xwin, FALSE); + + g_mutex_lock (xwin->main_lock); + + if (xwin->ov_refresh_id) + g_source_remove (xwin->ov_refresh_id); + xwin->ov_refresh_id = + g_timeout_add (200, (GSourceFunc) gst_xwin_refresh, + (gpointer) xwin); + + xwin->ov_conf = FALSE; + + g_mutex_unlock (xwin->main_lock); + } + } + + xwin->ov_conf_id = 0; + + /* once is enough */ + return FALSE; +} + +static void +gst_xwin_configure (GstXWindowListener *xwin) +{ +#if 0 + /* This part is disabled, because the idle task will be done + * in the main thread instead of here. */ + if (!xwin->ov_conf_id) + xwin->ov_conf_id = + g_idle_add ((GSourceFunc) gst_rec_xoverlay_window, + (gpointer) xwin); +#endif + + gst_xwin_window ((gpointer) xwin); +} + +static void +gst_xwin_resize (GstXWindowListener *xwin) +{ + Drawable drawable, parent, *kids, root; + guint numkids; + XWindowAttributes attr; + + XGetWindowAttributes (xwin->display, + xwin->xwindow_id, &attr); + XMoveResizeWindow (xwin->display, xwin->child, + 0, 0, attr.width, attr.height); + + /* set the video window - the first clip is our own window */ + xwin->x = 0; + xwin->y = 0; + xwin->w = attr.width; + xwin->h = attr.height; + + drawable = xwin->child; + while (1) { + XQueryTree (xwin->display, drawable, + &root, &parent, &kids, &numkids); + if (numkids) + XFree(kids); + drawable = parent; + XGetWindowAttributes (xwin->display, drawable, &attr); + xwin->x += attr.x; + xwin->y += attr.y; + if (parent == attr.root) + break; + } + + xwin->ov_conf = TRUE; + xwin->ov_move = TRUE; + + gst_xwin_configure (xwin); +} + +static void +gst_xwin_init_window (GstXWindowListener *xwin) +{ + XWindowAttributes attr; + + /* start values */ + xwin->ov_conf = TRUE; + xwin->ov_map = xwin->ov_wmmap = TRUE; + xwin->ov_move = TRUE; + xwin->ov_refresh = FALSE; + g_mutex_lock (xwin->main_lock); + xwin->ov_conf_id = xwin->ov_refresh_id = 0; + g_mutex_unlock (xwin->main_lock); + xwin->ov_visibility = VisibilityFullyObscured; + + /* start the memory that we'll use */ + xwin->clips = g_malloc (sizeof (GstXWindowClip) * NUM_CLIPS); + xwin->num_clips = 0; + + /* open connection to X server */ + xwin->display = XOpenDisplay (xwin->display_name); + + /* window */ + XGetWindowAttributes (xwin->display, + xwin->xwindow_id, &attr); + xwin->child = XCreateSimpleWindow (xwin->display, + xwin->xwindow_id, 0, 0, + attr.width, attr.height, 0, 0, 0); + + /* listen to certain X events */ + XSelectInput (xwin->display, xwin->xwindow_id, + StructureNotifyMask); + XSelectInput (xwin->display, xwin->child, + VisibilityChangeMask | StructureNotifyMask); + XSelectInput (xwin->display, DefaultRootWindow (xwin->display), + VisibilityChangeMask | StructureNotifyMask | + SubstructureNotifyMask); + + /* show */ + XMapWindow (xwin->display, xwin->child); + + gst_xwin_resize (xwin); +} + +static void +gst_xwin_exit_window (GstXWindowListener *xwin) +{ + /* disable overlay */ + gst_xwin_set_overlay (xwin, FALSE); + + /* delete idle funcs */ + if (xwin->ov_conf_id != 0) + g_source_remove (xwin->ov_conf_id); + + g_mutex_lock (xwin->main_lock); + if (xwin->ov_refresh_id != 0) + g_source_remove (xwin->ov_refresh_id); + g_mutex_unlock (xwin->main_lock); + + /* get away from X and free mem */ + XDestroyWindow (xwin->display, xwin->child); + XCloseDisplay (xwin->display); + g_free (xwin->clips); +} + +static gpointer +gst_xwin_thread (gpointer data) +{ + GstXWindowListener *xwin = GST_X_WINDOW_LISTENER (data); + XEvent event; + + /* Hi, I'm GStreamer. What's your name? */ + gst_xwin_init_window (xwin); + + while (xwin->cycle) { + XNextEvent (xwin->display, &event); + + if (!xwin->cycle) + break; + + if ((event.type == ConfigureNotify && + event.xconfigure.window == xwin->xwindow_id) || + (event.type == MapNotify && + event.xmap.window == xwin->xwindow_id) || + (event.type == UnmapNotify && + event.xunmap.window == xwin->xwindow_id)) { + /* the 'parent' window, i.e. the widget provided by client */ + switch (event.type) { + case MapNotify: + xwin->ov_map = TRUE; + xwin->ov_conf = TRUE; + gst_xwin_configure (xwin); + break; + + case UnmapNotify: + xwin->ov_map = FALSE; + xwin->ov_conf = TRUE; + gst_xwin_configure (xwin); + break; + + case ConfigureNotify: + gst_xwin_resize (xwin); + break; + + default: + /* nothing */ + break; + } + } else if (event.xany.window == xwin->child) { + /* our own private window */ + switch (event.type) { + case Expose: + if (!event.xexpose.count) { + if (xwin->ov_refresh) { + xwin->ov_refresh = FALSE; + } else { + xwin->ov_conf = TRUE; + gst_xwin_configure (xwin); + } + } + break; + + case VisibilityNotify: + xwin->ov_visibility = event.xvisibility.state; + if (xwin->ov_refresh) { + if (event.xvisibility.state != VisibilityFullyObscured) + xwin->ov_refresh = FALSE; + } else { + xwin->ov_conf = TRUE; + gst_xwin_configure (xwin); + } + break; + + default: + /* nothing */ + break; + } + } else { + /* root window */ + switch (event.type) { + case MapNotify: + case UnmapNotify: + /* are we still visible? */ + if (!xwin->ov_refresh) { + XWindowAttributes attr; + gboolean on; + XGetWindowAttributes (xwin->display, + xwin->xwindow_id, &attr); + on = (attr.map_state == IsViewable); + xwin->ov_wmmap = on; + xwin->ov_conf = TRUE; + gst_xwin_configure (xwin); + } + break; + + case ConfigureNotify: + if (!xwin->ov_refresh) { + gst_xwin_resize (xwin); + } + break; + + default: + /* nothing */ + break; + } + } + } + + /* Nice to have met you, see you later */ + gst_xwin_exit_window (xwin); + + g_thread_exit (NULL); + + return NULL; +} + +static void +gst_xwin_start (GstXWindowListener *xwin) +{ + DEBUG ("Starting XWindow listener"); + + xwin->cycle = TRUE; + /* we use this main_display for two things: first of all, + * the window needs to be 'refreshed' to remove artifacts + * after every move. Secondly, we use this to 'unhang' the + * event handler after we've stopped it */ + xwin->main_lock = g_mutex_new (); + xwin->main_display = XOpenDisplay (xwin->display_name); + xwin->thread = g_thread_create (gst_xwin_thread, + (gpointer) xwin, + TRUE, NULL); + + DEBUG ("Started X-overlay"); +} + +static void +gst_xwin_stop (GstXWindowListener *xwin) +{ + DEBUG ("Stopping XWindow listener"); + + xwin->cycle = FALSE; + /* now, the event loop will hang. To prevent this from hanging + * our app, app, we re-do our refresh hack. Oh man, this is + * ugly. But it works. :). */ + g_mutex_lock (xwin->main_lock); + if (xwin->ov_refresh_id) + g_source_remove (xwin->ov_refresh_id); + g_mutex_unlock (xwin->main_lock); + + gst_xwin_refresh ((gpointer) xwin); + g_thread_join (xwin->thread); + XCloseDisplay (xwin->main_display); + g_mutex_free (xwin->main_lock); + + DEBUG ("Stopped X-overlay"); +} + +/* + * End of code inspired by XawTV. + */ + +static gboolean +plugin_init (GModule *module, + GstPlugin *plugin) +{ + gst_plugin_set_longname (plugin, + "X11-based XWindow event/motion listener"); + return TRUE; +} + +GstPluginDesc plugin_desc = { + GST_VERSION_MAJOR, + GST_VERSION_MINOR, + "xwindowlistener", + plugin_init +}; diff --git a/gst-libs/gst/xwindowlistener/xwindowlistener.h b/gst-libs/gst/xwindowlistener/xwindowlistener.h new file mode 100644 index 0000000000..834be67cad --- /dev/null +++ b/gst-libs/gst/xwindowlistener/xwindowlistener.h @@ -0,0 +1,116 @@ +/* G-Streamer X11 Window event/motion listener + * Copyright (C) 2003 Ronald Bultje + * + * xwindowlistener.h: object definition + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __X_WINDOW_LISTENER_H__ +#define __X_WINDOW_LISTENER_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_X_WINDOW_LISTENER \ + (gst_x_window_listener_get_type()) +#define GST_X_WINDOW_LISTENER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_X_WINDOW_LISTENER, \ + GstXWindowListener)) +#define GST_X_WINDOW_LISTENER_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_X_WINDOW_LISTENER, \ + GstXWindowListenerClass)) +#define GST_IS_X_WINDOW_LISTENER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_X_WINDOW_LISTENER)) +#define GST_IS_X_WINDOW_LISTENER_CLASS(obj) \ + (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_X_WINDOW_LISTENER)) + +typedef struct _GstXWindowListener GstXWindowListener; +typedef struct _GstXWindowListenerClass GstXWindowListenerClass; +typedef struct _GstXWindowClip GstXWindowClip; +typedef void (* MapWindowFunc) (gpointer your_data, + gboolean visible); +typedef void (* SetWindowFunc) (gpointer your_data, + gint x, gint y, + gint w, gint h, + GstXWindowClip *clips, + gint num_clips); + +struct _GstXWindowClip { + gint32 x_offset, + y_offset, + width, + height; + gpointer data; +}; + +struct _GstXWindowListener { + GObject parent; + + /* "per-instance virtual functions" */ + MapWindowFunc map_window_func; + SetWindowFunc set_window_func; + + /* private data with which we call the virtual functions */ + gpointer private_data; + + /* general information of what we're doing */ + gchar *display_name; + XID xwindow_id; + + /* one extra... */ + Display *main_display; + GMutex *main_lock; + + /* oh my g*d, this is going to be so horribly ugly */ + GThread *thread; + gboolean cycle; + + /* the overlay window + own thread */ + Display *display; + Drawable child; + gboolean ov_conf, + ov_map, + ov_visible, + ov_refresh, + ov_move, + ov_wmmap; + gint ov_visibility; + guint ov_conf_id, + ov_refresh_id; + gint x, y, w, h; + GstXWindowClip *clips; + gint num_clips; +}; + +struct _GstXWindowListenerClass { + GObjectClass parent; +}; + +GType gst_x_window_listener_get_type (void); +GstXWindowListener * + gst_x_window_listener_new (gchar *display, + MapWindowFunc map_window_func, + SetWindowFunc set_window_func, + gpointer private_data); +void gst_x_window_listener_set_xid (GstXWindowListener *xwin, + XID id); + +G_END_DECLS + +#endif /* __X_WINDOW_LISTENER_H__ */ diff --git a/sys/v4l/gstv4lcolorbalance.c b/sys/v4l/gstv4lcolorbalance.c new file mode 100644 index 0000000000..6e2346cd2d --- /dev/null +++ b/sys/v4l/gstv4lcolorbalance.c @@ -0,0 +1,151 @@ +/* GStreamer Color Balance interface implementation + * Copyright (C) 2003 Ronald Bultje + * + * gstv4lcolorbalance.c: color balance interface implementation for V4L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gstv4lcolorbalance.h" +#include "gstv4lelement.h" + +static void +gst_v4l_color_balance_channel_class_init(GstV4lColorBalanceChannelClass *klass); +static void +gst_v4l_color_balance_channel_init (GstV4lColorBalanceChannel *channel); + +static const GList * +gst_v4l_color_balance_list_channels (GstColorBalance *balance); +static void +gst_v4l_color_balance_set_value (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value); +static gint +gst_v4l_color_balance_get_value (GstColorBalance *balance, + GstColorBalanceChannel *channel); + +static GstColorBalanceChannelClass *parent_class = NULL; + +GType +gst_v4l_color_balance_channel_get_type (void) +{ + static GType gst_v4l_color_balance_channel_type = 0; + + if (!gst_v4l_color_balance_channel_type) { + static const GTypeInfo v4l_tuner_channel_info = { + sizeof (GstV4lColorBalanceChannelClass), + NULL, + NULL, + (GClassInitFunc) gst_v4l_color_balance_channel_class_init, + NULL, + NULL, + sizeof (GstV4lColorBalanceChannel), + 0, + (GInstanceInitFunc) gst_v4l_color_balance_channel_init, + NULL + }; + + gst_v4l_color_balance_channel_type = + g_type_register_static (GST_TYPE_COLOR_BALANCE_CHANNEL, + "GstV4lColorBalanceChannel", + &v4l_tuner_channel_info, 0); + } + + return gst_v4l_color_balance_channel_type; +} + +static void +gst_v4l_color_balance_channel_class_init (GstV4lColorBalanceChannelClass *klass) +{ + parent_class = g_type_class_ref (GST_TYPE_COLOR_BALANCE_CHANNEL); +} + +static void +gst_v4l_color_balance_channel_init (GstV4lColorBalanceChannel *channel) +{ + channel->index = 0; +} + +void +gst_v4l_color_balance_interface_init (GstColorBalanceClass *klass) +{ + /* default virtual functions */ + klass->list_channels = gst_v4l_color_balance_list_channels; + klass->set_value = gst_v4l_color_balance_set_value; + klass->get_value = gst_v4l_color_balance_get_value; +} + +static gboolean +gst_v4l_color_balance_contains_channel (GstV4lElement *v4lelement, + GstV4lColorBalanceChannel *v4lchannel) +{ + const GList *item; + + for (item = v4lelement->colors; item != NULL; item = item->next) + if (item->data == v4lchannel) + return TRUE; + + return FALSE; +} + +static const GList * +gst_v4l_color_balance_list_channels (GstColorBalance *balance) +{ + return GST_V4LELEMENT (balance)->colors; +} + +static void +gst_v4l_color_balance_set_value (GstColorBalance *balance, + GstColorBalanceChannel *channel, + gint value) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (balance); + GstV4lColorBalanceChannel *v4lchannel = + GST_V4L_COLOR_BALANCE_CHANNEL (channel); + + /* assert that we're opened and that we're using a known item */ + g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); + g_return_if_fail (gst_v4l_color_balance_contains_channel (v4lelement, + v4lchannel)); + + gst_v4l_set_picture (v4lelement, v4lchannel->index, value); +} + +static gint +gst_v4l_color_balance_get_value (GstColorBalance *balance, + GstColorBalanceChannel *channel) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (balance); + GstV4lColorBalanceChannel *v4lchannel = + GST_V4L_COLOR_BALANCE_CHANNEL (channel); + gint value; + + /* assert that we're opened and that we're using a known item */ + g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), 0); + g_return_val_if_fail (gst_v4l_color_balance_contains_channel (v4lelement, + v4lchannel), + 0); + + if (!gst_v4l_get_picture (v4lelement, v4lchannel->index, &value)) + return 0; + + return value; +} diff --git a/sys/v4l/gstv4lcolorbalance.h b/sys/v4l/gstv4lcolorbalance.h new file mode 100644 index 0000000000..c59d024413 --- /dev/null +++ b/sys/v4l/gstv4lcolorbalance.h @@ -0,0 +1,58 @@ +/* G-Streamer generic V4L element - Color Balance interface implementation + * Copyright (C) 2003 Ronald Bultje + * + * gstv4lcolorbalance.h: color balance interface implementation for V4L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_V4L_COLOR_BALANCE_H__ +#define __GST_V4L_COLOR_BALANCE_H__ + +#include +#include +#include "v4l_calls.h" + +G_BEGIN_DECLS + +#define GST_TYPE_V4L_COLOR_BALANCE_CHANNEL \ + (gst_v4l_color_balance_channel_get_type ()) +#define GST_V4L_COLOR_BALANCE_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L_COLOR_BALANCE_CHANNEL, \ + GstV4lColorBalanceChannel)) +#define GST_V4L_COLOR_BALANCE_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L_COLOR_BALANCE_CHANNEL, \ + GstV4lColorBalanceChannelClass)) +#define GST_IS_V4L_COLOR_BALANCE_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L_COLOR_BALANCE_CHANNEL)) +#define GST_IS_V4L_COLOR_BALANCE_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L_COLOR_BALANCE_CHANNEL)) + +typedef struct _GstV4lColorBalanceChannel { + GstColorBalanceChannel parent; + + GstV4lPictureType index; +} GstV4lColorBalanceChannel; + +typedef struct _GstV4lColorBalanceChannelClass { + GstColorBalanceChannelClass parent; +} GstV4lColorBalanceChannelClass; + +GType gst_v4l_color_balance_channel_get_type (void); + +void gst_v4l_color_balance_interface_init (GstColorBalanceClass *klass); + +#endif /* __GST_V4L_COLOR_BALANCE_H__ */ diff --git a/sys/v4l/gstv4lelement-marshal.list b/sys/v4l/gstv4lelement-marshal.list deleted file mode 100644 index dedf783097..0000000000 --- a/sys/v4l/gstv4lelement-marshal.list +++ /dev/null @@ -1,3 +0,0 @@ -BOOLEAN:INT,INT,INT,INT,POINTER,INT -BOOLEAN:STRING,POINTER -BOOLEAN:STRING,INT diff --git a/sys/v4l/gstv4lelement.c b/sys/v4l/gstv4lelement.c index 62b85331e7..4144def348 100644 --- a/sys/v4l/gstv4lelement.c +++ b/sys/v4l/gstv4lelement.c @@ -18,20 +18,19 @@ */ #ifdef HAVE_CONFIG_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif #include #endif #include #include "v4l_calls.h" -#include "gstv4lelement-marshal.h" +#include "gstv4ltuner.h" +#include "gstv4lxoverlay.h" +#include "gstv4lcolorbalance.h" /* elementfactory information */ static GstElementDetails gst_v4lelement_details = { "Generic video4linux Element", - "None/Video", + "Generic/Video", "LGPL", "Generic plugin for handling common video4linux calls", VERSION, @@ -44,52 +43,88 @@ enum { /* FILL ME */ SIGNAL_OPEN, SIGNAL_CLOSE, - SIGNAL_SET_VIDEOWINDOW, - SIGNAL_GET_ATTRIBUTE, - SIGNAL_SET_ATTRIBUTE, LAST_SIGNAL }; enum { ARG_0, - ARG_CHANNEL, - ARG_CHANNEL_NAMES, - ARG_NORM, - ARG_NORM_NAMES, - ARG_HAS_TUNER, - ARG_FREQUENCY, - ARG_HAS_AUDIO, - ARG_ATTRIBUTES, ARG_DEVICE, ARG_DEVICE_NAME, - ARG_DEVICE_IS_CAPTURE, - ARG_DEVICE_IS_OVERLAY, - ARG_DEVICE_IS_MJPEG_CAPTURE, - ARG_DEVICE_IS_MJPEG_PLAYBACK, - ARG_DEVICE_IS_MPEG_CAPTURE, - ARG_DEVICE_IS_MPEG_PLAYBACK, - ARG_DISPLAY, - ARG_DO_OVERLAY, - ARG_SIGNAL, + ARG_FLAGS, }; -static void gst_v4lelement_class_init (GstV4lElementClass *klass); -static void gst_v4lelement_init (GstV4lElement *v4lelement); -static void gst_v4lelement_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec); -static void gst_v4lelement_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec); -static GstElementStateReturn gst_v4lelement_change_state (GstElement *element); +static void gst_v4lelement_class_init (GstV4lElementClass *klass); +static void gst_v4lelement_init (GstV4lElement *v4lelement); +static void gst_v4lelement_dispose (GObject *object); +static void gst_v4lelement_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gst_v4lelement_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static GstElementStateReturn + gst_v4lelement_change_state (GstElement *element); static GstElementClass *parent_class = NULL; static guint gst_v4lelement_signals[LAST_SIGNAL] = { 0 }; +static gboolean +gst_v4l_iface_supported (GstInterface *iface, + GType iface_type) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (iface); + + g_assert (iface_type == GST_TYPE_TUNER || + iface_type == GST_TYPE_X_OVERLAY || + iface_type == GST_TYPE_COLOR_BALANCE); + + if (v4lelement->video_fd == -1) + return FALSE; + + if (iface_type == GST_TYPE_X_OVERLAY && + !GST_V4L_IS_OVERLAY(v4lelement)) + return FALSE; + + return TRUE; +} + +static void +gst_v4l_interface_init (GstInterfaceClass *klass) +{ + /* default virtual functions */ + klass->supported = gst_v4l_iface_supported; +} + +#define GST_TYPE_V4L_DEVICE_FLAGS (gst_v4l_device_get_type ()) +GType +gst_v4l_device_get_type (void) +{ + static GType v4l_device_type = 0; + + if (v4l_device_type == 0) { + static const GFlagsValue values[] = { + { VID_TYPE_CAPTURE, "CAPTURE", "Device can capture" }, + { VID_TYPE_TUNER, "TUNER", "Device has a tuner" }, + { VID_TYPE_OVERLAY, "OVERLAY", "Device can do overlay" }, + { VID_TYPE_MPEG_DECODER, "MPEG_DECODER", "Device can decode MPEG" }, + { VID_TYPE_MPEG_ENCODER, "MPEG_ENCODER", "Device can encode MPEG" }, + { VID_TYPE_MJPEG_DECODER, "MJPEG_DECODER", "Device can decode MJPEG" }, + { VID_TYPE_MJPEG_ENCODER, "MJPEG_ENCODER", "Device can encode MJPEG" }, + { 0x10000, "AUDIO", "Device handles audio" }, + { 0, NULL, NULL } + }; + + v4l_device_type = g_flags_register_static ("GstV4lDeviceTypeFlags", + values); + } + + return v4l_device_type; +} + GType gst_v4lelement_get_type (void) @@ -109,72 +144,49 @@ gst_v4lelement_get_type (void) (GInstanceInitFunc)gst_v4lelement_init, NULL }; - v4lelement_type = g_type_register_static(GST_TYPE_ELEMENT, "GstV4lElement", &v4lelement_info, 0); + static const GInterfaceInfo v4liface_info = { + (GInterfaceInitFunc) gst_v4l_interface_init, + NULL, + NULL, + }; + static const GInterfaceInfo v4l_tuner_info = { + (GInterfaceInitFunc) gst_v4l_tuner_interface_init, + NULL, + NULL, + }; + static const GInterfaceInfo v4l_xoverlay_info = { + (GInterfaceInitFunc) gst_v4l_xoverlay_interface_init, + NULL, + NULL, + }; + static const GInterfaceInfo v4l_colorbalance_info = { + (GInterfaceInitFunc) gst_v4l_color_balance_interface_init, + NULL, + NULL, + }; + + v4lelement_type = g_type_register_static(GST_TYPE_ELEMENT, + "GstV4lElement", + &v4lelement_info, 0); + + g_type_add_interface_static (v4lelement_type, + GST_TYPE_INTERFACE, + &v4liface_info); + g_type_add_interface_static (v4lelement_type, + GST_TYPE_TUNER, + &v4l_tuner_info); + g_type_add_interface_static (v4lelement_type, + GST_TYPE_X_OVERLAY, + &v4l_xoverlay_info); + g_type_add_interface_static (v4lelement_type, + GST_TYPE_COLOR_BALANCE, + &v4l_colorbalance_info); } + return v4lelement_type; } -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 gst_v4lelement_class_init (GstV4lElementClass *klass) { @@ -186,98 +198,15 @@ gst_v4lelement_class_init (GstV4lElementClass *klass) parent_class = g_type_class_ref(GST_TYPE_ELEMENT); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNEL, - g_param_spec_int("channel","channel","channel", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CHANNEL_NAMES, - g_param_spec_pointer("channel_names","channel_names","channel_names", - G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NORM, - g_param_spec_int("norm","norm","norm", - G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NORM_NAMES, - g_param_spec_pointer("norm_names","norm_names","norm_names", - G_PARAM_READABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HAS_TUNER, - g_param_spec_boolean("has_tuner","has_tuner","has_tuner", - 0,G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQUENCY, - g_param_spec_ulong("frequency","frequency","frequency", - 0,G_MAXULONG,0,G_PARAM_READWRITE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SIGNAL, - g_param_spec_uint("signal","signal","signal", - 0,65535,0,G_PARAM_READABLE)); - - 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_DEVICE, - g_param_spec_string("device","device","device", - NULL, G_PARAM_READWRITE)); + g_param_spec_string("device","Device","Device location", + NULL, G_PARAM_READWRITE)); g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_NAME, - g_param_spec_string("device_name","device_name","device_name", - NULL, G_PARAM_READABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_CAPTURE, - g_param_spec_boolean("can_capture","can_capture","can_capture", - 0,G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_OVERLAY, - g_param_spec_boolean("has_overlay","has_overlay","has_overlay", - 0,G_PARAM_READABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MJPEG_CAPTURE, - g_param_spec_boolean("can_capture_mjpeg","can_capture_mjpeg","can_capture_mjpeg", - 0,G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MJPEG_PLAYBACK, - g_param_spec_boolean("can_playback_mjpeg","can_playback_mjpeg","can_playback_mjpeg", - 0,G_PARAM_READABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MPEG_CAPTURE, - g_param_spec_boolean("can_capture_mpeg","can_capture_mpeg","can_capture_mpeg", - 0,G_PARAM_READABLE)); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DEVICE_IS_MPEG_PLAYBACK, - g_param_spec_boolean("can_playback_mpeg","can_playback_mpeg","can_playback_mpeg", - 0,G_PARAM_READABLE)); - - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_DISPLAY, - g_param_spec_string("display","display","display", - NULL, G_PARAM_WRITABLE)); - 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)); - - /* actions */ - 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; + g_param_spec_string("device_name","Device name","Name of the device", + NULL, G_PARAM_READABLE)); + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FLAGS, + g_param_spec_flags("flags","Flags","Device type flags", + GST_TYPE_V4L_DEVICE_FLAGS, 0,G_PARAM_READABLE)); /* signals */ gst_v4lelement_signals[SIGNAL_OPEN] = @@ -295,6 +224,8 @@ gst_v4lelement_class_init (GstV4lElementClass *klass) gobject_class->get_property = gst_v4lelement_get_property; gstelement_class->change_state = gst_v4lelement_change_state; + + gobject_class->dispose = gst_v4lelement_dispose; } @@ -304,17 +235,34 @@ gst_v4lelement_init (GstV4lElement *v4lelement) /* some default values */ v4lelement->video_fd = -1; v4lelement->buffer = NULL; - v4lelement->videodev = NULL; - v4lelement->display = NULL; + v4lelement->videodev = g_strdup ("/dev/video"); + v4lelement->display = g_strdup(g_getenv("DISPLAY"));; - v4lelement->norm = -1; - v4lelement->channel = -1; /* the first channel */ + v4lelement->norms = NULL; + v4lelement->channels = NULL; + v4lelement->colors = NULL; - v4lelement->frequency = 0; + v4lelement->overlay = gst_v4l_xoverlay_new (v4lelement); +} - v4lelement->norm_names = NULL; - v4lelement->input_names = NULL; - v4lelement->control_specs = NULL; + +static void +gst_v4lelement_dispose (GObject *object) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (object); + + gst_v4l_xoverlay_free (v4lelement); + + if (v4lelement->display) { + g_free (v4lelement->display); + } + + if (v4lelement->videodev) { + g_free (v4lelement->videodev); + } + + if (((GObjectClass *) parent_class)->dispose) + ((GObjectClass *) parent_class)->dispose (object); } @@ -332,49 +280,11 @@ gst_v4lelement_set_property (GObject *object, switch (prop_id) { - case ARG_CHANNEL: - v4lelement->channel = g_value_get_int(value); - if (GST_V4L_IS_OPEN(v4lelement) && !GST_V4L_IS_ACTIVE(v4lelement)) - { - if (v4lelement->norm >= VIDEO_MODE_PAL && - v4lelement->norm < VIDEO_MODE_AUTO && - v4lelement->channel >= 0) - if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm)) - return; - } - break; - case ARG_NORM: - v4lelement->norm = g_value_get_int(value); - if (GST_V4L_IS_OPEN(v4lelement) && !GST_V4L_IS_ACTIVE(v4lelement)) - { - if (v4lelement->norm >= VIDEO_MODE_PAL && - v4lelement->norm < VIDEO_MODE_AUTO && - v4lelement->channel >= 0) - if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, v4lelement->norm)) - return; - } - break; - case ARG_FREQUENCY: - v4lelement->frequency = g_value_get_ulong(value); - if (gst_v4l_has_tuner(v4lelement)) { - if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency)){ - return; - } - } - break; case ARG_DEVICE: if (v4lelement->videodev) g_free(v4lelement->videodev); v4lelement->videodev = g_strdup(g_value_get_string(value)); break; - case ARG_DO_OVERLAY: - if (GST_V4L_IS_OPEN(v4lelement)) - gst_v4l_enable_overlay(v4lelement, g_value_get_boolean(value)); - break; - case ARG_DISPLAY: - if (v4lelement->display) g_free(v4lelement->display); - v4lelement->display = g_strdup(g_value_get_string(value)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -389,9 +299,6 @@ gst_v4lelement_get_property (GObject *object, GParamSpec *pspec) { GstV4lElement *v4lelement; - 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_V4LELEMENT(object)); @@ -399,89 +306,26 @@ gst_v4lelement_get_property (GObject *object, switch (prop_id) { - case ARG_CHANNEL: - if (GST_V4L_IS_OPEN(v4lelement)) - gst_v4l_get_chan_norm(v4lelement, &temp_i, NULL); - g_value_set_int(value, temp_i); - break; - case ARG_CHANNEL_NAMES: - if (GST_V4L_IS_OPEN(v4lelement)) - list = gst_v4l_get_chan_names(v4lelement); - g_value_set_pointer(value, (gpointer)list); - break; - case ARG_NORM: - if (GST_V4L_IS_OPEN(v4lelement)) - gst_v4l_get_chan_norm(v4lelement, NULL, &temp_i); - g_value_set_int(value, temp_i); - break; - case ARG_NORM_NAMES: - for (temp_i=0;norm_name[temp_i]!=NULL;temp_i++) - list = g_list_append(list, (gpointer)norm_name[temp_i]); - g_value_set_pointer(value, (gpointer)list); - break; - case ARG_HAS_TUNER: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - if (gst_v4l_has_tuner(v4lelement)) - g_value_set_boolean(value, TRUE); - break; - case ARG_FREQUENCY: - if (GST_V4L_IS_OPEN(v4lelement)) - if (gst_v4l_has_tuner(v4lelement)) - gst_v4l_get_frequency(v4lelement, &temp_ul); - g_value_set_ulong(value, temp_ul); - break; - case ARG_SIGNAL: - if (GST_V4L_IS_OPEN(v4lelement)) - if (gst_v4l_has_tuner(v4lelement)) - gst_v4l_get_signal(v4lelement, &temp_i); - g_value_set_uint(value, temp_i); - break; - case ARG_HAS_AUDIO: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - if (gst_v4l_has_audio(v4lelement)) - g_value_set_boolean(value, TRUE); - break; case ARG_DEVICE: - g_value_set_string(value, v4lelement->videodev?v4lelement->videodev:"/dev/video"); + g_value_set_string(value, v4lelement->videodev); break; - case ARG_DEVICE_NAME: + case ARG_DEVICE_NAME: { + gchar *new = NULL; if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_string(value, v4lelement->vcap.name); - else - g_value_set_string(value, "None"); + new = v4lelement->vcap.name; + g_value_set_string(value, new); break; - case ARG_DEVICE_IS_CAPTURE: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_CAPTURE); - break; - case ARG_DEVICE_IS_OVERLAY: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_OVERLAY); - break; - case ARG_DEVICE_IS_MJPEG_CAPTURE: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MJPEG_ENCODER); - break; - case ARG_DEVICE_IS_MJPEG_PLAYBACK: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MJPEG_DECODER); - break; - case ARG_DEVICE_IS_MPEG_CAPTURE: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MPEG_ENCODER); - break; - case ARG_DEVICE_IS_MPEG_PLAYBACK: - g_value_set_boolean(value, FALSE); - if (GST_V4L_IS_OPEN(v4lelement)) - g_value_set_boolean(value, v4lelement->vcap.type & VID_TYPE_MPEG_DECODER); + } + case ARG_FLAGS: { + guint flags = 0; + if (GST_V4L_IS_OPEN(v4lelement)) { + flags |= v4lelement->vcap.type & 0x3C0B; + if (v4lelement->vcap.audios) + flags |= 0x10000; + } + g_value_set_flags(value, flags); break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -504,38 +348,21 @@ gst_v4lelement_change_state (GstElement *element) switch (GST_STATE_TRANSITION(element)) { case GST_STATE_NULL_TO_READY: - { - if (v4lelement->display) - gst_v4l_set_overlay(v4lelement, v4lelement->display); + gst_v4l_set_overlay(v4lelement); if (!gst_v4l_open(v4lelement)) return GST_STATE_FAILURE; - /* now, sync options */ - if (v4lelement->norm >= VIDEO_MODE_PAL && - v4lelement->norm < VIDEO_MODE_AUTO && - v4lelement->channel >= 0) - { - if (!gst_v4l_set_chan_norm(v4lelement, v4lelement->channel, - v4lelement->norm)) { - gst_v4l_close(v4lelement); - return GST_STATE_FAILURE; - } - } - if (v4lelement->frequency > 0 && gst_v4l_has_tuner(v4lelement)) - { - if (!gst_v4l_set_frequency(v4lelement, v4lelement->frequency)) { - gst_v4l_close(v4lelement); - return GST_STATE_FAILURE; - } - } + gst_v4l_xoverlay_open (v4lelement); g_signal_emit(G_OBJECT(v4lelement), gst_v4lelement_signals[SIGNAL_OPEN], 0, v4lelement->videodev); - } break; + case GST_STATE_READY_TO_NULL: + gst_v4l_xoverlay_close (v4lelement); + if (!gst_v4l_close(v4lelement)) return GST_STATE_FAILURE; @@ -557,6 +384,11 @@ gst_v4lelement_factory_init (GstPlugin *plugin) { GstElementFactory *factory; + /* actually, we can survive without it, but I'll create + * that handling later on. */ + if (!gst_library_load ("xwindowlistener")) + return FALSE; + /* create an elementfactory for the v4lelement */ factory = gst_element_factory_new("v4lelement", GST_TYPE_V4LELEMENT, &gst_v4lelement_details); diff --git a/sys/v4l/gstv4lelement.h b/sys/v4l/gstv4lelement.h index 4559983455..4b6ecfca90 100644 --- a/sys/v4l/gstv4lelement.h +++ b/sys/v4l/gstv4lelement.h @@ -21,6 +21,7 @@ #define __GST_V4LELEMENT_H__ #include +#include /* Because of some really cool feature in video4linux1, also known as * 'not including sys/types.h and sys/time.h', we had to include it @@ -56,10 +57,6 @@ extern "C" { typedef struct _GstV4lElement GstV4lElement; typedef struct _GstV4lElementClass GstV4lElementClass; -typedef struct _GstV4lRect { - gint x, y, w, h; -} GstV4lRect; - struct _GstV4lElement { GstElement element; @@ -79,14 +76,15 @@ struct _GstV4lElement { struct video_channel vchan; /* lists... */ - GList *control_specs; - GList *norm_names; - GList *input_names; + GList *colors; + GList *norms; + GList *channels; + + /* X-overlay */ + GstXWindowListener *overlay; + XID xwindow_id; /* caching values */ - gint channel; - gint norm; - gulong frequency; gchar *display; }; @@ -100,13 +98,6 @@ struct _GstV4lElementClass { 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); diff --git a/sys/v4l/gstv4lmjpegsink.c b/sys/v4l/gstv4lmjpegsink.c index 5c854da03f..683107d5a5 100644 --- a/sys/v4l/gstv4lmjpegsink.c +++ b/sys/v4l/gstv4lmjpegsink.c @@ -225,7 +225,7 @@ gst_v4lmjpegsink_sinkconnect (GstPad *pad, if (!gst_v4lmjpegsink_set_playback(v4lmjpegsink, v4lmjpegsink->width, v4lmjpegsink->height, v4lmjpegsink->x_offset, v4lmjpegsink->y_offset, - GST_V4LELEMENT(v4lmjpegsink)->norm, 0)) /* TODO: interlacing */ + GST_V4LELEMENT(v4lmjpegsink)->vchan.norm, 0)) /* TODO: interlacing */ continue; /* set buffer info */ @@ -454,16 +454,6 @@ gst_v4lmjpegsink_change_state (GstElement *element) parent_value = GST_STATE_FAILURE; } - if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY) - { - if ((GST_V4LELEMENT(v4lmjpegsink)->norm >= VIDEO_MODE_PAL || - GST_V4LELEMENT(v4lmjpegsink)->norm < VIDEO_MODE_AUTO) || - GST_V4LELEMENT(v4lmjpegsink)->channel < 0) - if (!gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lmjpegsink), - 0, GST_V4LELEMENT(v4lmjpegsink)->norm)) - return GST_STATE_FAILURE; - } - if (GST_ELEMENT_CLASS (parent_class)->change_state) return parent_value; diff --git a/sys/v4l/gstv4lmjpegsrc.c b/sys/v4l/gstv4lmjpegsrc.c index 3543fe3797..8bd58a1d25 100644 --- a/sys/v4l/gstv4lmjpegsrc.c +++ b/sys/v4l/gstv4lmjpegsrc.c @@ -710,7 +710,6 @@ static GstElementStateReturn gst_v4lmjpegsrc_change_state (GstElement *element) { GstV4lMjpegSrc *v4lmjpegsrc; - GstElementStateReturn parent_value; GTimeVal time; g_return_val_if_fail(GST_IS_V4LMJPEGSRC(element), GST_STATE_FAILURE); @@ -750,39 +749,8 @@ gst_v4lmjpegsrc_change_state (GstElement *element) break; } - if (GST_ELEMENT_CLASS (parent_class)->change_state) { - parent_value = GST_ELEMENT_CLASS (parent_class)->change_state (element); - } else { - parent_value = GST_STATE_FAILURE; - } - - if (GST_STATE_TRANSITION(element) == GST_STATE_NULL_TO_READY) - { - /* do autodetection if no input/norm is selected yet */ - if ((GST_V4LELEMENT(v4lmjpegsrc)->norm < VIDEO_MODE_PAL || - GST_V4LELEMENT(v4lmjpegsrc)->norm == VIDEO_MODE_AUTO) || - (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0 || - GST_V4LELEMENT(v4lmjpegsrc)->channel == V4L_MJPEG_INPUT_AUTO)) - { - gint norm, input; - - if (GST_V4LELEMENT(v4lmjpegsrc)->norm < 0) - norm = VIDEO_MODE_AUTO; - else - norm = GST_V4LELEMENT(v4lmjpegsrc)->norm; - - if (GST_V4LELEMENT(v4lmjpegsrc)->channel < 0) - input = V4L_MJPEG_INPUT_AUTO; - else - input = GST_V4LELEMENT(v4lmjpegsrc)->channel; - - if (!gst_v4lmjpegsrc_set_input_norm(v4lmjpegsrc, input, norm)) - return GST_STATE_FAILURE; - } - } - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return parent_value; + return GST_ELEMENT_CLASS (parent_class)->change_state (element); return GST_STATE_SUCCESS; } diff --git a/sys/v4l/gstv4ltuner.c b/sys/v4l/gstv4ltuner.c new file mode 100644 index 0000000000..fddec4d377 --- /dev/null +++ b/sys/v4l/gstv4ltuner.c @@ -0,0 +1,341 @@ +/* GStreamer Tuner interface implementation + * Copyright (C) 2003 Ronald Bultje + * + * gstv4ltuner.c: tuner interface implementation for V4L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +#include "gstv4ltuner.h" +#include "gstv4lelement.h" +#include "v4l_calls.h" + +static void gst_v4l_tuner_channel_class_init(GstV4lTunerChannelClass *klass); +static void gst_v4l_tuner_channel_init (GstV4lTunerChannel *channel); + +static void gst_v4l_tuner_norm_class_init (GstV4lTunerNormClass *klass); +static void gst_v4l_tuner_norm_init (GstV4lTunerNorm *norm); + +static const GList * + gst_v4l_tuner_list_channels (GstTuner *tuner); +static void gst_v4l_tuner_set_channel (GstTuner *tuner, + GstTunerChannel *channel); +static const GstTunerChannel * + gst_v4l_tuner_get_channel (GstTuner *tuner); + +static const GList * + gst_v4l_tuner_list_norms (GstTuner *tuner); +static void gst_v4l_tuner_set_norm (GstTuner *tuner, + GstTunerNorm *norm); +static const GstTunerNorm * + gst_v4l_tuner_get_norm (GstTuner *tuner); + +static void gst_v4l_tuner_set_frequency (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency); +static gulong gst_v4l_tuner_get_frequency (GstTuner *tuner, + GstTunerChannel *channel); +static gint gst_v4l_tuner_signal_strength (GstTuner *tuner, + GstTunerChannel *channel); + +static GstTunerNormClass *norm_parent_class = NULL; +static GstTunerChannelClass *channel_parent_class = NULL; + +GType +gst_v4l_tuner_channel_get_type (void) +{ + static GType gst_v4l_tuner_channel_type = 0; + + if (!gst_v4l_tuner_channel_type) { + static const GTypeInfo v4l_tuner_channel_info = { + sizeof (GstV4lTunerChannelClass), + NULL, + NULL, + (GClassInitFunc) gst_v4l_tuner_channel_class_init, + NULL, + NULL, + sizeof (GstV4lTunerChannel), + 0, + (GInstanceInitFunc) gst_v4l_tuner_channel_init, + NULL + }; + + gst_v4l_tuner_channel_type = + g_type_register_static (GST_TYPE_TUNER_CHANNEL, + "GstV4lTunerChannel", + &v4l_tuner_channel_info, 0); + } + + return gst_v4l_tuner_channel_type; +} + +static void +gst_v4l_tuner_channel_class_init (GstV4lTunerChannelClass *klass) +{ + channel_parent_class = g_type_class_ref (GST_TYPE_TUNER_CHANNEL); +} + +static void +gst_v4l_tuner_channel_init (GstV4lTunerChannel *channel) +{ + channel->index = 0; + channel->audio = 0; + channel->tuner = 0; +} + +GType +gst_v4l_tuner_norm_get_type (void) +{ + static GType gst_v4l_tuner_norm_type = 0; + + if (!gst_v4l_tuner_norm_type) { + static const GTypeInfo v4l_tuner_norm_info = { + sizeof (GstV4lTunerNormClass), + NULL, + NULL, + (GClassInitFunc) gst_v4l_tuner_norm_class_init, + NULL, + NULL, + sizeof (GstV4lTunerNorm), + 0, + (GInstanceInitFunc) gst_v4l_tuner_norm_init, + NULL + }; + + gst_v4l_tuner_norm_type = + g_type_register_static (GST_TYPE_TUNER_NORM, + "GstV4lTunerNorm", + &v4l_tuner_norm_info, 0); + } + + return gst_v4l_tuner_norm_type; +} + +static void +gst_v4l_tuner_norm_class_init (GstV4lTunerNormClass *klass) +{ + norm_parent_class = g_type_class_ref (GST_TYPE_TUNER_NORM); +} + +static void +gst_v4l_tuner_norm_init (GstV4lTunerNorm *norm) +{ + norm->index = 0; +} + +void +gst_v4l_tuner_interface_init (GstTunerClass *klass) +{ + /* default virtual functions */ + klass->list_channels = gst_v4l_tuner_list_channels; + klass->set_channel = gst_v4l_tuner_set_channel; + klass->get_channel = gst_v4l_tuner_get_channel; + + klass->list_norms = gst_v4l_tuner_list_norms; + klass->set_norm = gst_v4l_tuner_set_norm; + klass->get_norm = gst_v4l_tuner_get_norm; + + klass->set_frequency = gst_v4l_tuner_set_frequency; + klass->get_frequency = gst_v4l_tuner_get_frequency; + klass->signal_strength = gst_v4l_tuner_signal_strength; +} + +static gboolean +gst_v4l_tuner_contains_channel (GstV4lElement *v4lelement, + GstV4lTunerChannel *v4lchannel) +{ + const GList *item; + + for (item = v4lelement->channels; item != NULL; item = item->next) + if (item->data == v4lchannel) + return TRUE; + + return FALSE; +} + +static const GList * +gst_v4l_tuner_list_channels (GstTuner *tuner) +{ + return GST_V4LELEMENT (tuner)->channels; +} + +static void +gst_v4l_tuner_set_channel (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL (channel); + gint norm; + + /* assert that we're opened and that we're using a known item */ + g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); + g_return_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel)); + + gst_v4l_get_chan_norm (v4lelement, NULL, &norm); + gst_v4l_set_chan_norm (v4lelement, v4lchannel->index, norm); +} + +static const GstTunerChannel * +gst_v4l_tuner_get_channel (GstTuner *tuner) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GList *item; + gint channel; + + /* assert that we're opened */ + g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), NULL); + + gst_v4l_get_chan_norm (v4lelement, &channel, NULL); + + for (item = v4lelement->channels; item != NULL; item = item->next) { + if (channel == GST_V4L_TUNER_CHANNEL (item->data)->index) + return (const GstTunerChannel *) item->data; + } + + return NULL; +} + +static gboolean +gst_v4l_tuner_contains_norm (GstV4lElement *v4lelement, + GstV4lTunerNorm *v4lnorm) +{ + const GList *item; + + for (item = v4lelement->norms; item != NULL; item = item->next) + if (item->data == v4lnorm) + return TRUE; + + return FALSE; +} + +static const GList * +gst_v4l_tuner_list_norms (GstTuner *tuner) +{ + return GST_V4LELEMENT (tuner)->norms; +} + +static void +gst_v4l_tuner_set_norm (GstTuner *tuner, + GstTunerNorm *norm) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GstV4lTunerNorm *v4lnorm = GST_V4L_TUNER_NORM (norm); + gint channel; + + /* assert that we're opened and that we're using a known item */ + g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); + g_return_if_fail (gst_v4l_tuner_contains_norm (v4lelement, v4lnorm)); + + gst_v4l_get_chan_norm (v4lelement, &channel, NULL); + gst_v4l_set_chan_norm (v4lelement, channel, v4lnorm->index); +} + +static const GstTunerNorm * +gst_v4l_tuner_get_norm (GstTuner *tuner) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GList *item; + gint norm; + + /* assert that we're opened */ + g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), NULL); + + gst_v4l_get_chan_norm (v4lelement, NULL, &norm); + + for (item = v4lelement->norms; item != NULL; item = item->next) { + if (norm == GST_V4L_TUNER_NORM (item->data)->index) + return (const GstTunerNorm *) item->data; + } + + return NULL; +} + +static void +gst_v4l_tuner_set_frequency (GstTuner *tuner, + GstTunerChannel *channel, + gulong frequency) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL(channel); + gint chan; + + /* assert that we're opened and that we're using a known item */ + g_return_if_fail (GST_V4L_IS_OPEN (v4lelement)); + g_return_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY)); + g_return_if_fail (gst_v4l_tuner_contains_channel (v4lelement, v4lchannel)); + + gst_v4l_get_chan_norm (v4lelement, &chan, NULL); + if (chan == GST_V4L_TUNER_CHANNEL (channel)->index) { + gst_v4l_set_frequency (v4lelement, v4lchannel->tuner, frequency); + } +} + +static gulong +gst_v4l_tuner_get_frequency (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL(channel); + gint chan; + gulong frequency = 0; + + /* assert that we're opened and that we're using a known item */ + g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), 0); + g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY), 0); + g_return_val_if_fail (gst_v4l_tuner_contains_channel (v4lelement, + v4lchannel), 0); + + gst_v4l_get_chan_norm (v4lelement, &chan, NULL); + if (chan == GST_V4L_TUNER_CHANNEL (channel)->index) { + gst_v4l_get_frequency (v4lelement, v4lchannel->tuner, &frequency); + } + + return frequency; +} + +static gint +gst_v4l_tuner_signal_strength (GstTuner *tuner, + GstTunerChannel *channel) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (tuner); + GstV4lTunerChannel *v4lchannel = GST_V4L_TUNER_CHANNEL(channel); + gint chan; + gint signal = 0; + + /* assert that we're opened and that we're using a known item */ + g_return_val_if_fail (GST_V4L_IS_OPEN (v4lelement), 0); + g_return_val_if_fail (GST_TUNER_CHANNEL_HAS_FLAG (channel, + GST_TUNER_CHANNEL_FREQUENCY), 0); + g_return_val_if_fail (gst_v4l_tuner_contains_channel (v4lelement, + v4lchannel), 0); + + gst_v4l_get_chan_norm (v4lelement, &chan, NULL); + if (chan == GST_V4L_TUNER_CHANNEL (channel)->index && + GST_TUNER_CHANNEL_HAS_FLAG (channel, GST_TUNER_CHANNEL_FREQUENCY)) { + gst_v4l_get_signal (v4lelement, v4lchannel->tuner, &signal); + } + + return signal; +} diff --git a/sys/v4l/gstv4ltuner.h b/sys/v4l/gstv4ltuner.h new file mode 100644 index 0000000000..2777a2e460 --- /dev/null +++ b/sys/v4l/gstv4ltuner.h @@ -0,0 +1,83 @@ +/* G-Streamer generic V4L element - Tuner interface implementation + * Copyright (C) 2003 Ronald Bultje + * + * gstv4ltuner.h: tuner interface implementation for V4L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_V4L_TUNER_H__ +#define __GST_V4L_TUNER_H__ + +#include +#include + +G_BEGIN_DECLS + +#define GST_TYPE_V4L_TUNER_CHANNEL \ + (gst_v4l_tuner_channel_get_type ()) +#define GST_V4L_TUNER_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L_TUNER_CHANNEL, \ + GstV4lTunerChannel)) +#define GST_V4L_TUNER_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L_TUNER_CHANNEL, \ + GstV4lTunerChannelClass)) +#define GST_IS_V4L_TUNER_CHANNEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L_TUNER_CHANNEL)) +#define GST_IS_V4L_TUNER_CHANNEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L_TUNER_CHANNEL)) + +typedef struct _GstV4lTunerChannel { + GstTunerChannel parent; + + gint index; + gint tuner; + gint audio; +} GstV4lTunerChannel; + +typedef struct _GstV4lTunerChannelClass { + GstTunerChannelClass parent; +} GstV4lTunerChannelClass; + +#define GST_TYPE_V4L_TUNER_NORM \ + (gst_v4l_tuner_norm_get_type ()) +#define GST_V4L_TUNER_NORM(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_V4L_TUNER_NORM, \ + GstV4lTunerNorm)) +#define GST_V4L_TUNER_NORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_V4L_TUNER_NORM, \ + GstV4lTunerNormClass)) +#define GST_IS_V4L_TUNER_NORM(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_V4L_TUNER_NORM)) +#define GST_IS_V4L_TUNER_NORM_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_V4L_TUNER_NORM)) + +typedef struct _GstV4lTunerNorm { + GstTunerNorm parent; + + gint index; +} GstV4lTunerNorm; + +typedef struct _GstV4lTunerNormClass { + GstTunerNormClass parent; +} GstV4lTunerNormClass; + +GType gst_v4l_tuner_channel_get_type (void); +GType gst_v4l_tuner_norm_get_type (void); + +void gst_v4l_tuner_interface_init (GstTunerClass *klass); + +#endif /* __GST_V4L_TUNER_H__ */ diff --git a/sys/v4l/gstv4lxoverlay.c b/sys/v4l/gstv4lxoverlay.c new file mode 100644 index 0000000000..e8f69a81ea --- /dev/null +++ b/sys/v4l/gstv4lxoverlay.c @@ -0,0 +1,126 @@ +/* GStreamer X-based overlay interface implementation + * Copyright (C) 2003 Ronald Bultje + * + * gstv4lxoverlay.c: X-based overlay interface implementation for V4L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "gstv4lxoverlay.h" +#include "gstv4lelement.h" +#include "v4l_calls.h" + +static void gst_v4l_xoverlay_set_xwindow_id (GstXOverlay *overlay, + XID xwindow_id); + +void +gst_v4l_xoverlay_interface_init (GstXOverlayClass *klass) +{ + /* default virtual functions */ + klass->set_xwindow_id = gst_v4l_xoverlay_set_xwindow_id; +} + +GstXWindowListener * +gst_v4l_xoverlay_new (GstV4lElement *v4lelement) +{ + GstXWindowListener *xwin = + gst_x_window_listener_new (NULL, + (MapWindowFunc) gst_v4l_enable_overlay, + (SetWindowFunc) gst_v4l_set_window, + (gpointer) v4lelement); + + v4lelement->overlay = xwin; + v4lelement->xwindow_id = 0; + + return xwin; +} + +void +gst_v4l_xoverlay_free (GstV4lElement *v4lelement) +{ + gst_v4l_xoverlay_close (v4lelement); + g_object_unref (G_OBJECT (v4lelement->overlay)); + v4lelement->overlay = NULL; +} + +void +gst_v4l_xoverlay_open (GstV4lElement *v4lelement) +{ + GstXWindowListener *xwin = v4lelement->overlay; + + if (xwin != NULL) { + xwin->display_name = g_strdup (v4lelement->display); + + if (v4lelement->xwindow_id != 0 && + xwin->display_name && + xwin->display_name[0] == ':') { + gst_x_window_listener_set_xid (xwin, v4lelement->xwindow_id); + } + } +} + +void +gst_v4l_xoverlay_close (GstV4lElement *v4lelement) +{ + GstXWindowListener *xwin = v4lelement->overlay; + + if (xwin != NULL) { + if (v4lelement->xwindow_id != 0 && + xwin->display_name && + xwin->display_name[0] == ':') { + gst_x_window_listener_set_xid (xwin, 0); + } + + g_free (xwin->display_name); + xwin->display_name = NULL; + } +} + +static void +gst_v4l_xoverlay_set_xwindow_id (GstXOverlay *overlay, + XID xwindow_id) +{ + GstV4lElement *v4lelement = GST_V4LELEMENT (overlay); + GstXWindowListener *xwin = v4lelement->overlay; + + if (v4lelement->xwindow_id == xwindow_id) { + return; + } + + if (gst_element_get_state (GST_ELEMENT (v4lelement)) != GST_STATE_NULL && + v4lelement->xwindow_id != 0 && + xwin && xwin->display_name && + xwin->display_name[0] == ':') { + gst_x_window_listener_set_xid (xwin, 0); + } + + v4lelement->xwindow_id = xwindow_id; + + if (gst_element_get_state (GST_ELEMENT (v4lelement)) != GST_STATE_NULL && + v4lelement->xwindow_id != 0 && + xwin && xwin->display_name && + xwin->display_name[0] == ':') { + gst_x_window_listener_set_xid (xwin, v4lelement->xwindow_id); + } +} diff --git a/sys/v4l/gstv4lxoverlay.h b/sys/v4l/gstv4lxoverlay.h new file mode 100644 index 0000000000..5c390ff729 --- /dev/null +++ b/sys/v4l/gstv4lxoverlay.h @@ -0,0 +1,42 @@ +/* G-Streamer generic V4L element - X overlay interface implementation + * Copyright (C) 2003 Ronald Bultje + * + * gstv4lxoverlay.h: tv mixer interface implementation for V4L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_V4L_X_OVERLAY_H__ +#define __GST_V4L_X_OVERLAY_H__ + +#include +#include + +#include "gstv4lelement.h" + +G_BEGIN_DECLS + +void gst_v4l_xoverlay_interface_init (GstXOverlayClass *klass); + +GstXWindowListener * + gst_v4l_xoverlay_new (GstV4lElement *v4lelement); +void gst_v4l_xoverlay_free (GstV4lElement *v4lelement); + +/* signal handlers */ +void gst_v4l_xoverlay_open (GstV4lElement *v4lelement); +void gst_v4l_xoverlay_close (GstV4lElement *v4lelement); + +#endif /* __GST_V4L_X_OVERLAY_H__ */ diff --git a/sys/v4l/v4l-overlay_calls.c b/sys/v4l/v4l-overlay_calls.c index 902487c54d..044c07f611 100644 --- a/sys/v4l/v4l-overlay_calls.c +++ b/sys/v4l/v4l-overlay_calls.c @@ -44,30 +44,34 @@ ******************************************************/ gboolean -gst_v4l_set_overlay (GstV4lElement *v4lelement, - gchar *display) +gst_v4l_set_overlay (GstV4lElement *v4lelement) { gchar *buff; - DEBUG("setting display to '%s'", display); + if (v4lelement->display) + g_free(v4lelement->display); + v4lelement->display = g_strdup(g_getenv("DISPLAY")); + + DEBUG("setting display to '%s'", v4lelement->display); GST_V4L_CHECK_NOT_OPEN(v4lelement); + if (!v4lelement->display || v4lelement->display[0] != ':') + return FALSE; + /* start v4l-conf */ buff = g_strdup_printf("v4l-conf -q -c %s -d %s", - v4lelement->videodev?v4lelement->videodev:"/dev/video", display); + v4lelement->videodev, v4lelement->display); switch (system(buff)) { case -1: - gst_element_error(GST_ELEMENT(v4lelement), - "Could not start v4l-conf: %s", g_strerror(errno)); + g_warning("Could not start v4l-conf: %s", g_strerror(errno)); g_free(buff); return FALSE; case 0: break; default: - gst_element_error(GST_ELEMENT(v4lelement), - "v4l-conf failed to run correctly: %s", g_strerror(errno)); + g_warning("v4l-conf failed to run correctly: %s", g_strerror(errno)); g_free(buff); return FALSE; } diff --git a/sys/v4l/v4l_calls.c b/sys/v4l/v4l_calls.c index 1c2317504b..42bfdb3760 100644 --- a/sys/v4l/v4l_calls.c +++ b/sys/v4l/v4l_calls.c @@ -30,7 +30,13 @@ #include #include +#include +#include +#include + #include "v4l_calls.h" +#include "gstv4ltuner.h" +#include "gstv4lcolorbalance.h" #define DEBUG(format, args...) \ GST_DEBUG_OBJECT (\ @@ -38,7 +44,7 @@ "V4L: " format, ##args) -const char *picture_name[] = { +static const char *picture_name[] = { "Hue", "Brightness", "Contrast", @@ -46,14 +52,14 @@ const char *picture_name[] = { NULL }; -const char *audio_name[] = { +static const char *audio_name[] = { "Volume", "Mute", "Mode", NULL }; -const char *norm_name[] = { +static const char *norm_name[] = { "PAL", "NTSC", "SECAM", @@ -94,15 +100,17 @@ gboolean gst_v4l_open (GstV4lElement *v4lelement) { int num; - GParamSpec *spec; DEBUG("opening device %s", v4lelement->videodev); GST_V4L_CHECK_NOT_OPEN(v4lelement); GST_V4L_CHECK_NOT_ACTIVE(v4lelement); /* be sure we have a device */ - if (!v4lelement->videodev) - v4lelement->videodev = g_strdup("/dev/video"); + if (!v4lelement->videodev) { + gst_element_error (GST_ELEMENT (v4lelement), + "No device given - open failed"); + return FALSE; + } /* open the device */ v4lelement->video_fd = open(v4lelement->videodev, O_RDWR); @@ -125,22 +133,34 @@ gst_v4l_open (GstV4lElement *v4lelement) gst_info("Opened device \'%s\' (\'%s\') successfully\n", 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); + /* norms + inputs, for the tuner interface */ + for (num=0;norm_name[num]!=NULL;num++) { + GstV4lTunerNorm *v4lnorm = g_object_new (GST_TYPE_V4L_TUNER_NORM, + NULL); + GstTunerNorm *norm = GST_TUNER_NORM (v4lnorm); + + norm->label = g_strdup (norm_name[num]); + norm->fps = (num == 1) ? (30000./1001) : 25.; + v4lnorm->index = num; + v4lelement->norms = g_list_append(v4lelement->norms, + (gpointer) norm); + } + v4lelement->channels = 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); + GstV4lColorBalanceChannel *v4lchannel = + g_object_new (GST_TYPE_V4L_COLOR_BALANCE_CHANNEL, NULL); + GstColorBalanceChannel *channel = GST_COLOR_BALANCE_CHANNEL (v4lchannel); + channel->label = g_strdup (picture_name[num]); + channel->min_value = 0; + channel->max_value = 65535; + v4lchannel->index = num; + v4lelement->colors = g_list_append(v4lelement->colors, channel); } - 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); + + DEBUG("Setting default norm/input"); + gst_v4l_set_chan_norm (v4lelement, 0, 0); return TRUE; } @@ -162,20 +182,17 @@ gst_v4l_close (GstV4lElement *v4lelement) close(v4lelement->video_fd); 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)); - } + g_list_foreach (v4lelement->channels, (GFunc) g_object_unref, NULL); + g_list_free (v4lelement->channels); + v4lelement->channels = NULL; + + g_list_foreach (v4lelement->norms, (GFunc) g_object_unref, NULL); + g_list_free (v4lelement->norms); + v4lelement->norms = NULL; + + g_list_foreach (v4lelement->colors, (GFunc) g_object_unref, NULL); + g_list_free (v4lelement->colors); + v4lelement->colors = NULL; return TRUE; } @@ -205,6 +222,7 @@ GList * gst_v4l_get_chan_names (GstV4lElement *v4lelement) { struct video_channel vchan; + const GList *pads = gst_element_get_pad_list (GST_ELEMENT (v4lelement)); GList *list = NULL; gint i; @@ -213,12 +231,58 @@ gst_v4l_get_chan_names (GstV4lElement *v4lelement) if (!GST_V4L_IS_OPEN(v4lelement)) return NULL; + /* sinks don't have inputs in v4l */ + if (pads && g_list_length ((GList *) pads) == 1) + if (GST_PAD_DIRECTION (GST_PAD (pads->data)) == GST_PAD_SINK) + return NULL; + for (i=0;ivideo_fd, VIDIOCGCHAN, &vchan) < 0) - return NULL; - list = g_list_append(list, (gpointer)g_strdup(vchan.name)); + return NULL; /* memleak... */ + channel->label = g_strdup (vchan.name); + channel->flags = GST_TUNER_CHANNEL_INPUT; + v4lchannel->index = i; + if (vchan.flags & VIDEO_VC_TUNER) { + struct video_tuner vtun; + gint n; + + for (n = 0; ; n++) { + vtun.tuner = n; + if (ioctl(v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0) + break; /* no more tuners */ + if (!strcmp(vtun.name, vchan.name)) { + v4lchannel->tuner = n; + channel->flags |= GST_TUNER_CHANNEL_FREQUENCY; + channel->min_frequency = vtun.rangelow; + channel->max_frequency = vtun.rangehigh; + channel->min_signal = 0; + channel->max_signal = 0xffff; + break; + } + } + } + if (vchan.flags & VIDEO_VC_AUDIO) { + struct video_audio vaud; + gint n; + + for (n = 0; n < v4lelement->vcap.audios; n++) { + vaud.audio = n; + if (ioctl(v4lelement->video_fd, VIDIOCGAUDIO, &vaud) < 0) + continue; + if (!strcmp(vaud.name, vchan.name)) { + v4lchannel->audio = n; + channel->flags |= GST_TUNER_CHANNEL_AUDIO; + break; + } + } + } + list = g_list_append(list, (gpointer) channel); } return list; @@ -289,21 +353,6 @@ gst_v4l_set_chan_norm (GstV4lElement *v4lelement, } -/****************************************************** - * gst_v4l_has_tuner(): - * return value: TRUE if it has a tuner, else FALSE - ******************************************************/ - -gboolean -gst_v4l_has_tuner (GstV4lElement *v4lelement) -{ - DEBUG("checking whether device has a tuner"); - GST_V4L_CHECK_OPEN(v4lelement); - - return v4lelement->vcap.type & VID_TYPE_TUNER; -} - - /****************************************************** * gst_v4l_get_signal(): * get the current signal @@ -312,17 +361,15 @@ gst_v4l_has_tuner (GstV4lElement *v4lelement) gboolean gst_v4l_get_signal (GstV4lElement *v4lelement, - guint *signal) + gint tunernum, + guint *signal) { - struct video_tuner tuner; + struct video_tuner tuner; DEBUG("getting tuner signal"); GST_V4L_CHECK_OPEN(v4lelement); - if (!gst_v4l_has_tuner(v4lelement)) - return FALSE; - - tuner.tuner = 0; + tuner.tuner = tunernum; if (ioctl(v4lelement->video_fd, VIDIOCGTUNER, &tuner) < 0) { gst_element_error(GST_ELEMENT(v4lelement), @@ -345,12 +392,19 @@ gst_v4l_get_signal (GstV4lElement *v4lelement, gboolean gst_v4l_get_frequency (GstV4lElement *v4lelement, + gint tunernum, gulong *frequency) { + struct video_tuner vtun; + DEBUG("getting tuner frequency"); GST_V4L_CHECK_OPEN(v4lelement); - if (!gst_v4l_has_tuner(v4lelement)) + /* check that this is the current input */ + vtun.tuner = tunernum; + if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0) + return FALSE; + if (strcmp(vtun.name, v4lelement->vchan.name)) return FALSE; if (ioctl(v4lelement->video_fd, VIDIOCGFREQ, frequency) < 0) @@ -373,12 +427,19 @@ gst_v4l_get_frequency (GstV4lElement *v4lelement, gboolean gst_v4l_set_frequency (GstV4lElement *v4lelement, - gulong frequency) + gint tunernum, + gulong frequency) { + struct video_tuner vtun; + DEBUG("setting tuner frequency to %lu", frequency); GST_V4L_CHECK_OPEN(v4lelement); - - if (!gst_v4l_has_tuner(v4lelement)) + + /* check that this is the current input */ + vtun.tuner = tunernum; + if (ioctl (v4lelement->video_fd, VIDIOCGTUNER, &vtun) < 0) + return FALSE; + if (strcmp(vtun.name, v4lelement->vchan.name)) return FALSE; if (ioctl(v4lelement->video_fd, VIDIOCSFREQ, &frequency) < 0) @@ -501,21 +562,6 @@ gst_v4l_set_picture (GstV4lElement *v4lelement, } -/****************************************************** - * gst_v4l_has_audio(): - * return value: TRUE if it can do audio, else FALSE - ******************************************************/ - -gboolean -gst_v4l_has_audio (GstV4lElement *v4lelement) -{ - DEBUG("checking whether device has audio"); - GST_V4L_CHECK_OPEN(v4lelement); - - return v4lelement->vcap.audios > 0; -} - - /****************************************************** * gst_v4l_get_audio(): * get some audio value @@ -524,6 +570,7 @@ gst_v4l_has_audio (GstV4lElement *v4lelement) gboolean gst_v4l_get_audio (GstV4lElement *v4lelement, + gint audionum, GstV4lAudioType type, gint *value) { @@ -533,9 +580,7 @@ gst_v4l_get_audio (GstV4lElement *v4lelement, type, audio_name[type]); GST_V4L_CHECK_OPEN(v4lelement); - if (!gst_v4l_has_audio(v4lelement)) - return FALSE; - + vau.audio = audionum; if (ioctl(v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0) { gst_element_error(GST_ELEMENT(v4lelement), @@ -574,6 +619,7 @@ gst_v4l_get_audio (GstV4lElement *v4lelement, gboolean gst_v4l_set_audio (GstV4lElement *v4lelement, + gint audionum, GstV4lAudioType type, gint value) { @@ -583,9 +629,7 @@ gst_v4l_set_audio (GstV4lElement *v4lelement, type, audio_name[type], value); GST_V4L_CHECK_OPEN(v4lelement); - if (!gst_v4l_has_audio(v4lelement)) - return FALSE; - + vau.audio = audionum; if (ioctl(v4lelement->video_fd, VIDIOCGAUDIO, &vau) < 0) { gst_element_error(GST_ELEMENT(v4lelement), diff --git a/sys/v4l/v4l_calls.h b/sys/v4l/v4l_calls.h index 3214e8a477..df12f29e85 100644 --- a/sys/v4l/v4l_calls.h +++ b/sys/v4l/v4l_calls.h @@ -91,50 +91,64 @@ typedef enum { V4L_PICTURE_SATURATION, } GstV4lPictureType; -extern const char *picture_name[]; - typedef enum { V4L_AUDIO_VOLUME = 0, V4L_AUDIO_MUTE, V4L_AUDIO_MODE, /* stereo, mono, ... (see videodev.h) */ } GstV4lAudioType; -extern const char *audio_name[]; - -extern const char *norm_name[]; - /* open/close the device */ gboolean gst_v4l_open (GstV4lElement *v4lelement); gboolean gst_v4l_close (GstV4lElement *v4lelement); /* norm control (norm = VIDEO_MODE_{PAL|NTSC|SECAM|AUTO}) */ -gint gst_v4l_get_num_chans (GstV4lElement *v4lelement); -gboolean gst_v4l_get_chan_norm (GstV4lElement *v4lelement, gint *channel, gint *norm); -gboolean gst_v4l_set_chan_norm (GstV4lElement *v4lelement, gint channel, gint norm); +gboolean gst_v4l_get_chan_norm (GstV4lElement *v4lelement, + gint *channel, + gint *norm); +gboolean gst_v4l_set_chan_norm (GstV4lElement *v4lelement, + gint channel, + gint norm); GList *gst_v4l_get_chan_names (GstV4lElement *v4lelement); /* frequency control */ -gboolean gst_v4l_has_tuner (GstV4lElement *v4lelement); -gboolean gst_v4l_get_signal (GstV4lElement *v4lelement, guint *signal); -gboolean gst_v4l_get_frequency (GstV4lElement *v4lelement, gulong *frequency); -gboolean gst_v4l_set_frequency (GstV4lElement *v4lelement, gulong frequency); +gboolean gst_v4l_get_signal (GstV4lElement *v4lelement, + gint tunernum, + guint *signal); +gboolean gst_v4l_get_frequency (GstV4lElement *v4lelement, + gint tunernum, + gulong *frequency); +gboolean gst_v4l_set_frequency (GstV4lElement *v4lelement, + gint tunernum, + gulong frequency); /* picture control */ -gboolean gst_v4l_get_picture (GstV4lElement *v4lelement, GstV4lPictureType type, gint *value); -gboolean gst_v4l_set_picture (GstV4lElement *v4lelement, GstV4lPictureType type, gint value); +gboolean gst_v4l_get_picture (GstV4lElement *v4lelement, + GstV4lPictureType type, + gint *value); +gboolean gst_v4l_set_picture (GstV4lElement *v4lelement, + GstV4lPictureType type, + gint value); /* audio control */ -gboolean gst_v4l_has_audio (GstV4lElement *v4lelement); -gboolean gst_v4l_get_audio (GstV4lElement *v4lelement, GstV4lAudioType type, gint *value); -gboolean gst_v4l_set_audio (GstV4lElement *v4lelement, GstV4lAudioType type, gint value); +gboolean gst_v4l_get_audio (GstV4lElement *v4lelement, + gint audionum, + GstV4lAudioType type, + gint *value); +gboolean gst_v4l_set_audio (GstV4lElement *v4lelement, + gint audionum, + GstV4lAudioType type, + gint value); /* overlay */ -gboolean gst_v4l_set_overlay (GstV4lElement *v4lelement, gchar *display); -gboolean gst_v4l_set_window (GstElement *element, gint x, gint y, - gint w, gint h, - struct video_clip *clips, gint num_clips); -gboolean gst_v4l_enable_overlay (GstV4lElement *v4lelement, gboolean enable); +gboolean gst_v4l_set_overlay (GstV4lElement *v4lelement); +gboolean gst_v4l_set_window (GstElement *element, + gint x, gint y, + gint w, gint h, + struct video_clip *clips, + gint num_clips); +gboolean gst_v4l_enable_overlay (GstV4lElement *v4lelement, + gboolean enable); #ifdef __cplusplus diff --git a/sys/v4l/v4lmjpegsrc_calls.c b/sys/v4l/v4lmjpegsrc_calls.c index 4e1e3e5b64..1db5a7c23c 100644 --- a/sys/v4l/v4lmjpegsrc_calls.c +++ b/sys/v4l/v4lmjpegsrc_calls.c @@ -42,9 +42,6 @@ GST_ELEMENT(v4lmjpegsrc), \ "V4LMJPEGSRC: " format, ##args) - -char *input_name[] = { "Composite", "S-Video", "TV-Tuner", "Autodetect" }; - enum { QUEUE_STATE_ERROR = -1, QUEUE_STATE_READY_FOR_QUEUE, @@ -119,99 +116,6 @@ gst_v4lmjpegsrc_sync_next_frame (GstV4lMjpegSrc *v4lmjpegsrc, } -/****************************************************** - * gst_v4lmjpegsrc_set_input_norm(): - * set input/norm (includes autodetection), norm is - * VIDEO_MODE_{PAL|NTSC|SECAM|AUTO} - * return value: TRUE on success, FALSE on error - ******************************************************/ - -gboolean -gst_v4lmjpegsrc_set_input_norm (GstV4lMjpegSrc *v4lmjpegsrc, - GstV4lMjpegInputType input, - gint norm) -{ - struct mjpeg_status bstat; - - DEBUG("setting input = %d (%s), norm = %d (%s)", - input, input_name[input], norm, norm_name[norm]); - - GST_V4L_CHECK_OPEN(GST_V4LELEMENT(v4lmjpegsrc)); - GST_V4L_CHECK_NOT_ACTIVE(GST_V4LELEMENT(v4lmjpegsrc)); - - if (input == V4L_MJPEG_INPUT_AUTO) - { - int n; - - for (n=V4L_MJPEG_INPUT_COMPOSITE;nvideo_fd, MJPIOC_G_STATUS, &bstat) < 0) - { - gst_element_error(GST_ELEMENT(v4lmjpegsrc), - "Error getting device status: %s", - g_strerror(errno)); - return FALSE; - } - - if (bstat.signal) - { - input = bstat.input; - if (norm == VIDEO_MODE_AUTO) - norm = bstat.norm; - gst_info("Signal found: on input %s, norm %s\n", - input_name[bstat.input], norm_name[bstat.norm]); - break; - } - } - - /* check */ - if (input == V4L_MJPEG_INPUT_AUTO || norm == VIDEO_MODE_AUTO) - { - gst_element_error(GST_ELEMENT(v4lmjpegsrc), - "Unable to auto-detect an input"); - return FALSE; - } - - /* save */ - GST_V4LELEMENT(v4lmjpegsrc)->channel = input; - GST_V4LELEMENT(v4lmjpegsrc)->norm = norm; - } - else if (norm == VIDEO_MODE_AUTO && input) - { - bstat.input = input; - - if (ioctl(GST_V4LELEMENT(v4lmjpegsrc)->video_fd, MJPIOC_G_STATUS, &bstat) < 0) - { - gst_element_error(GST_ELEMENT(v4lmjpegsrc), - "Error getting device status: %s", - g_strerror(errno)); - return FALSE; - } - - if (bstat.signal) - { - norm = bstat.norm; - gst_info("Norm %s detected on input %s\n", - norm_name[bstat.norm], input_name[input]); - GST_V4LELEMENT(v4lmjpegsrc)->norm = norm; - } - else - { - gst_element_error(GST_ELEMENT(v4lmjpegsrc), - "No signal found on input %s", - input_name[input]); - return FALSE; - } - } - - return gst_v4l_set_chan_norm(GST_V4LELEMENT(v4lmjpegsrc), input, norm); -} - - /****************************************************** * gst_v4lmjpegsrc_set_buffer(): * set buffer parameters (size/count) diff --git a/sys/v4l/v4lmjpegsrc_calls.h b/sys/v4l/v4lmjpegsrc_calls.h index 17b4097d28..6d4d2652a7 100644 --- a/sys/v4l/v4lmjpegsrc_calls.h +++ b/sys/v4l/v4lmjpegsrc_calls.h @@ -28,21 +28,6 @@ extern "C" { #endif /* __cplusplus */ -typedef enum { - V4L_MJPEG_INPUT_COMPOSITE = 0, - V4L_MJPEG_INPUT_SVIDEO = 1, - V4L_MJPEG_INPUT_TVTUNER = 2, - V4L_MJPEG_INPUT_AUTO = 3, -} GstV4lMjpegInputType; - -extern char *input_name[]; - - -/* set input/norm (includes autodetection, norm = VIDEO_MODE_{PAL|NTSC|SECAM|AUTO}) */ -gboolean gst_v4lmjpegsrc_set_input_norm (GstV4lMjpegSrc *v4lmjpegsrc, - GstV4lMjpegInputType input, - gint norm); - /* frame grabbing/capture */ gboolean gst_v4lmjpegsrc_set_buffer (GstV4lMjpegSrc *v4lmjpegsrc, gint numbufs,