/* GStreamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ * Copyright (C) <2003> David Schleef <ds@schleef.org>
*
- * EffecTV:
+ * EffecTV - Realtime Digital Video Effector
* Copyright (C) 2001 FUKUCHI Kentarou
*
- * EffecTV is free software. * This library is free software;
- * you can redistribute it and/or
+ * 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.
*/
+/*
+ * This file was (probably) generated from gstvideotemplate.c,
+ * gstvideotemplate.c,v 1.11 2004/01/07 08:56:45 ds Exp
+ */
+
+/* From main.c of warp-1.1:
+ *
+ * Simple DirectMedia Layer demo
+ * Realtime picture 'gooing'
+ * by sam lantinga slouken@devolution.com
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gstvideofilter.h>
+
#include <string.h>
-#include "gsteffectv.h"
+#include <math.h>
+
+#include <gst/video/video.h>
#define GST_TYPE_AGINGTV \
(gst_agingtv_get_type())
#define GST_AGINGTV(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGINGTV,GstAgingTV))
#define GST_AGINGTV_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstAgingTV))
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGINGTV,GstAgingTVClass))
#define GST_IS_AGINGTV(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGINGTV))
#define GST_IS_AGINGTV_CLASS(obj) \
gint x;
gint dx;
gint init;
-} scratch;
-
-static int dx[8] = { 1, 1, 0, -1, -1, -1, 0, 1};
-static int dy[8] = { 0, -1, -1, -1, 0, 1, 1, 1};
+}
+scratch;
+static int dx[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
+static int dy[8] = { 0, -1, -1, -1, 0, 1, 1, 1 };
typedef struct _GstAgingTV GstAgingTV;
typedef struct _GstAgingTVClass GstAgingTVClass;
struct _GstAgingTV
{
- GstElement element;
-
- GstPad *sinkpad, *srcpad;
+ GstVideofilter videofilter;
gint width, height;
- gint video_size;
- gint area_scale;
gint aging_mode;
scratch scratches[SCRATCH_MAX];
gint dust_interval;
gint pits_interval;
-};
-
-struct _GstAgingTVClass
-{
- GstElementClass parent_class;
-};
-/* elementfactory information */
-GstElementDetails gst_agingtv_details = {
- "AgingTV",
- "Filter/Video/Effect",
- "LGPL",
- "Aply aging effect on video",
- VERSION,
- "Wim Taymans <wim.taymans@chello.be>",
- "(C) 2001 FUKUCHI Kentarou",
};
-
-/* Filter signals and args */
-enum
-{
- /* FILL ME */
- LAST_SIGNAL
-};
-
-enum
+struct _GstAgingTVClass
{
- ARG_0,
+ GstVideofilterClass parent_class;
};
-static void gst_agingtv_class_init (GstAgingTVClass * klass);
-static void gst_agingtv_init (GstAgingTV * filter);
+GType gst_agingtv_get_type (void);
-static void aging_mode_switch (GstAgingTV *filter);
+static GstElementDetails agingtv_details = GST_ELEMENT_DETAILS ("AgingTV",
+ "Filter/Effect/Video",
+ "AgingTV adds age to video input using scratches and dust",
+ "Sam Lantinga <slouken@devolution.com>");
-static void gst_agingtv_set_property (GObject * object, guint prop_id,
- const GValue * value, GParamSpec * pspec);
-static void gst_agingtv_get_property (GObject * object, guint prop_id,
- GValue * value, GParamSpec * pspec);
+static GstStaticPadTemplate gst_agingtv_src_template =
+GST_STATIC_PAD_TEMPLATE ("src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)
+ );
-static void gst_agingtv_chain (GstPad * pad, GstBuffer * buf);
+static GstStaticPadTemplate gst_agingtv_sink_template =
+GST_STATIC_PAD_TEMPLATE ("sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)
+ );
-static GstElementClass *parent_class = NULL;
-/*static guint gst_agingtv_signals[LAST_SIGNAL] = { 0 }; */
+static GstVideofilterClass *parent_class = NULL;
-GType gst_agingtv_get_type (void)
+static gboolean
+gst_agingtv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
+ GstCaps * outcaps)
{
- static GType agingtv_type = 0;
+ GstAgingTV *filter = GST_AGINGTV (btrans);
+ GstStructure *structure;
+ gboolean ret = FALSE;
- if (!agingtv_type) {
- static const GTypeInfo agingtv_info = {
- sizeof (GstAgingTVClass), NULL,
- NULL,
- (GClassInitFunc) gst_agingtv_class_init,
- NULL,
- NULL,
- sizeof (GstAgingTV),
- 0,
- (GInstanceInitFunc) gst_agingtv_init,
- };
+ structure = gst_caps_get_structure (incaps, 0);
- agingtv_type = g_type_register_static (GST_TYPE_ELEMENT, "GstAgingTV", &agingtv_info, 0);
+ if (gst_structure_get_int (structure, "width", &filter->width) &&
+ gst_structure_get_int (structure, "height", &filter->height)) {
+ ret = TRUE;
}
- return agingtv_type;
-}
-
-static void
-gst_agingtv_class_init (GstAgingTVClass * klass)
-{
- GObjectClass *gobject_class;
- GstElementClass *gstelement_class;
-
- gobject_class = (GObjectClass *) klass;
- gstelement_class = (GstElementClass *) klass;
-
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
- gobject_class->set_property = gst_agingtv_set_property;
- gobject_class->get_property = gst_agingtv_get_property;
+ return ret;
}
-static GstPadConnectReturn
-gst_agingtv_sinkconnect (GstPad * pad, GstCaps * caps)
+static gboolean
+gst_agingtv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
+ guint * size)
{
GstAgingTV *filter;
+ GstStructure *structure;
+ gboolean ret = FALSE;
+ gint width, height;
- filter = GST_AGINGTV (gst_pad_get_parent (pad));
-
- if (!GST_CAPS_IS_FIXED (caps))
- return GST_PAD_CONNECT_DELAYED;
-
- gst_caps_get_int (caps, "width", &filter->width);
- gst_caps_get_int (caps, "height", &filter->height);
-
- filter->video_size = filter->width * filter->height;
- filter->aging_mode = 0;
- aging_mode_switch (filter);
+ filter = GST_AGINGTV (btrans);
- return gst_pad_try_set_caps (filter->srcpad, caps);
-}
+ structure = gst_caps_get_structure (caps, 0);
-static void
-gst_agingtv_init (GstAgingTV * filter)
-{
- filter->sinkpad = gst_pad_new_from_template (gst_effectv_sink_factory (), "sink");
- gst_pad_set_chain_function (filter->sinkpad, gst_agingtv_chain);
- gst_pad_set_connect_function (filter->sinkpad, gst_agingtv_sinkconnect);
- gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
+ if (gst_structure_get_int (structure, "width", &width) &&
+ gst_structure_get_int (structure, "height", &height)) {
+ *size = width * height * 32 / 8;
+ ret = TRUE;
+ GST_DEBUG_OBJECT (filter, "our frame size is %d bytes (%dx%d)", *size,
+ width, height);
+ }
- filter->srcpad = gst_pad_new_from_template (gst_effectv_src_factory (), "src");
- gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
+ return ret;
}
-
-static unsigned int
+static unsigned int
fastrand (void)
{
static unsigned int fastrand_val;
}
-static void
-coloraging (guint32 *src, guint32 *dest, gint video_area)
+static void
+coloraging (guint32 * src, guint32 * dest, gint video_area)
{
guint32 a, b;
gint i;
}
-static void
-scratching (scratch *scratches, gint scratch_lines, guint32 *dest, gint width, gint height)
+static void
+scratching (scratch * scratches, gint scratch_lines, guint32 * dest, gint width,
+ gint height)
{
gint i, y, y1, y2;
guint32 *p, a, b;
if (scratch->life) {
scratch->x = scratch->x + scratch->dx;
-
+
if (scratch->x < 0 || scratch->x > width * 256) {
- scratch->life = 0;
- break;
+ scratch->life = 0;
+ break;
}
p = dest + (scratch->x >> 8);
if (scratch->init) {
- y1 = scratch->init;
- scratch->init = 0;
+ y1 = scratch->init;
+ scratch->init = 0;
} else {
- y1 = 0;
+ y1 = 0;
}
scratch->life--;
if (scratch->life) {
- y2 = height;
+ y2 = height;
} else {
- y2 = fastrand () % height;
+ y2 = fastrand () % height;
}
for (y = y1; y < y2; y++) {
- a = *p & 0xfefeff;
- a += 0x202020;
- b = a & 0x1010100;
- *p = a | (b - (b >> 8));
- p += width;
+ a = *p & 0xfefeff;
+ a += 0x202020;
+ b = a & 0x1010100;
+ *p = a | (b - (b >> 8));
+ p += width;
}
} else {
if ((fastrand () & 0xf0000000) == 0) {
- scratch->life = 2 + (fastrand () >> 27);
- scratch->x = fastrand () % (width * 256);
- scratch->dx = ((int) fastrand ()) >> 23;
- scratch->init = (fastrand () % (height - 1)) + 1;
+ scratch->life = 2 + (fastrand () >> 27);
+ scratch->x = fastrand () % (width * 256);
+ scratch->dx = ((int) fastrand ()) >> 23;
+ scratch->init = (fastrand () % (height - 1)) + 1;
}
}
}
}
-static void
-dusts (guint32 *dest, gint width, gint height, gint dust_interval, gint area_scale)
+static void
+dusts (guint32 * dest, gint width, gint height, gint dust_interval,
+ gint area_scale)
{
int i, j;
int dnum;
}
return;
}
- dnum = area_scale * 4 + (fastrand() >> 27);
-
+ dnum = area_scale * 4 + (fastrand () >> 27);
+
for (i = 0; i < dnum; i++) {
x = fastrand () % width;
y = fastrand () % height;
y += dy[d];
x += dx[d];
- if (y >= height || x >= width) break;
+ if (y >= height || x >= width)
+ break;
d = (d + fastrand () % 3 - 1) & 7;
}
dust_interval--;
}
-static void
-pits (guint32 *dest, gint width, gint height, gint area_scale, gint pits_interval)
+static void
+pits (guint32 * dest, gint width, gint height, gint area_scale,
+ gint pits_interval)
{
int i, j;
int pnum, size, pnumscale;
x = x + fastrand () % 3 - 1;
y = y + fastrand () % 3 - 1;
- if (y >= height || x >= width) break;
+ if (y >= height || x >= width)
+ break;
dest[y * width + x] = 0xc0c0c0;
}
}
}
-static void
-aging_mode_switch (GstAgingTV *filter)
+static GstFlowReturn
+gst_agingtv_transform (GstBaseTransform * trans, GstBuffer * in,
+ GstBuffer * out)
{
- switch (filter->aging_mode) {
- default:
- case 0:
- filter->scratch_lines = 7;
- /* Most of the parameters are tuned for 640x480 mode */
- /* area_scale is set to 10 when screen size is 640x480. */
- filter->area_scale = filter->width * filter->height / 64 / 480;
- }
- if (filter->area_scale <= 0)
- filter->area_scale = 1;
+ GstAgingTV *agingtv = GST_AGINGTV (trans);
+ gint width = agingtv->width;
+ gint height = agingtv->height;
+ int video_size = width * height;
+ guint32 *src = (guint32 *) GST_BUFFER_DATA (in);
+ guint32 *dest = (guint32 *) GST_BUFFER_DATA (out);
+ gint area_scale = width * height / 64 / 480;
+ GstFlowReturn ret = GST_FLOW_OK;
+
+ gst_buffer_stamp (out, in);
+
+ if (area_scale <= 0)
+ area_scale = 1;
+
+ coloraging (src, dest, video_size);
+ scratching (agingtv->scratches, agingtv->scratch_lines, dest, width, height);
+ pits (dest, width, height, area_scale, agingtv->pits_interval);
+ if (area_scale > 1)
+ dusts (dest, width, height, agingtv->dust_interval, area_scale);
+
+ return ret;
}
static void
-gst_agingtv_chain (GstPad * pad, GstBuffer * buf)
+gst_agingtv_base_init (gpointer g_class)
{
- GstAgingTV *filter;
- guint32 *src, *dest;
- GstBuffer *outbuf;
-
- filter = GST_AGINGTV (gst_pad_get_parent (pad));
+ GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
- src = (guint32 *) GST_BUFFER_DATA (buf);
+ gst_element_class_set_details (element_class, &agingtv_details);
- outbuf = gst_buffer_new ();
- GST_BUFFER_SIZE (outbuf) = (filter->video_size * sizeof (guint32));
- dest = (guint32 *) GST_BUFFER_DATA (outbuf) = g_malloc (GST_BUFFER_SIZE (outbuf));
- GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-
- coloraging (src, dest, filter->video_size);
- scratching (filter->scratches, filter->scratch_lines, dest, filter->width, filter->height);
- pits (dest, filter->width, filter->height, filter->area_scale, filter->pits_interval);
- if(filter->area_scale > 1)
- dusts (dest, filter->width, filter->height, filter->dust_interval, filter->area_scale);
-
- gst_buffer_unref (buf);
-
- gst_pad_push (filter->srcpad, outbuf);
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_agingtv_sink_template));
+ gst_element_class_add_pad_template (element_class,
+ gst_static_pad_template_get (&gst_agingtv_src_template));
}
static void
-gst_agingtv_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
+gst_agingtv_class_init (gpointer klass, gpointer class_data)
{
- GstAgingTV *filter;
+ GObjectClass *gobject_class;
+ GstElementClass *element_class;
+ GstBaseTransformClass *trans_class;
- /* it's not null if we got it, but it might not be ours */
- g_return_if_fail (GST_IS_AGINGTV (object));
+ gobject_class = (GObjectClass *) klass;
+ element_class = (GstElementClass *) klass;
+ trans_class = (GstBaseTransformClass *) klass;
- filter = GST_AGINGTV (object);
+ parent_class = g_type_class_peek_parent (klass);
- switch (prop_id) {
- default:
- break;
- }
+ trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_agingtv_set_caps);
+ trans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_agingtv_get_unit_size);
+ trans_class->transform = GST_DEBUG_FUNCPTR (gst_agingtv_transform);
}
static void
-gst_agingtv_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
+gst_agingtv_init (GTypeInstance * instance, gpointer g_class)
{
- GstAgingTV *filter;
+}
- /* it's not null if we got it, but it might not be ours */
- g_return_if_fail (GST_IS_AGINGTV (object));
+GType
+gst_agingtv_get_type (void)
+{
+ static GType agingtv_type = 0;
- filter = GST_AGINGTV (object);
+ if (!agingtv_type) {
+ static const GTypeInfo agingtv_info = {
+ sizeof (GstAgingTVClass),
+ gst_agingtv_base_init,
+ NULL,
+ gst_agingtv_class_init,
+ NULL,
+ NULL,
+ sizeof (GstAgingTV),
+ 0,
+ gst_agingtv_init,
+ };
- switch (prop_id) {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
+ agingtv_type = g_type_register_static (GST_TYPE_VIDEOFILTER,
+ "GstAgingTV", &agingtv_info, 0);
}
+ return agingtv_type;
}