summaryrefslogtreecommitdiffstats
path: root/gst/frei0r/gstfrei0rfilter.c
diff options
context:
space:
mode:
authorDave Robillard <dave@drobilla.net>2009-06-19 21:01:54 -0400
committerDave Robillard <dave@drobilla.net>2009-06-19 21:01:54 -0400
commit925e83ee60c5406b2e5f0f39b0da0f90370efc27 (patch)
treece01d298ed0c5d31853fa43aedc2af0779417816 /gst/frei0r/gstfrei0rfilter.c
parent7f3bcd484b465d8216ac419754450adf07e9b0d2 (diff)
parentc70dbe94b5ff9a0993d852605d40c21020c59552 (diff)
downloadgst-plugins-bad-925e83ee60c5406b2e5f0f39b0da0f90370efc27.tar.gz
gst-plugins-bad-925e83ee60c5406b2e5f0f39b0da0f90370efc27.tar.bz2
gst-plugins-bad-925e83ee60c5406b2e5f0f39b0da0f90370efc27.zip
Merge branch 'master' of git://anongit.freedesktop.org/gstreamer/gst-plugins-bad into fdo
Diffstat (limited to 'gst/frei0r/gstfrei0rfilter.c')
-rw-r--r--gst/frei0r/gstfrei0rfilter.c241
1 files changed, 241 insertions, 0 deletions
diff --git a/gst/frei0r/gstfrei0rfilter.c b/gst/frei0r/gstfrei0rfilter.c
new file mode 100644
index 00000000..43d8fc67
--- /dev/null
+++ b/gst/frei0r/gstfrei0rfilter.c
@@ -0,0 +1,241 @@
+/* GStreamer
+ * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
+ *
+ * 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 <string.h>
+
+#include "gstfrei0r.h"
+#include "gstfrei0rfilter.h"
+
+GST_DEBUG_CATEGORY_EXTERN (frei0r_debug);
+#define GST_CAT_DEFAULT frei0r_debug
+
+typedef struct
+{
+ f0r_plugin_info_t info;
+ GstFrei0rFuncTable ftable;
+} GstFrei0rFilterClassData;
+
+static gboolean
+gst_frei0r_filter_set_caps (GstBaseTransform * trans, GstCaps * incaps,
+ GstCaps * outcaps)
+{
+ GstFrei0rFilter *self = GST_FREI0R_FILTER (trans);
+ GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (trans);
+ GstVideoFormat fmt;
+ gint width, height;
+
+ if (!gst_video_format_parse_caps (incaps, &fmt, &width, &height))
+ return FALSE;
+
+ if (self->f0r_instance) {
+ klass->ftable->destruct (self->f0r_instance);
+ self->f0r_instance = NULL;
+ }
+
+ self->f0r_instance =
+ gst_frei0r_instance_construct (klass->ftable, klass->properties,
+ klass->n_properties, self->property_cache, width, height);
+
+ return TRUE;
+}
+
+static gboolean
+gst_frei0r_filter_stop (GstBaseTransform * trans)
+{
+ GstFrei0rFilter *self = GST_FREI0R_FILTER (trans);
+ GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (trans);
+
+ if (self->f0r_instance) {
+ klass->ftable->destruct (self->f0r_instance);
+ self->f0r_instance = NULL;
+ }
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_frei0r_filter_transform (GstBaseTransform * trans, GstBuffer * inbuf,
+ GstBuffer * outbuf)
+{
+ GstFrei0rFilter *self = GST_FREI0R_FILTER (trans);
+ GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (trans);
+ gdouble time;
+
+ if (!self->f0r_instance)
+ return GST_FLOW_NOT_NEGOTIATED;
+
+ time = ((gdouble) GST_BUFFER_TIMESTAMP (inbuf)) / GST_SECOND;
+
+ if (klass->ftable->update2)
+ klass->ftable->update2 (self->f0r_instance, time,
+ (const guint32 *) GST_BUFFER_DATA (inbuf), NULL, NULL,
+ (guint32 *) GST_BUFFER_DATA (outbuf));
+ else
+ klass->ftable->update (self->f0r_instance, time,
+ (const guint32 *) GST_BUFFER_DATA (inbuf),
+ (guint32 *) GST_BUFFER_DATA (outbuf));
+
+ return GST_FLOW_OK;
+}
+
+static void
+gst_frei0r_filter_finalize (GObject * object)
+{
+ GstFrei0rFilter *self = GST_FREI0R_FILTER (object);
+ GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (object);
+
+ if (self->f0r_instance) {
+ klass->ftable->destruct (self->f0r_instance);
+ self->f0r_instance = NULL;
+ }
+
+ if (self->property_cache)
+ gst_frei0r_property_cache_free (klass->properties, self->property_cache,
+ klass->n_properties);
+ self->property_cache = NULL;
+
+ G_OBJECT_CLASS (g_type_class_peek_parent (klass))->finalize (object);
+}
+
+static void
+gst_frei0r_filter_get_property (GObject * object, guint prop_id, GValue * value,
+ GParamSpec * pspec)
+{
+ GstFrei0rFilter *self = GST_FREI0R_FILTER (object);
+ GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (object);
+
+ if (!gst_frei0r_get_property (self->f0r_instance, klass->ftable,
+ klass->properties, klass->n_properties, self->property_cache, prop_id,
+ value))
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
+
+static void
+gst_frei0r_filter_set_property (GObject * object, guint prop_id,
+ const GValue * value, GParamSpec * pspec)
+{
+ GstFrei0rFilter *self = GST_FREI0R_FILTER (object);
+ GstFrei0rFilterClass *klass = GST_FREI0R_FILTER_GET_CLASS (object);
+
+ if (!gst_frei0r_set_property (self->f0r_instance, klass->ftable,
+ klass->properties, klass->n_properties, self->property_cache, prop_id,
+ value))
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
+
+static void
+gst_frei0r_filter_class_init (GstFrei0rFilterClass * klass,
+ GstFrei0rFilterClassData * class_data)
+{
+ GObjectClass *gobject_class = (GObjectClass *) klass;
+ GstElementClass *gstelement_class = (GstElementClass *) klass;
+ GstBaseTransformClass *gsttrans_class = (GstBaseTransformClass *) klass;
+ GstPadTemplate *templ;
+ GstCaps *caps;
+ gchar *author;
+
+ klass->ftable = &class_data->ftable;
+ klass->info = &class_data->info;
+
+ gobject_class->finalize = gst_frei0r_filter_finalize;
+ gobject_class->set_property = gst_frei0r_filter_set_property;
+ gobject_class->get_property = gst_frei0r_filter_get_property;
+
+ klass->n_properties = klass->info->num_params;
+ klass->properties = g_new0 (GstFrei0rProperty, klass->n_properties);
+
+ gst_frei0r_klass_install_properties (gobject_class, klass->ftable,
+ klass->properties, klass->n_properties);
+
+ author =
+ g_strdup_printf
+ ("Sebastian Dröge <sebastian.droege@collabora.co.uk>, %s",
+ class_data->info.author);
+ gst_element_class_set_details_simple (gstelement_class, class_data->info.name,
+ "Filter/Effect/Video", class_data->info.explanation, author);
+ g_free (author);
+
+ caps = gst_frei0r_caps_from_color_model (class_data->info.color_model);
+
+ templ =
+ gst_pad_template_new ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
+ gst_caps_ref (caps));
+ gst_element_class_add_pad_template (gstelement_class, templ);
+
+ templ = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, caps);
+ gst_element_class_add_pad_template (gstelement_class, templ);
+
+ gsttrans_class->set_caps = GST_DEBUG_FUNCPTR (gst_frei0r_filter_set_caps);
+ gsttrans_class->stop = GST_DEBUG_FUNCPTR (gst_frei0r_filter_stop);
+ gsttrans_class->transform = GST_DEBUG_FUNCPTR (gst_frei0r_filter_transform);
+}
+
+static void
+gst_frei0r_filter_init (GstFrei0rFilter * self, GstFrei0rFilterClass * klass)
+{
+ self->property_cache =
+ gst_frei0r_property_cache_init (klass->properties, klass->n_properties);
+}
+
+gboolean
+gst_frei0r_filter_register (GstPlugin * plugin, const f0r_plugin_info_t * info,
+ const GstFrei0rFuncTable * ftable)
+{
+ GTypeInfo typeinfo = {
+ sizeof (GstFrei0rFilterClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_frei0r_filter_class_init,
+ NULL,
+ NULL,
+ sizeof (GstFrei0rFilter),
+ 0,
+ (GInstanceInitFunc) gst_frei0r_filter_init
+ };
+ GType type;
+ gchar *type_name, *tmp;
+ GstFrei0rFilterClassData *class_data;
+ gboolean ret = FALSE;
+
+ tmp = g_strdup_printf ("frei0r-filter-%s", info->name);
+ type_name = g_ascii_strdown (tmp, -1);
+ g_free (tmp);
+ g_strcanon (type_name, G_CSET_A_2_Z G_CSET_a_2_z G_CSET_DIGITS "-+", '-');
+
+ if (g_type_from_name (type_name)) {
+ GST_WARNING ("Type '%s' already exists", type_name);
+ return FALSE;
+ }
+
+ class_data = g_new0 (GstFrei0rFilterClassData, 1);
+ memcpy (&class_data->info, info, sizeof (f0r_plugin_info_t));
+ memcpy (&class_data->ftable, ftable, sizeof (GstFrei0rFuncTable));
+ typeinfo.class_data = class_data;
+
+ type =
+ g_type_register_static (GST_TYPE_VIDEO_FILTER, type_name, &typeinfo, 0);
+ ret = gst_element_register (plugin, type_name, GST_RANK_NONE, type);
+
+ g_free (type_name);
+ return ret;
+}