1 /* GStreamer unit test for the alphacolor element
3 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
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.
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.
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., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 #include <gst/check/gstcheck.h>
22 #include <gst/video/video.h>
24 /* For ease of programming we use globals to keep refs for our floating
25 * src and sink pads we create; otherwise we always have to do get_pad,
26 * get_peer, and then remove references in every test function */
27 GstPad *mysrcpad, *mysinkpad;
29 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
32 GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV"))
34 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
37 GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_RGB)
41 setup_alphacolor (void)
43 GstElement *alphacolor;
45 alphacolor = gst_check_setup_element ("alphacolor");
46 mysrcpad = gst_check_setup_src_pad (alphacolor, &srctemplate, NULL);
47 mysinkpad = gst_check_setup_sink_pad (alphacolor, &sinktemplate, NULL);
49 gst_pad_set_active (mysrcpad, TRUE);
50 gst_pad_set_active (mysinkpad, TRUE);
56 cleanup_alphacolor (GstElement * alphacolor)
58 GST_DEBUG ("cleaning up");
60 gst_pad_set_active (mysrcpad, FALSE);
61 gst_pad_set_active (mysinkpad, FALSE);
62 gst_check_teardown_src_pad (alphacolor);
63 gst_check_teardown_sink_pad (alphacolor);
64 gst_check_teardown_element (alphacolor);
71 create_caps_rgb24 (void)
75 caps = gst_caps_new_simple ("video/x-raw-rgb",
76 "width", G_TYPE_INT, 3,
77 "height", G_TYPE_INT, 4,
78 "bpp", G_TYPE_INT, 24,
79 "depth", G_TYPE_INT, 24,
80 "framerate", GST_TYPE_FRACTION, 0, 1,
81 "endianness", G_TYPE_INT, G_BIG_ENDIAN,
82 "red_mask", G_TYPE_INT, 0x00ff0000,
83 "green_mask", G_TYPE_INT, 0x0000ff00,
84 "blue_mask", G_TYPE_INT, 0x000000ff, NULL);
90 create_caps_rgba32 (void)
94 caps = gst_caps_new_simple ("video/x-raw-rgb",
95 "width", G_TYPE_INT, 3,
96 "height", G_TYPE_INT, 4,
97 "bpp", G_TYPE_INT, 32,
98 "depth", G_TYPE_INT, 32,
99 "framerate", GST_TYPE_FRACTION, 0, 1,
100 "endianness", G_TYPE_INT, G_BIG_ENDIAN,
101 "red_mask", G_TYPE_INT, 0xff000000,
102 "green_mask", G_TYPE_INT, 0x00ff0000,
103 "blue_mask", G_TYPE_INT, 0x0000ff00,
104 "alpha_mask", G_TYPE_INT, 0x000000ff, NULL);
110 create_buffer_rgb24_3x4 (void)
112 /* stride is rounded up to multiple of 4, so 3 bytes padding for each row */
113 const guint8 rgb24_3x4_img[HEIGHT * GST_ROUND_UP_4 (WIDTH * 3)] = {
114 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
115 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00
119 guint rowstride = GST_ROUND_UP_4 (WIDTH * 3);
123 buf = gst_buffer_new_and_alloc (HEIGHT * rowstride);
124 fail_unless_equals_int (GST_BUFFER_SIZE (buf), sizeof (rgb24_3x4_img));
125 memcpy (GST_BUFFER_DATA (buf), rgb24_3x4_img, sizeof (rgb24_3x4_img));
127 caps = create_caps_rgb24 ();
128 gst_buffer_set_caps (buf, caps);
129 gst_caps_unref (caps);
135 create_buffer_rgba32_3x4 (void)
137 /* stride is rounded up to multiple of 4, so 3 bytes padding for each row */
138 /* should be: RED BLUE WHITE where 'nothing' is fully transparent
139 * GREEN RED BLUE and all other colours are fully
140 * NOTHING GREEN RED opaque.
141 * BLACK NOTHING GREEN
143 const guint8 rgba32_3x4_img[HEIGHT * WIDTH * 4] = {
144 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
145 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff,
147 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff
149 guint rowstride = WIDTH * 4;
153 buf = gst_buffer_new_and_alloc (HEIGHT * rowstride);
154 fail_unless_equals_int (GST_BUFFER_SIZE (buf), sizeof (rgba32_3x4_img));
155 memcpy (GST_BUFFER_DATA (buf), rgba32_3x4_img, sizeof (rgba32_3x4_img));
157 caps = create_caps_rgba32 ();
158 gst_buffer_set_caps (buf, caps);
159 gst_caps_unref (caps);
164 GST_START_TEST (test_rgb24)
166 GstElement *alphacolor;
170 incaps = create_caps_rgb24 ();
171 alphacolor = setup_alphacolor ();
173 fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_PLAYING),
174 GST_STATE_CHANGE_SUCCESS);
176 inbuffer = create_buffer_rgb24_3x4 ();
177 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
179 /* pushing gives away reference; this should error out with a not-negotiated
180 * error, alphacolor should only accept RGBA caps, not but plain RGB24 caps */
181 GST_DEBUG ("push it");
182 fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer),
183 GST_FLOW_NOT_NEGOTIATED);
184 GST_DEBUG ("pushed it");
186 fail_unless (g_list_length (buffers) == 0);
188 fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_NULL),
189 GST_STATE_CHANGE_SUCCESS);
192 GST_DEBUG ("cleanup alphacolor");
193 cleanup_alphacolor (alphacolor);
194 GST_DEBUG ("cleanup, unref incaps");
195 ASSERT_CAPS_REFCOUNT (incaps, "incaps", 1);
196 gst_caps_unref (incaps);
201 /* these macros assume WIDTH and HEIGHT is fixed to what's defined above */
202 #define fail_unless_ayuv_pixel_has_alpha(ayuv,x,y,a) \
205 pixel = ((guint8*)(ayuv) + ((WIDTH * 4) * (y)) + ((x) * 4)); \
206 fail_unless_equals_int (pixel[0], a); \
209 GST_START_TEST (test_rgba32)
211 GstElement *alphacolor;
213 GstBuffer *outbuffer;
218 incaps = create_caps_rgba32 ();
219 alphacolor = setup_alphacolor ();
221 fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_PLAYING),
222 GST_STATE_CHANGE_SUCCESS);
224 inbuffer = create_buffer_rgba32_3x4 ();
225 GST_DEBUG ("Created buffer of %d bytes", GST_BUFFER_SIZE (inbuffer));
226 ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
228 /* pushing gives away reference */
229 GST_DEBUG ("push it");
230 fail_unless_equals_int (gst_pad_push (mysrcpad, inbuffer), GST_FLOW_OK);
231 GST_DEBUG ("pushed it");
233 /* ... and puts a new buffer on the global list */
234 fail_unless (g_list_length (buffers) == 1);
235 outbuffer = (GstBuffer *) buffers->data;
236 fail_if (outbuffer == NULL);
237 fail_unless (GST_IS_BUFFER (outbuffer));
239 ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
240 outlength = WIDTH * HEIGHT * 4; /* output is AYUV */
241 fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), outlength);
243 ayuv = GST_BUFFER_DATA (outbuffer);
245 /* check alpha values (0x00 = totally transparent, 0xff = totally opaque) */
246 fail_unless_ayuv_pixel_has_alpha (ayuv, 0, 0, 0xff);
247 fail_unless_ayuv_pixel_has_alpha (ayuv, 1, 0, 0xff);
248 fail_unless_ayuv_pixel_has_alpha (ayuv, 2, 0, 0xff);
249 fail_unless_ayuv_pixel_has_alpha (ayuv, 0, 1, 0xff);
250 fail_unless_ayuv_pixel_has_alpha (ayuv, 1, 1, 0xff);
251 fail_unless_ayuv_pixel_has_alpha (ayuv, 2, 1, 0xff);
252 fail_unless_ayuv_pixel_has_alpha (ayuv, 0, 2, 0x00);
253 fail_unless_ayuv_pixel_has_alpha (ayuv, 1, 2, 0xff);
254 fail_unless_ayuv_pixel_has_alpha (ayuv, 2, 2, 0xff);
255 fail_unless_ayuv_pixel_has_alpha (ayuv, 0, 3, 0xff);
256 fail_unless_ayuv_pixel_has_alpha (ayuv, 1, 3, 0x00);
257 fail_unless_ayuv_pixel_has_alpha (ayuv, 2, 3, 0xff);
259 /* we don't check the YUV data, because apparently results differ slightly
260 * depending on whether we run in valgrind or not */
262 buffers = g_list_remove (buffers, outbuffer);
263 gst_buffer_unref (outbuffer);
265 fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_NULL),
266 GST_STATE_CHANGE_SUCCESS);
269 GST_DEBUG ("cleanup alphacolor");
270 cleanup_alphacolor (alphacolor);
271 GST_DEBUG ("cleanup, unref incaps");
272 ASSERT_CAPS_REFCOUNT (incaps, "incaps", 1);
273 gst_caps_unref (incaps);
280 alphacolor_suite (void)
282 Suite *s = suite_create ("alphacolor");
283 TCase *tc_chain = tcase_create ("general");
285 suite_add_tcase (s, tc_chain);
286 tcase_add_test (tc_chain, test_rgb24);
287 tcase_add_test (tc_chain, test_rgba32);
292 GST_CHECK_MAIN (alphacolor);