1 /* GStreamer unit test for the alpha element
2 *
3 * Copyright (C) 2007 Ravi Kiran K N <ravi.kiran@samsung.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 */
20
21 #include <gst/check/gstcheck.h>
22 #include <gst/video/video.h>
23
24
25 GstPad *srcpad, *sinkpad;
26
27 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
28 GST_PAD_SINK,
29 GST_PAD_ALWAYS,
30 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("AYUV"))
31 );
32 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
33 GST_PAD_SRC,
34 GST_PAD_ALWAYS,
35 GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV, "
36 "ARGB, BGRA, ABGR, RGBA, Y444, xRGB, BGRx, xBGR, "
37 "RGBx, RGB, BGR, Y42B, YUY2, YVYU, UYVY, I420, YV12, Y41B } "))
38 );
39
40
41 typedef enum
42 {
43 FILL_GREEN,
44 FILL_BLUE
45 }
46 FillColor;
47
48 static GstElement *
setup_alpha(void)49 setup_alpha (void)
50 {
51 GstElement *alpha;
52
53 alpha = gst_check_setup_element ("alpha");
54 srcpad = gst_check_setup_src_pad (alpha, &srctemplate);
55 sinkpad = gst_check_setup_sink_pad (alpha, &sinktemplate);
56
57 gst_pad_set_active (srcpad, TRUE);
58 gst_pad_set_active (sinkpad, TRUE);
59
60 return alpha;
61 }
62
63 static void
cleanup_alpha(GstElement * alpha)64 cleanup_alpha (GstElement * alpha)
65 {
66 gst_pad_set_active (srcpad, FALSE);
67 gst_pad_set_active (sinkpad, FALSE);
68 gst_check_teardown_src_pad (alpha);
69 gst_check_teardown_sink_pad (alpha);
70 gst_check_teardown_element (alpha);
71 }
72
73 #define WIDTH 3
74 #define HEIGHT 4
75
76 static GstCaps *
create_caps_rgba32(void)77 create_caps_rgba32 (void)
78 {
79 GstCaps *caps;
80
81 caps = gst_caps_new_simple ("video/x-raw",
82 "width", G_TYPE_INT, WIDTH,
83 "height", G_TYPE_INT, HEIGHT,
84 "framerate", GST_TYPE_FRACTION, 0, 1,
85 "format", G_TYPE_STRING, "RGBA", NULL);
86
87 return caps;
88 }
89
90 static GstBuffer *
create_buffer_rgba32(FillColor color)91 create_buffer_rgba32 (FillColor color)
92 {
93 guint8 rgba32_img[HEIGHT * WIDTH * 4];
94 guint32 *rgba32 = (guint32 *) rgba32_img;
95
96 GstBuffer *buf;
97 GstMapInfo map;
98 guint32 rgba_col;
99 int i;
100
101 if (color == FILL_GREEN)
102 rgba_col = 0xff00ff00; /* GREEN */
103 else
104 rgba_col = 0xffff0000; /* BLUE */
105
106 for (i = 0; i < HEIGHT * WIDTH; i++)
107 rgba32[i] = rgba_col;
108
109 buf = gst_buffer_new_and_alloc (HEIGHT * WIDTH * 4);
110 gst_buffer_map (buf, &map, GST_MAP_READWRITE);
111 fail_unless_equals_int (map.size, sizeof (rgba32_img));
112 memcpy (map.data, rgba32_img, sizeof (rgba32_img));
113
114 gst_buffer_unmap (buf, &map);
115
116 return buf;
117 }
118
119
GST_START_TEST(test_chromakeying)120 GST_START_TEST (test_chromakeying)
121 {
122 GstElement *alpha;
123 GstBuffer *inbuffer;
124 GstBuffer *outbuffer;
125 GstCaps *incaps;
126 guint8 *ayuv;
127 guint outlength;
128 GstMapInfo map;
129 int i;
130
131 incaps = create_caps_rgba32 ();
132
133 alpha = setup_alpha ();
134
135 g_object_set (alpha, "method", 1, NULL); /* Chroma-keying GREEN */
136
137 fail_unless_equals_int (gst_element_set_state (alpha, GST_STATE_PLAYING),
138 GST_STATE_CHANGE_SUCCESS);
139
140 gst_check_setup_events (srcpad, alpha, incaps, GST_FORMAT_TIME);
141
142 inbuffer = create_buffer_rgba32 (FILL_GREEN);
143 GST_DEBUG ("Created buffer of %" G_GSIZE_FORMAT " bytes",
144 gst_buffer_get_size (inbuffer));
145 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
146
147 fail_unless_equals_int (gst_pad_push (srcpad, inbuffer), GST_FLOW_OK);
148
149 fail_unless (g_list_length (buffers) == 1);
150 outbuffer = (GstBuffer *) buffers->data;
151 fail_if (outbuffer == NULL);
152 fail_unless (GST_IS_BUFFER (outbuffer));
153
154 ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
155 outlength = WIDTH * HEIGHT * 4; /* output is AYUV */
156 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
157 fail_unless_equals_int (map.size, outlength);
158
159 ayuv = map.data;
160
161 /* check chroma keying GREEN */
162 for (i = 0; i < HEIGHT * WIDTH; i += 4)
163 fail_unless_equals_int (ayuv[i], 0x00);
164
165 gst_buffer_unmap (outbuffer, &map);
166
167 buffers = g_list_remove (buffers, outbuffer);
168 gst_buffer_unref (outbuffer);
169
170 fail_unless_equals_int (gst_element_set_state (alpha, GST_STATE_NULL),
171 GST_STATE_CHANGE_SUCCESS);
172
173 /* cleanup */
174 cleanup_alpha (alpha);
175 ASSERT_CAPS_REFCOUNT (incaps, "incaps", 1);
176 gst_caps_unref (incaps);
177
178 }
179
180 GST_END_TEST;
181
182
183
GST_START_TEST(test_alpha)184 GST_START_TEST (test_alpha)
185 {
186 GstElement *alpha;
187 GstBuffer *inbuffer;
188 GstBuffer *outbuffer;
189 GstCaps *incaps;
190 guint8 *ayuv;
191 guint outlength;
192 GstMapInfo map;
193 int i;
194
195 incaps = create_caps_rgba32 ();
196
197 alpha = setup_alpha ();
198
199 g_object_set (alpha, "alpha", 0.5, NULL); /* Alpha value 0.5 */
200
201 fail_unless_equals_int (gst_element_set_state (alpha, GST_STATE_PLAYING),
202 GST_STATE_CHANGE_SUCCESS);
203
204 gst_check_setup_events (srcpad, alpha, incaps, GST_FORMAT_TIME);
205
206 inbuffer = create_buffer_rgba32 (FILL_BLUE);
207 GST_DEBUG ("Created buffer of %" G_GSIZE_FORMAT " bytes",
208 gst_buffer_get_size (inbuffer));
209 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
210
211 /* pushing gives away reference */
212 GST_DEBUG ("push it");
213 fail_unless_equals_int (gst_pad_push (srcpad, inbuffer), GST_FLOW_OK);
214 GST_DEBUG ("pushed it");
215
216 /* ... and puts a new buffer on the global list */
217 fail_unless (g_list_length (buffers) == 1);
218 outbuffer = (GstBuffer *) buffers->data;
219 fail_if (outbuffer == NULL);
220 fail_unless (GST_IS_BUFFER (outbuffer));
221
222 ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
223 outlength = WIDTH * HEIGHT * 4; /* output is AYUV */
224 gst_buffer_map (outbuffer, &map, GST_MAP_READ);
225 fail_unless_equals_int (map.size, outlength);
226
227 ayuv = map.data;
228
229 for (i = 0; i < HEIGHT * WIDTH; i += 4)
230 fail_unless_equals_int (ayuv[i], 0x7F);
231
232 gst_buffer_unmap (outbuffer, &map);
233
234 buffers = g_list_remove (buffers, outbuffer);
235 gst_buffer_unref (outbuffer);
236
237 fail_unless_equals_int (gst_element_set_state (alpha, GST_STATE_NULL),
238 GST_STATE_CHANGE_SUCCESS);
239
240 /* cleanup */
241 GST_DEBUG ("cleanup alpha");
242 cleanup_alpha (alpha);
243 GST_DEBUG ("cleanup, unref incaps");
244 ASSERT_CAPS_REFCOUNT (incaps, "incaps", 1);
245 gst_caps_unref (incaps);
246
247 }
248
249 GST_END_TEST;
250
251
252 static Suite *
alpha_suite(void)253 alpha_suite (void)
254 {
255 Suite *s = suite_create ("alpha");
256 TCase *tc_chain = tcase_create ("general");
257
258 suite_add_tcase (s, tc_chain);
259 tcase_add_test (tc_chain, test_alpha);
260 tcase_add_test (tc_chain, test_chromakeying);
261
262 return s;
263 }
264
265 GST_CHECK_MAIN (alpha);
266