make it easier to reorder states: begin in enum order
[sparrow.git] / gstsparrow.c
blobe2d963bac0dec1a7106af4b86dfacb91fb91f14f
1 /* GStreamer
2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
4 * Copyright (C) <2010> Douglas Bagnall <douglas@halo.gen.nz>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 /**
24 * SECTION:element-sparrow
26 * Performs sparrow correction on a video stream.
28 * <refsect2>
29 * <title>Example launch line</title>
30 * |[
31 * gst-launch videotestsrc ! ffmpegcolorspace ! sparrow ! ximagesink
32 * ]|
33 * </refsect2>
36 #include "sparrow.h"
37 #include "gstsparrow.h"
38 #include <gst/video/gstvideofilter.h>
39 #include <gst/video/video.h>
40 GST_DEBUG_CATEGORY (sparrow_debug);
42 #include <string.h>
43 #include <math.h>
45 /* static_functions */
46 static void gst_sparrow_base_init(gpointer g_class);
47 static void gst_sparrow_class_init(GstSparrowClass *g_class);
48 static void gst_sparrow_init(GstSparrow *sparrow, GstSparrowClass *g_class);
49 static void gst_sparrow_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
50 static void gst_sparrow_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
51 static gboolean gst_sparrow_set_caps(GstBaseTransform *base, GstCaps *incaps, GstCaps *outcaps);
52 static GstFlowReturn gst_sparrow_transform(GstBaseTransform *base, GstBuffer *inbuf, GstBuffer *outbuf);
53 static gboolean plugin_init(GstPlugin *plugin);
56 //#include <sparrow.c>
57 #include <sparrow.h>
60 /* the capabilities of the inputs and outputs.
62 * Use RGB, not YUV, because inverting video is trivial in RGB, not so in YUV
64 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
65 GST_PAD_SINK,
66 GST_PAD_ALWAYS,
67 GST_STATIC_CAPS (
68 GST_VIDEO_CAPS_xBGR "; " GST_VIDEO_CAPS_xRGB "; "
69 GST_VIDEO_CAPS_BGRx "; " GST_VIDEO_CAPS_RGBx)
72 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
73 GST_PAD_SRC,
74 GST_PAD_ALWAYS,
75 GST_STATIC_CAPS (
76 GST_VIDEO_CAPS_xBGR "; " GST_VIDEO_CAPS_xRGB "; "
77 GST_VIDEO_CAPS_BGRx "; " GST_VIDEO_CAPS_RGBx)
81 GST_BOILERPLATE (GstSparrow, gst_sparrow, GstVideoFilter, GST_TYPE_VIDEO_FILTER);
83 /* plugin_init - registers plugin (once)
84 XXX_base_init - for the gobject class (once)
85 XXX_class_init - for global state (once)
86 XXX_init - for each plugin instance
89 static void
90 gst_sparrow_base_init (gpointer g_class)
92 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
94 gst_element_class_set_details_simple (element_class, "Video sparrow correction",
95 "Filter/Effect/Video",
96 "Adds sparrows to a video stream",
97 "Douglas Bagnall <douglas@halo.gen.nz>");
99 gst_element_class_add_pad_template (element_class,
100 gst_static_pad_template_get (&sink_factory));
101 gst_element_class_add_pad_template (element_class,
102 gst_static_pad_template_get (&src_factory));
104 GST_INFO("gst base init\n");
108 /* Clean up */
109 static void
110 gst_sparrow_finalize (GObject * obj){
111 GST_DEBUG("in gst_sparrow_finalize!\n");
112 GstSparrow *sparrow = GST_SPARROW(obj);
113 sparrow_finalise(sparrow);
116 static void
117 gst_sparrow_class_init (GstSparrowClass * g_class)
119 GObjectClass *gobject_class;
120 GstBaseTransformClass *trans_class;
122 gobject_class = G_OBJECT_CLASS (g_class);
123 trans_class = GST_BASE_TRANSFORM_CLASS (g_class);
125 gobject_class->set_property = gst_sparrow_set_property;
126 gobject_class->get_property = gst_sparrow_get_property;
127 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_sparrow_finalize);
129 g_object_class_install_property (gobject_class, PROP_CALIBRATE,
130 g_param_spec_boolean ("calibrate", "Calibrate", "calibrate against projection [on]",
131 DEFAULT_PROP_CALIBRATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
133 g_object_class_install_property (gobject_class, PROP_DEBUG,
134 g_param_spec_boolean ("debug", "Debug", "save PPM files of internal state [off]",
135 DEFAULT_PROP_DEBUG,
136 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
138 g_object_class_install_property (gobject_class, PROP_TIMER,
139 g_param_spec_boolean ("timer", "Timer", "Time each transform [off]",
140 DEFAULT_PROP_TIMER,
141 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
143 g_object_class_install_property (gobject_class, PROP_RNG_SEED,
144 g_param_spec_uint ("rngseed", "RNGSeed", "Seed for the random number generator [-1, meaning auto]",
145 0, (guint32)-1, (guint32)DEFAULT_PROP_RNG_SEED,
146 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
148 trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_sparrow_set_caps);
149 trans_class->transform = GST_DEBUG_FUNCPTR (gst_sparrow_transform);
150 GST_INFO("gst class init\n");
153 static void
154 gst_sparrow_init (GstSparrow * sparrow, GstSparrowClass * g_class)
156 GST_INFO("gst sparrow init\n");
157 /*disallow resizing */
158 gst_pad_use_fixed_caps(GST_BASE_TRANSFORM_SRC_PAD(sparrow));
161 static void
162 gst_sparrow_set_property (GObject * object, guint prop_id, const GValue * value,
163 GParamSpec * pspec)
165 GstSparrow *sparrow;
167 g_return_if_fail (GST_IS_SPARROW (object));
168 sparrow = GST_SPARROW (object);
170 GST_DEBUG("gst_sparrow_set_property\n");
171 if (value){
172 switch (prop_id) {
173 case PROP_CALIBRATE:
174 sparrow->calibrate_flag = g_value_get_boolean(value);
175 GST_DEBUG("Calibrate argument is %d\n", sparrow->calibrate_flag);
176 break;
177 case PROP_DEBUG:
178 sparrow->debug = g_value_get_boolean(value);
179 GST_DEBUG("debug_value is %d\n", sparrow->debug);
180 break;
181 case PROP_TIMER:
182 sparrow->use_timer = g_value_get_boolean(value);
183 GST_DEBUG("timer_value is %d\n", sparrow->use_timer);
184 break;
185 case PROP_RNG_SEED:
186 sparrow->rng_seed = g_value_get_uint(value);
187 GST_DEBUG("rng seed is %d\n", sparrow->rng_seed);
188 break;
189 default:
190 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
191 break;
196 static void
197 gst_sparrow_get_property (GObject * object, guint prop_id, GValue * value,
198 GParamSpec * pspec)
200 GstSparrow *sparrow;
202 g_return_if_fail (GST_IS_SPARROW (object));
203 sparrow = GST_SPARROW (object);
205 switch (prop_id) {
206 case PROP_CALIBRATE:
207 g_value_set_boolean (value, sparrow->calibrate_flag);
208 break;
209 case PROP_DEBUG:
210 g_value_set_boolean(value, sparrow->debug);
211 break;
212 case PROP_TIMER:
213 g_value_set_boolean(value, sparrow->use_timer);
214 break;
215 case PROP_RNG_SEED:
216 g_value_set_uint(value, sparrow->rng_seed);
217 break;
218 default:
219 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220 break;
226 static gboolean
227 gst_sparrow_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps)
229 GST_INFO("set_caps\n");
230 GstSparrow *sparrow = GST_SPARROW(base);
232 GST_DEBUG_OBJECT (sparrow,
233 "set_caps: \nin %" GST_PTR_FORMAT " \nout %" GST_PTR_FORMAT, incaps, outcaps);
235 /* set_caps gets called after set_property, so it is a good place for hooks
236 that depend on properties and that need to be run before everything
237 starts. */
239 return sparrow_init(sparrow, incaps, outcaps);
244 static GstFlowReturn
245 gst_sparrow_transform (GstBaseTransform * base, GstBuffer * inbuf,
246 GstBuffer * outbuf)
248 GstSparrow *sparrow = GST_SPARROW(base);
249 guint8 *indata = GST_BUFFER_DATA(inbuf);
250 guint8 *outdata = GST_BUFFER_DATA(outbuf);
251 guint insize = GST_BUFFER_SIZE(inbuf);
252 guint outsize = GST_BUFFER_SIZE(outbuf);
254 if (insize != sparrow->in.size || outsize != sparrow->out.size)
255 goto wrong_size;
257 sparrow_rotate_history(sparrow, inbuf);
258 sparrow_transform(sparrow, indata, outdata);
259 return GST_FLOW_OK;
261 /* ERRORS */
262 wrong_size:
264 GST_ELEMENT_ERROR (sparrow, STREAM, FORMAT,
265 (NULL), ("Invalid buffer size(s)\nIN: size %d, expected %d\nOUT: size %d, expected %d",
266 insize, sparrow->in.size, outsize, sparrow->out.size));
267 return GST_FLOW_ERROR;
272 static gboolean
273 plugin_init (GstPlugin * plugin)
275 GST_DEBUG_CATEGORY_INIT (sparrow_debug, "sparrow", 0, "sparrow");
276 GST_INFO("gst plugin init\n");
278 return gst_element_register (plugin, "sparrow", GST_RANK_NONE, GST_TYPE_SPARROW);
281 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
282 GST_VERSION_MINOR,
283 "sparrow",
284 "Add sparrows to video streams",
285 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);