clamped difference projection
[sparrow.git] / gstsparrow.c
blob0d718105bf6db923ad38780e6cabd55a8d46d7cc
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_DEBUG,
130 g_param_spec_boolean ("debug", "Debug", "save PPM files of internal state [off]",
131 DEFAULT_PROP_DEBUG,
132 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
134 g_object_class_install_property (gobject_class, PROP_TIMER,
135 g_param_spec_boolean ("timer", "Timer", "Time each transform [off]",
136 DEFAULT_PROP_TIMER,
137 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
139 g_object_class_install_property (gobject_class, PROP_RNG_SEED,
140 g_param_spec_uint ("rngseed", "RNGSeed", "Seed for the random number generator [-1, meaning auto]",
141 0, (guint32)-1, (guint32)DEFAULT_PROP_RNG_SEED,
142 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
144 g_object_class_install_property (gobject_class, PROP_COLOUR,
145 g_param_spec_uint ("colour", "Colour", "Colour for calibration (" QUOTE(SPARROW_GREEN)
146 " for green, " QUOTE(SPARROW_MAGENTA) "for magenta) [" QUOTE(DEFAULT_PROP_COLOUR) "]",
147 0, SPARROW_LAST_COLOUR - 1, (guint32)DEFAULT_PROP_COLOUR,
148 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
150 g_object_class_install_property (gobject_class, PROP_RELOAD,
151 g_param_spec_string ("reload", "Reload", "reload calibration from this file, don't calibrate [None]",
152 DEFAULT_PROP_RELOAD, G_PARAM_READWRITE));
154 g_object_class_install_property (gobject_class, PROP_SAVE,
155 g_param_spec_string ("save", "Save", "save calibration details to this file [None]",
156 DEFAULT_PROP_SAVE, G_PARAM_READWRITE));
158 trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_sparrow_set_caps);
159 trans_class->transform = GST_DEBUG_FUNCPTR (gst_sparrow_transform);
160 GST_INFO("gst class init\n");
163 static void
164 gst_sparrow_init (GstSparrow * sparrow, GstSparrowClass * g_class)
166 GST_INFO("gst sparrow init\n");
167 /*disallow resizing */
168 gst_pad_use_fixed_caps(GST_BASE_TRANSFORM_SRC_PAD(sparrow));
171 static inline void
172 set_string_prop(const GValue *value, const char **target){
173 const char *s = g_value_dup_string(value);
174 size_t len = strlen(s);
175 if(len){
176 *target = s;
180 static void
181 gst_sparrow_set_property (GObject * object, guint prop_id, const GValue * value,
182 GParamSpec * pspec)
184 GstSparrow *sparrow;
186 g_return_if_fail (GST_IS_SPARROW (object));
187 sparrow = GST_SPARROW (object);
188 guint val;
189 GST_DEBUG("gst_sparrow_set_property\n");
190 if (value){
191 switch (prop_id) {
192 case PROP_DEBUG:
193 sparrow->debug = g_value_get_boolean(value);
194 GST_DEBUG("debug_value is %d\n", sparrow->debug);
195 break;
196 case PROP_TIMER:
197 sparrow->use_timer = g_value_get_boolean(value);
198 GST_DEBUG("timer_value is %d\n", sparrow->use_timer);
199 break;
200 case PROP_RNG_SEED:
201 sparrow->rng_seed = g_value_get_uint(value);
202 GST_DEBUG("rng seed is %d\n", sparrow->rng_seed);
203 break;
204 case PROP_COLOUR:
205 val = g_value_get_uint(value);
206 if (val < SPARROW_LAST_COLOUR){
207 sparrow->colour = val;
209 GST_DEBUG("colour is %d\n", sparrow->rng_seed);
210 break;
211 case PROP_RELOAD:
212 set_string_prop(value, &sparrow->reload);
213 GST_DEBUG("reload is %s\n", sparrow->reload);
214 break;
215 case PROP_SAVE:
216 set_string_prop(value, &sparrow->save);
217 GST_DEBUG("save is %s\n", sparrow->save);
218 break;
219 default:
220 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
221 break;
226 static void
227 gst_sparrow_get_property (GObject * object, guint prop_id, GValue * value,
228 GParamSpec * pspec)
230 GstSparrow *sparrow;
232 g_return_if_fail (GST_IS_SPARROW (object));
233 sparrow = GST_SPARROW (object);
235 switch (prop_id) {
236 case PROP_DEBUG:
237 g_value_set_boolean(value, sparrow->debug);
238 break;
239 case PROP_TIMER:
240 g_value_set_boolean(value, sparrow->use_timer);
241 break;
242 case PROP_RNG_SEED:
243 g_value_set_uint(value, sparrow->rng_seed);
244 break;
245 case PROP_COLOUR:
246 g_value_set_uint(value, sparrow->colour);
247 break;
248 case PROP_RELOAD:
249 g_value_set_string(value, sparrow->reload);
250 break;
251 case PROP_SAVE:
252 g_value_set_string(value, sparrow->save);
253 break;
254 default:
255 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
256 break;
262 static gboolean
263 gst_sparrow_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps)
265 GST_INFO("set_caps\n");
266 GstSparrow *sparrow = GST_SPARROW(base);
268 GST_DEBUG_OBJECT (sparrow,
269 "set_caps: \nin %" GST_PTR_FORMAT " \nout %" GST_PTR_FORMAT, incaps, outcaps);
271 /* set_caps gets called after set_property, so it is a good place for hooks
272 that depend on properties and that need to be run before everything
273 starts. */
275 return sparrow_init(sparrow, incaps, outcaps);
280 static GstFlowReturn
281 gst_sparrow_transform (GstBaseTransform * base, GstBuffer * inbuf,
282 GstBuffer * outbuf)
284 GstSparrow *sparrow = GST_SPARROW(base);
285 guint8 *indata = GST_BUFFER_DATA(inbuf);
286 guint8 *outdata = GST_BUFFER_DATA(outbuf);
287 guint insize = GST_BUFFER_SIZE(inbuf);
288 guint outsize = GST_BUFFER_SIZE(outbuf);
290 if (insize != sparrow->in.size || outsize != sparrow->out.size)
291 goto wrong_size;
293 sparrow_transform(sparrow, indata, outdata);
294 return GST_FLOW_OK;
296 /* ERRORS */
297 wrong_size:
299 GST_ELEMENT_ERROR (sparrow, STREAM, FORMAT,
300 (NULL), ("Invalid buffer size(s)\nIN: size %d, expected %d\nOUT: size %d, expected %d",
301 insize, sparrow->in.size, outsize, sparrow->out.size));
302 return GST_FLOW_ERROR;
307 static gboolean
308 plugin_init (GstPlugin * plugin)
310 GST_DEBUG_CATEGORY_INIT (sparrow_debug, "sparrow", 0, "sparrow");
311 GST_INFO("gst plugin init\n");
313 return gst_element_register (plugin, "sparrow", GST_RANK_NONE, GST_TYPE_SPARROW);
316 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
317 GST_VERSION_MINOR,
318 "sparrow",
319 "Add sparrows to video streams",
320 plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);