Remove unused variables in _class_init
[platform/upstream/gstreamer.git] / gst / effectv / gstvertigo.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * EffecTV:
5  * Copyright (C) 2001 FUKUCHI Kentarou
6  *
7  * EffecTV is free software. This library is free software;
8  * you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <gst/video/gstvideofilter.h>
30
31 #include <math.h>
32 #include <string.h>
33
34 #include <gst/video/video.h>
35
36 #define GST_TYPE_VERTIGOTV \
37   (gst_vertigotv_get_type())
38 #define GST_VERTIGOTV(obj) \
39   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_VERTIGOTV,GstVertigoTV))
40 #define GST_VERTIGOTV_CLASS(klass) \
41   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_VERTIGOTV,GstVertigoTVClass))
42 #define GST_IS_VERTIGOTV(obj) \
43   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_VERTIGOTV))
44 #define GST_IS_VERTIGOTV_CLASS(klass) \
45   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_VERTIGOTV))
46
47 typedef struct _GstVertigoTV GstVertigoTV;
48 typedef struct _GstVertigoTVClass GstVertigoTVClass;
49
50 struct _GstVertigoTV
51 {
52   GstVideoFilter videofilter;
53
54   gint width, height;
55   guint32 *buffer;
56   guint32 *current_buffer, *alt_buffer;
57   gint dx, dy;
58   gint sx, sy;
59   gdouble phase;
60   gdouble phase_increment;
61   gdouble zoomrate;
62 };
63
64 struct _GstVertigoTVClass
65 {
66   GstVideoFilterClass parent_class;
67 };
68
69 GType gst_vertigotv_get_type (void);
70
71 /* Filter signals and args */
72 enum
73 {
74   ARG_0,
75   ARG_SPEED,
76   ARG_ZOOM_SPEED
77 };
78
79 static const GstElementDetails vertigotv_details =
80 GST_ELEMENT_DETAILS ("VertigoTV effect",
81     "Filter/Effect/Video",
82     "A loopback alpha blending effector with rotating and scaling",
83     "Wim Taymans <wim.taymans@chello.be>");
84
85 static GstStaticPadTemplate gst_vertigotv_src_template =
86 GST_STATIC_PAD_TEMPLATE ("src",
87     GST_PAD_SRC,
88     GST_PAD_ALWAYS,
89     GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)
90     );
91
92 static GstStaticPadTemplate gst_vertigotv_sink_template =
93 GST_STATIC_PAD_TEMPLATE ("sink",
94     GST_PAD_SINK,
95     GST_PAD_ALWAYS,
96     GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx)
97     );
98
99 static GstVideoFilterClass *parent_class = NULL;
100
101 static gboolean
102 gst_vertigotv_set_caps (GstBaseTransform * btrans, GstCaps * incaps,
103     GstCaps * outcaps)
104 {
105   GstVertigoTV *filter = GST_VERTIGOTV (btrans);
106   GstStructure *structure;
107   gboolean ret = FALSE;
108
109   structure = gst_caps_get_structure (incaps, 0);
110
111   if (gst_structure_get_int (structure, "width", &filter->width) &&
112       gst_structure_get_int (structure, "height", &filter->height)) {
113     gint area = filter->width * filter->height;
114
115     g_free (filter->buffer);
116     filter->buffer = (guint32 *) g_malloc (area * 2 * sizeof (guint32));
117
118     memset (filter->buffer, 0, area * 2 * sizeof (guint32));
119     filter->current_buffer = filter->buffer;
120     filter->alt_buffer = filter->buffer + area;
121     filter->phase = 0;
122
123     ret = TRUE;
124   }
125
126   return ret;
127 }
128
129 static gboolean
130 gst_vertigotv_get_unit_size (GstBaseTransform * btrans, GstCaps * caps,
131     guint * size)
132 {
133   GstVertigoTV *filter;
134   GstStructure *structure;
135   gboolean ret = FALSE;
136   gint width, height;
137
138   filter = GST_VERTIGOTV (btrans);
139
140   structure = gst_caps_get_structure (caps, 0);
141
142   if (gst_structure_get_int (structure, "width", &width) &&
143       gst_structure_get_int (structure, "height", &height)) {
144     *size = width * height * 32 / 8;
145     ret = TRUE;
146     GST_DEBUG_OBJECT (filter, "our frame size is %d bytes (%dx%d)", *size,
147         width, height);
148   }
149
150   return ret;
151 }
152
153 static void
154 gst_vertigotv_set_parms (GstVertigoTV * filter)
155 {
156   double vx, vy;
157   double t;
158   double x, y;
159   double dizz;
160
161   dizz = sin (filter->phase) * 10 + sin (filter->phase * 1.9 + 5) * 5;
162
163   x = filter->width / 2;
164   y = filter->height / 2;
165
166   t = (x * x + y * y) * filter->zoomrate;
167
168   if (filter->width > filter->height) {
169     if (dizz >= 0) {
170       if (dizz > x)
171         dizz = x;
172       vx = (x * (x - dizz) + y * y) / t;
173     } else {
174       if (dizz < -x)
175         dizz = -x;
176       vx = (x * (x + dizz) + y * y) / t;
177     }
178     vy = (dizz * y) / t;
179   } else {
180     if (dizz >= 0) {
181       if (dizz > y)
182         dizz = y;
183       vx = (x * x + y * (y - dizz)) / t;
184     } else {
185       if (dizz < -y)
186         dizz = -y;
187       vx = (x * x + y * (y + dizz)) / t;
188     }
189     vy = (dizz * x) / t;
190   }
191   filter->dx = vx * 65536;
192   filter->dy = vy * 65536;
193   filter->sx = (-vx * x + vy * y + x + cos (filter->phase * 5) * 2) * 65536;
194   filter->sy = (-vx * y - vy * x + y + sin (filter->phase * 6) * 2) * 65536;
195
196   filter->phase += filter->phase_increment;
197   if (filter->phase > 5700000)
198     filter->phase = 0;
199 }
200
201 static GstFlowReturn
202 gst_vertigotv_transform (GstBaseTransform * trans, GstBuffer * in,
203     GstBuffer * out)
204 {
205   GstVertigoTV *filter;
206   guint32 *src, *dest, *p;
207   guint32 v;
208   gint x, y, ox, oy, i, width, height, area;
209   GstFlowReturn ret = GST_FLOW_OK;
210
211   filter = GST_VERTIGOTV (trans);
212
213   gst_buffer_copy_metadata (out, in, GST_BUFFER_COPY_TIMESTAMPS);
214
215   src = (guint32 *) GST_BUFFER_DATA (in);
216   dest = (guint32 *) GST_BUFFER_DATA (out);
217
218   width = filter->width;
219   height = filter->height;
220   area = width * height;
221
222   gst_vertigotv_set_parms (filter);
223   p = filter->alt_buffer;
224
225   for (y = height; y > 0; y--) {
226     ox = filter->sx;
227     oy = filter->sy;
228
229     for (x = width; x > 0; x--) {
230       i = (oy >> 16) * width + (ox >> 16);
231       if (i < 0)
232         i = 0;
233       if (i >= area)
234         i = area;
235
236       v = filter->current_buffer[i] & 0xfcfcff;
237       v = (v * 3) + ((*src++) & 0xfcfcff);
238
239       *p++ = (v >> 2);
240       ox += filter->dx;
241       oy += filter->dy;
242     }
243     filter->sx -= filter->dy;
244     filter->sy += filter->dx;
245   }
246
247   memcpy (dest, filter->alt_buffer, area * sizeof (guint32));
248
249   p = filter->current_buffer;
250   filter->current_buffer = filter->alt_buffer;
251   filter->alt_buffer = p;
252
253   return ret;
254 }
255
256 static void
257 gst_vertigotv_set_property (GObject * object, guint prop_id,
258     const GValue * value, GParamSpec * pspec)
259 {
260   GstVertigoTV *filter;
261
262   g_return_if_fail (GST_IS_VERTIGOTV (object));
263
264   filter = GST_VERTIGOTV (object);
265
266   switch (prop_id) {
267     case ARG_SPEED:
268       filter->phase_increment = g_value_get_float (value);
269       break;
270     case ARG_ZOOM_SPEED:
271       filter->zoomrate = g_value_get_float (value);
272       break;
273     default:
274       break;
275   }
276 }
277
278 static void
279 gst_vertigotv_get_property (GObject * object, guint prop_id, GValue * value,
280     GParamSpec * pspec)
281 {
282   GstVertigoTV *filter;
283
284   g_return_if_fail (GST_IS_VERTIGOTV (object));
285
286   filter = GST_VERTIGOTV (object);
287
288   switch (prop_id) {
289     case ARG_SPEED:
290       g_value_set_float (value, filter->phase_increment);
291       break;
292     case ARG_ZOOM_SPEED:
293       g_value_set_float (value, filter->zoomrate);
294       break;
295     default:
296       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
297       break;
298   }
299 }
300
301 static void
302 gst_vertigotv_base_init (gpointer g_class)
303 {
304   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
305
306   gst_element_class_set_details (element_class, &vertigotv_details);
307
308   gst_element_class_add_pad_template (element_class,
309       gst_static_pad_template_get (&gst_vertigotv_sink_template));
310   gst_element_class_add_pad_template (element_class,
311       gst_static_pad_template_get (&gst_vertigotv_src_template));
312 }
313
314 static void
315 gst_vertigotv_class_init (gpointer klass, gpointer class_data)
316 {
317   GObjectClass *gobject_class;
318   GstBaseTransformClass *trans_class;
319
320   gobject_class = (GObjectClass *) klass;
321   trans_class = (GstBaseTransformClass *) klass;
322
323   parent_class = g_type_class_peek_parent (klass);
324
325   gobject_class->set_property = gst_vertigotv_set_property;
326   gobject_class->get_property = gst_vertigotv_get_property;
327
328   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SPEED,
329       g_param_spec_float ("speed", "Speed", "Control the speed of movement",
330           0.01, 100.0, 0.02, G_PARAM_READWRITE));
331   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ZOOM_SPEED,
332       g_param_spec_float ("zoom_speed", "Zoom Speed",
333           "Control the rate of zooming", 1.01, 1.1, 1.01, G_PARAM_READWRITE));
334
335   trans_class->set_caps = GST_DEBUG_FUNCPTR (gst_vertigotv_set_caps);
336   trans_class->get_unit_size = GST_DEBUG_FUNCPTR (gst_vertigotv_get_unit_size);
337   trans_class->transform = GST_DEBUG_FUNCPTR (gst_vertigotv_transform);
338 }
339
340 static void
341 gst_vertigotv_init (GTypeInstance * instance, gpointer g_class)
342 {
343   GstVertigoTV *filter = GST_VERTIGOTV (instance);
344
345   filter->buffer = NULL;
346   filter->phase = 0.0;
347   filter->phase_increment = 0.02;
348   filter->zoomrate = 1.01;
349 }
350
351 GType
352 gst_vertigotv_get_type (void)
353 {
354   static GType vertigotv_type = 0;
355
356   if (!vertigotv_type) {
357     static const GTypeInfo vertigotv_info = {
358       sizeof (GstVertigoTVClass),
359       gst_vertigotv_base_init,
360       NULL,
361       (GClassInitFunc) gst_vertigotv_class_init,
362       NULL,
363       NULL,
364       sizeof (GstVertigoTV),
365       0,
366       (GInstanceInitFunc) gst_vertigotv_init,
367     };
368
369     vertigotv_type =
370         g_type_register_static (GST_TYPE_VIDEO_FILTER, "GstVertigoTV",
371         &vertigotv_info, 0);
372   }
373   return vertigotv_type;
374 }