Tizen 2.0 Release
[framework/multimedia/gst-plugins-good0.10.git] / tests / check / elements / alphacolor.c
1 /* GStreamer unit test for the alphacolor element
2  *
3  * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
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., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <gst/check/gstcheck.h>
22 #include <gst/video/video.h>
23
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;
28
29 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
30     GST_PAD_SINK,
31     GST_PAD_ALWAYS,
32     GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("AYUV"))
33     );
34 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
35     GST_PAD_SRC,
36     GST_PAD_ALWAYS,
37     GST_STATIC_CAPS (GST_VIDEO_CAPS_RGBA ";" GST_VIDEO_CAPS_RGB)
38     );
39
40 static GstElement *
41 setup_alphacolor (void)
42 {
43   GstElement *alphacolor;
44
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);
48
49   gst_pad_set_active (mysrcpad, TRUE);
50   gst_pad_set_active (mysinkpad, TRUE);
51
52   return alphacolor;
53 }
54
55 static void
56 cleanup_alphacolor (GstElement * alphacolor)
57 {
58   GST_DEBUG ("cleaning up");
59
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);
65 }
66
67 #define WIDTH 3
68 #define HEIGHT 4
69
70 static GstCaps *
71 create_caps_rgb24 (void)
72 {
73   GstCaps *caps;
74
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);
85
86   return caps;
87 }
88
89 static GstCaps *
90 create_caps_rgba32 (void)
91 {
92   GstCaps *caps;
93
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);
105
106   return caps;
107 }
108
109 static GstBuffer *
110 create_buffer_rgb24_3x4 (void)
111 {
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
118   };
119   guint rowstride = GST_ROUND_UP_4 (WIDTH * 3);
120   GstBuffer *buf;
121   GstCaps *caps;
122
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));
126
127   caps = create_caps_rgb24 ();
128   gst_buffer_set_caps (buf, caps);
129   gst_caps_unref (caps);
130
131   return buf;
132 }
133
134 static GstBuffer *
135 create_buffer_rgba32_3x4 (void)
136 {
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
142    */
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
148   };
149   guint rowstride = WIDTH * 4;
150   GstBuffer *buf;
151   GstCaps *caps;
152
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));
156
157   caps = create_caps_rgba32 ();
158   gst_buffer_set_caps (buf, caps);
159   gst_caps_unref (caps);
160
161   return buf;
162 }
163
164 GST_START_TEST (test_rgb24)
165 {
166   GstElement *alphacolor;
167   GstBuffer *inbuffer;
168   GstCaps *incaps;
169
170   incaps = create_caps_rgb24 ();
171   alphacolor = setup_alphacolor ();
172
173   fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_PLAYING),
174       GST_STATE_CHANGE_SUCCESS);
175
176   inbuffer = create_buffer_rgb24_3x4 ();
177   ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1);
178
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");
185
186   fail_unless (g_list_length (buffers) == 0);
187
188   fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_NULL),
189       GST_STATE_CHANGE_SUCCESS);
190
191   /* cleanup */
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);
197 }
198
199 GST_END_TEST;
200
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) \
203     { \
204         guint8 *pixel; \
205         pixel = ((guint8*)(ayuv) + ((WIDTH * 4) * (y)) + ((x) * 4)); \
206         fail_unless_equals_int (pixel[0], a); \
207     }
208
209 GST_START_TEST (test_rgba32)
210 {
211   GstElement *alphacolor;
212   GstBuffer *inbuffer;
213   GstBuffer *outbuffer;
214   GstCaps *incaps;
215   guint8 *ayuv;
216   guint outlength;
217
218   incaps = create_caps_rgba32 ();
219   alphacolor = setup_alphacolor ();
220
221   fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_PLAYING),
222       GST_STATE_CHANGE_SUCCESS);
223
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);
227
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");
232
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));
238
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);
242
243   ayuv = GST_BUFFER_DATA (outbuffer);
244
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);
258
259   /* we don't check the YUV data, because apparently results differ slightly
260    * depending on whether we run in valgrind or not */
261
262   buffers = g_list_remove (buffers, outbuffer);
263   gst_buffer_unref (outbuffer);
264
265   fail_unless_equals_int (gst_element_set_state (alphacolor, GST_STATE_NULL),
266       GST_STATE_CHANGE_SUCCESS);
267
268   /* cleanup */
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);
274 }
275
276 GST_END_TEST;
277
278
279 static Suite *
280 alphacolor_suite (void)
281 {
282   Suite *s = suite_create ("alphacolor");
283   TCase *tc_chain = tcase_create ("general");
284
285   suite_add_tcase (s, tc_chain);
286   tcase_add_test (tc_chain, test_rgb24);
287   tcase_add_test (tc_chain, test_rgba32);
288
289   return s;
290 }
291
292 GST_CHECK_MAIN (alphacolor);