1 /* GStreamer
2  *
3  * Copyright (C) 2009 Sebastian Dröge <sebastian.droege@collabora.co.uk>
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 
23 gboolean have_eos = FALSE;
24 
25 /* For ease of programming we use globals to keep refs for our floating
26  * src and sink pads we create; otherwise we always have to do get_pad,
27  * get_peer, and then remove references in every test function */
28 GstPad *myvideosrcpad, *mymasksrcpad, *mysinkpad;
29 
30 
31 #define SHAPEWIPE_VIDEO_CAPS_STRING    \
32     "video/x-raw, " \
33     "format = (string)AYUV, " \
34     "width = 400, " \
35     "height = 400, " \
36     "framerate = 0/1"
37 
38 #define SHAPEWIPE_MASK_CAPS_STRING    \
39     "video/x-raw, " \
40     "format = (string)GRAY8, " \
41     "width = 400, " \
42     "height = 400, " \
43     "framerate = 0/1"
44 
45 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
46     GST_PAD_SINK,
47     GST_PAD_ALWAYS,
48     GST_STATIC_CAPS (SHAPEWIPE_VIDEO_CAPS_STRING)
49     );
50 static GstStaticPadTemplate videosrctemplate =
51 GST_STATIC_PAD_TEMPLATE ("videosrc",
52     GST_PAD_SRC,
53     GST_PAD_ALWAYS,
54     GST_STATIC_CAPS (SHAPEWIPE_VIDEO_CAPS_STRING)
55     );
56 static GstStaticPadTemplate masksrctemplate =
57 GST_STATIC_PAD_TEMPLATE ("masksrc",
58     GST_PAD_SRC,
59     GST_PAD_ALWAYS,
60     GST_STATIC_CAPS (SHAPEWIPE_MASK_CAPS_STRING)
61     );
62 
63 
64 static GstBuffer *output = NULL;
65 
66 static GstFlowReturn
on_chain(GstPad * pad,GstObject * parent,GstBuffer * buffer)67 on_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
68 {
69   g_return_val_if_fail (output == NULL, GST_FLOW_ERROR);
70 
71   output = buffer;
72   return GST_FLOW_OK;
73 }
74 
GST_START_TEST(test_general)75 GST_START_TEST (test_general)
76 {
77   GstElement *shapewipe, *videosrc, *masksrc, *sink, *bin;
78   GstPad *p;
79   GstCaps *caps;
80   GstBuffer *mask, *input;
81   guint i, j;
82   guint8 *data;
83   GstMapInfo map;
84 
85   bin = gst_bin_new ("myshapewipe");
86   videosrc = gst_bin_new ("myvideosrc");
87   masksrc = gst_bin_new ("mymasksrc");
88   sink = gst_bin_new ("mysink");
89   shapewipe = gst_element_factory_make ("shapewipe", NULL);
90   fail_unless (shapewipe != NULL);
91   gst_bin_add_many (GST_BIN (bin), videosrc, masksrc, shapewipe, sink, NULL);
92 
93   myvideosrcpad =
94       gst_pad_new_from_static_template (&videosrctemplate, "videosrc");
95   gst_element_add_pad (videosrc, myvideosrcpad);
96 
97   mymasksrcpad = gst_pad_new_from_static_template (&masksrctemplate, "masksrc");
98   gst_element_add_pad (masksrc, mymasksrcpad);
99 
100   mysinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
101   gst_element_add_pad (sink, mysinkpad);
102   gst_pad_set_chain_function (mysinkpad, on_chain);
103 
104   p = gst_element_get_static_pad (shapewipe, "video_sink");
105   fail_unless (gst_pad_link (myvideosrcpad, p) == GST_PAD_LINK_OK);
106   gst_object_unref (p);
107   p = gst_element_get_static_pad (shapewipe, "mask_sink");
108   fail_unless (gst_pad_link (mymasksrcpad, p) == GST_PAD_LINK_OK);
109   gst_object_unref (p);
110   p = gst_element_get_static_pad (shapewipe, "src");
111   fail_unless (gst_pad_link (p, mysinkpad) == GST_PAD_LINK_OK);
112   gst_object_unref (p);
113 
114   fail_unless (gst_element_set_state (bin,
115           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
116 
117   caps = gst_caps_from_string (SHAPEWIPE_MASK_CAPS_STRING);
118   gst_check_setup_events (mymasksrcpad, masksrc, caps, GST_FORMAT_TIME);
119   gst_caps_unref (caps);
120 
121   caps = gst_caps_from_string (SHAPEWIPE_VIDEO_CAPS_STRING);
122   gst_check_setup_events (myvideosrcpad, videosrc, caps, GST_FORMAT_TIME);
123   gst_caps_unref (caps);
124 
125   mask = gst_buffer_new_and_alloc (400 * 400);
126   gst_buffer_map (mask, &map, GST_MAP_WRITE);
127   data = map.data;
128   for (i = 0; i < 400; i++) {
129     for (j = 0; j < 400; j++) {
130       if (i < 100 && j < 100)
131         data[0] = 0;
132       else if (i < 200 && j < 200)
133         data[0] = 85;
134       else if (i < 300 && j < 300)
135         data[0] = 170;
136       else
137         data[0] = 254;
138       data++;
139     }
140   }
141   gst_buffer_unmap (mask, &map);
142 
143   fail_unless (gst_pad_push (mymasksrcpad, mask) == GST_FLOW_OK);
144 
145   input = gst_buffer_new_and_alloc (400 * 400 * 4);
146   gst_buffer_map (input, &map, GST_MAP_WRITE);
147   data = map.data;
148   for (i = 0; i < 400; i++) {
149     for (j = 0; j < 400; j++) {
150       /* This is green */
151       data[0] = 255;            /* A */
152       data[1] = 173;            /* Y */
153       data[2] = 42;             /* U */
154       data[3] = 26;             /* V */
155       data += 4;
156     }
157   }
158   gst_buffer_unmap (input, &map);
159 
160   g_object_set (G_OBJECT (shapewipe), "position", 0.0, NULL);
161   output = NULL;
162   fail_unless (gst_pad_push (myvideosrcpad,
163           gst_buffer_ref (input)) == GST_FLOW_OK);
164   fail_unless (output != NULL);
165   gst_buffer_map (output, &map, GST_MAP_WRITE);
166   data = map.data;
167   for (i = 0; i < 400; i++) {
168     for (j = 0; j < 400; j++) {
169       fail_unless_equals_int (data[0], 255);    /* A */
170       fail_unless_equals_int (data[1], 173);    /* Y */
171       fail_unless_equals_int (data[2], 42);     /* U */
172       fail_unless_equals_int (data[3], 26);     /* V */
173       data += 4;
174     }
175   }
176   gst_buffer_unmap (output, &map);
177   gst_buffer_unref (output);
178   output = NULL;
179 
180   g_object_set (G_OBJECT (shapewipe), "position", 0.1, NULL);
181   output = NULL;
182   fail_unless (gst_pad_push (myvideosrcpad,
183           gst_buffer_ref (input)) == GST_FLOW_OK);
184   fail_unless (output != NULL);
185   gst_buffer_map (output, &map, GST_MAP_READ);
186   data = map.data;
187   for (i = 0; i < 400; i++) {
188     for (j = 0; j < 400; j++) {
189       if (i < 100 && j < 100) {
190         fail_unless_equals_int (data[0], 0);    /* A */
191         fail_unless_equals_int (data[1], 173);  /* Y */
192         fail_unless_equals_int (data[2], 42);   /* U */
193         fail_unless_equals_int (data[3], 26);   /* V */
194       } else {
195         fail_unless_equals_int (data[0], 255);  /* A */
196         fail_unless_equals_int (data[1], 173);  /* Y */
197         fail_unless_equals_int (data[2], 42);   /* U */
198         fail_unless_equals_int (data[3], 26);   /* V */
199       }
200       data += 4;
201     }
202   }
203   gst_buffer_unmap (output, &map);
204   gst_buffer_unref (output);
205   output = NULL;
206 
207   g_object_set (G_OBJECT (shapewipe), "position", 0.34, NULL);
208   output = NULL;
209   fail_unless (gst_pad_push (myvideosrcpad,
210           gst_buffer_ref (input)) == GST_FLOW_OK);
211   fail_unless (output != NULL);
212   gst_buffer_map (output, &map, GST_MAP_READ);
213   data = map.data;
214   for (i = 0; i < 400; i++) {
215     for (j = 0; j < 400; j++) {
216       if (i < 200 && j < 200) {
217         fail_unless_equals_int (data[0], 0);    /* A */
218         fail_unless_equals_int (data[1], 173);  /* Y */
219         fail_unless_equals_int (data[2], 42);   /* U */
220         fail_unless_equals_int (data[3], 26);   /* V */
221       } else {
222         fail_unless_equals_int (data[0], 255);  /* A */
223         fail_unless_equals_int (data[1], 173);  /* Y */
224         fail_unless_equals_int (data[2], 42);   /* U */
225         fail_unless_equals_int (data[3], 26);   /* V */
226       }
227       data += 4;
228     }
229   }
230   gst_buffer_unmap (output, &map);
231   gst_buffer_unref (output);
232   output = NULL;
233 
234   g_object_set (G_OBJECT (shapewipe), "position", 0.67, NULL);
235   output = NULL;
236   fail_unless (gst_pad_push (myvideosrcpad,
237           gst_buffer_ref (input)) == GST_FLOW_OK);
238   fail_unless (output != NULL);
239   gst_buffer_map (output, &map, GST_MAP_READ);
240   data = map.data;
241   for (i = 0; i < 400; i++) {
242     for (j = 0; j < 400; j++) {
243       if (i < 300 && j < 300) {
244         fail_unless_equals_int (data[0], 0);    /* A */
245         fail_unless_equals_int (data[1], 173);  /* Y */
246         fail_unless_equals_int (data[2], 42);   /* U */
247         fail_unless_equals_int (data[3], 26);   /* V */
248       } else {
249         fail_unless_equals_int (data[0], 255);  /* A */
250         fail_unless_equals_int (data[1], 173);  /* Y */
251         fail_unless_equals_int (data[2], 42);   /* U */
252         fail_unless_equals_int (data[3], 26);   /* V */
253       }
254       data += 4;
255     }
256   }
257   gst_buffer_unmap (output, &map);
258   gst_buffer_unref (output);
259   output = NULL;
260 
261   g_object_set (G_OBJECT (shapewipe), "position", 1.0, NULL);
262   output = NULL;
263   fail_unless (gst_pad_push (myvideosrcpad,
264           gst_buffer_ref (input)) == GST_FLOW_OK);
265   fail_unless (output != NULL);
266   gst_buffer_map (output, &map, GST_MAP_READ);
267   data = map.data;
268   for (i = 0; i < 400; i++) {
269     for (j = 0; j < 400; j++) {
270       fail_unless_equals_int (data[0], 0);      /* A */
271       fail_unless_equals_int (data[1], 173);    /* Y */
272       fail_unless_equals_int (data[2], 42);     /* U */
273       fail_unless_equals_int (data[3], 26);     /* V */
274       data += 4;
275     }
276   }
277   gst_buffer_unmap (output, &map);
278   gst_buffer_unref (output);
279   output = NULL;
280 
281   gst_buffer_unref (input);
282 
283   fail_unless (gst_element_set_state (bin,
284           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
285 
286   p = gst_element_get_static_pad (shapewipe, "video_sink");
287   fail_unless (gst_pad_unlink (myvideosrcpad, p));
288   gst_object_unref (p);
289   p = gst_element_get_static_pad (shapewipe, "mask_sink");
290   fail_unless (gst_pad_unlink (mymasksrcpad, p));
291   gst_object_unref (p);
292   p = gst_element_get_static_pad (shapewipe, "src");
293   fail_unless (gst_pad_unlink (p, mysinkpad));
294   gst_object_unref (p);
295 
296   gst_object_unref (bin);
297 }
298 
299 GST_END_TEST;
300 
301 static Suite *
shapewipe_suite(void)302 shapewipe_suite (void)
303 {
304   Suite *s = suite_create ("shapewipe");
305   TCase *tc_chain = tcase_create ("general");
306 
307   suite_add_tcase (s, tc_chain);
308   tcase_set_timeout (tc_chain, 180);
309   tcase_add_test (tc_chain, test_general);
310 
311   return s;
312 }
313 
314 GST_CHECK_MAIN (shapewipe);
315