1 /* GStreamer
2  * Copyright (C) 2012-2016 Matthew Waters <ystreet00@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include <gst/check/gstcheck.h>
24 #include <gst/gl/gstglconfig.h>
25 
26 #ifndef GST_DISABLE_PARSE
27 
28 static GstElement *
setup_pipeline(const gchar * pipe_descr)29 setup_pipeline (const gchar * pipe_descr)
30 {
31   GstElement *pipeline;
32 
33   pipeline = gst_parse_launch (pipe_descr, NULL);
34   g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
35   return pipeline;
36 }
37 
38 /*
39  * run_pipeline:
40  * @pipe: the pipeline to run
41  * @desc: the description for use in messages
42  * @events: is a mask of expected events
43  * @tevent: is the expected terminal event.
44  *
45  * the poll call will time out after half a second.
46  */
47 static void
run_pipeline(GstElement * pipe,const gchar * descr,GstMessageType events,GstMessageType tevent,GstState target_state)48 run_pipeline (GstElement * pipe, const gchar * descr,
49     GstMessageType events, GstMessageType tevent, GstState target_state)
50 {
51   GstBus *bus;
52   GstMessage *message;
53   GstMessageType revent;
54   GstStateChangeReturn ret;
55 
56   g_assert (pipe);
57   bus = gst_element_get_bus (pipe);
58   g_assert (bus);
59 
60   fail_if (gst_element_set_state (pipe, target_state) ==
61       GST_STATE_CHANGE_FAILURE, "Could not set pipeline %s to playing", descr);
62   ret = gst_element_get_state (pipe, NULL, NULL, 10 * GST_SECOND);
63   if (ret == GST_STATE_CHANGE_ASYNC) {
64     g_critical ("Pipeline '%s' failed to go to PAUSED fast enough", descr);
65     goto done;
66   } else if ((ret != GST_STATE_CHANGE_SUCCESS)
67       && (ret != GST_STATE_CHANGE_NO_PREROLL)) {
68     g_critical ("Pipeline '%s' failed to go into PAUSED state (%s)", descr,
69         gst_element_state_change_return_get_name (ret));
70     goto done;
71   }
72 
73   while (1) {
74     message = gst_bus_poll (bus, GST_MESSAGE_ANY, GST_SECOND / 2);
75 
76     /* always have to pop the message before getting back into poll */
77     if (message) {
78       revent = GST_MESSAGE_TYPE (message);
79       gst_message_unref (message);
80     } else {
81       revent = GST_MESSAGE_UNKNOWN;
82     }
83 
84     if (revent == tevent) {
85       break;
86     } else if (revent == GST_MESSAGE_UNKNOWN) {
87       g_critical ("Unexpected timeout in gst_bus_poll, looking for %d: %s",
88           tevent, descr);
89       break;
90     } else if (revent & events) {
91       continue;
92     }
93     g_critical
94         ("Unexpected message received of type %d, '%s', looking for %d: %s",
95         revent, gst_message_type_get_name (revent), tevent, descr);
96   }
97 
98 done:
99   fail_if (gst_element_set_state (pipe, GST_STATE_NULL) ==
100       GST_STATE_CHANGE_FAILURE, "Could not set pipeline %s to NULL", descr);
101   gst_element_get_state (pipe, NULL, NULL, GST_CLOCK_TIME_NONE);
102   gst_object_unref (pipe);
103 
104   gst_bus_set_flushing (bus, TRUE);
105   gst_object_unref (bus);
106 }
107 
GST_START_TEST(test_glimagesink)108 GST_START_TEST (test_glimagesink)
109 {
110   const gchar *s;
111   GstState target_state = GST_STATE_PLAYING;
112 
113   s = "videotestsrc num-buffers=10 ! glimagesink";
114   run_pipeline (setup_pipeline (s), s,
115       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
116       GST_MESSAGE_UNKNOWN, target_state);
117 }
118 
119 GST_END_TEST
GST_START_TEST(test_glfiltercube)120 GST_START_TEST (test_glfiltercube)
121 {
122   const gchar *s;
123   GstState target_state = GST_STATE_PLAYING;
124 
125   s = "videotestsrc num-buffers=10 ! glupload ! glfiltercube ! fakesink";
126   run_pipeline (setup_pipeline (s), s,
127       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
128       GST_MESSAGE_UNKNOWN, target_state);
129 }
130 
131 GST_END_TEST
132 #define N_EFFECTS 18
GST_START_TEST(test_gleffects)133 GST_START_TEST (test_gleffects)
134 {
135   gchar *s;
136   GstState target_state = GST_STATE_PLAYING;
137   guint i;
138 
139   for (i = 0; i < N_EFFECTS; i++) {
140     s = g_strdup_printf ("videotestsrc num-buffers=10 ! glupload ! "
141         "gleffects effect=%i ! fakesink", i);
142     run_pipeline (setup_pipeline (s), s,
143         GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
144         GST_MESSAGE_UNKNOWN, target_state);
145     g_free (s);
146   }
147 }
148 
149 GST_END_TEST
150 #undef N_EFFECTS
GST_START_TEST(test_glshader)151 GST_START_TEST (test_glshader)
152 {
153   const gchar *s;
154   GstState target_state = GST_STATE_PLAYING;
155 
156   s = "videotestsrc num-buffers=10 ! glupload ! glshader ! fakesink";
157   run_pipeline (setup_pipeline (s), s,
158       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
159       GST_MESSAGE_UNKNOWN, target_state);
160 
161 #if GST_GL_HAVE_OPENGL
162   s = "gltestsrc num-buffers=10 ! glshader ! fakesink";
163   run_pipeline (setup_pipeline (s), s,
164       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
165       GST_MESSAGE_UNKNOWN, target_state);
166 #endif
167 }
168 
169 GST_END_TEST
GST_START_TEST(test_glfilterapp)170 GST_START_TEST (test_glfilterapp)
171 {
172   const gchar *s;
173   GstState target_state = GST_STATE_PLAYING;
174 
175   s = "videotestsrc num-buffers=10 ! glupload ! glfilterapp ! fakesink";
176   run_pipeline (setup_pipeline (s), s,
177       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
178       GST_MESSAGE_UNKNOWN, target_state);
179 
180 #if GST_GL_HAVE_OPENGL
181   s = "gltestsrc num-buffers=10 ! glfilterapp ! fakesink";
182   run_pipeline (setup_pipeline (s), s,
183       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
184       GST_MESSAGE_UNKNOWN, target_state);
185 #endif
186 }
187 
188 GST_END_TEST
189 #ifdef HAVE_PNG
190 #ifdef HAVE_JPEG
GST_START_TEST(test_gloverlay)191 GST_START_TEST (test_gloverlay)
192 {
193   const gchar *s;
194   GstState target_state = GST_STATE_PLAYING;
195 
196   s = "videotestsrc num-buffers=10 ! glupload ! gloverlay ! fakesink";
197   run_pipeline (setup_pipeline (s), s,
198       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
199       GST_MESSAGE_UNKNOWN, target_state);
200 
201 #if GST_GL_HAVE_OPENGL
202   s = "gltestsrc num-buffers=10 ! gloverlay ! fakesink";
203   run_pipeline (setup_pipeline (s), s,
204       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
205       GST_MESSAGE_UNKNOWN, target_state);
206 #endif
207 }
208 
209 GST_END_TEST
210 #endif
211 #endif
212 #if GST_GL_HAVE_OPENGL
213 #define N_SRCS 13
GST_START_TEST(test_gltestsrc)214 GST_START_TEST (test_gltestsrc)
215 {
216   gchar *s;
217   GstState target_state = GST_STATE_PLAYING;
218   guint i;
219 
220   for (i = 0; i < N_SRCS; i++) {
221     s = g_strdup_printf ("gltestsrc pattern=%i num-buffers=10 ! fakesink", i);
222     run_pipeline (setup_pipeline (s), s,
223         GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
224         GST_MESSAGE_UNKNOWN, target_state);
225     g_free (s);
226   }
227 }
228 
229 GST_END_TEST
230 #undef N_SRCS
GST_START_TEST(test_glfilterglass)231 GST_START_TEST (test_glfilterglass)
232 {
233   const gchar *s;
234   GstState target_state = GST_STATE_PLAYING;
235 
236   s = "videotestsrc num-buffers=10 ! glupload ! glfilterglass ! fakesink";
237   run_pipeline (setup_pipeline (s), s,
238       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
239       GST_MESSAGE_UNKNOWN, target_state);
240 
241   s = "gltestsrc num-buffers=10 ! glfilterglass ! fakesink";
242   run_pipeline (setup_pipeline (s), s,
243       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
244       GST_MESSAGE_UNKNOWN, target_state);
245 }
246 
247 GST_END_TEST
248 #if 0
249 GST_START_TEST (test_glfilterreflectedscreen)
250 {
251   const gchar *s;
252   GstState target_state = GST_STATE_PLAYING;
253 
254   s = "videotestsrc num-buffers=10 ! glupload ! glfilterreflectedscreen ! "
255       "fakesink";
256   run_pipeline (setup_pipeline (s), s,
257       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
258       GST_MESSAGE_UNKNOWN, target_state);
259 
260   s = "gltestsrc num-buffers=10 ! glfilterreflectedscreen ! fakesink";
261   run_pipeline (setup_pipeline (s), s,
262       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
263       GST_MESSAGE_UNKNOWN, target_state);
264 }
265 
266 GST_END_TEST
267 #endif
GST_START_TEST(test_gldeinterlace)268 GST_START_TEST (test_gldeinterlace)
269 {
270   const gchar *s;
271   GstState target_state = GST_STATE_PLAYING;
272 
273   s = "videotestsrc num-buffers=10 ! glupload ! gldeinterlace ! fakesink";
274   run_pipeline (setup_pipeline (s), s,
275       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
276       GST_MESSAGE_UNKNOWN, target_state);
277 
278   s = "gltestsrc num-buffers=10 ! gldeinterlace ! fakesink";
279   run_pipeline (setup_pipeline (s), s,
280       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
281       GST_MESSAGE_UNKNOWN, target_state);
282 }
283 
284 GST_END_TEST
GST_START_TEST(test_glmosaic)285 GST_START_TEST (test_glmosaic)
286 {
287   const gchar *s;
288   GstState target_state = GST_STATE_PLAYING;
289 
290   s = "videotestsrc num-buffers=10 ! glupload ! glmosaic ! fakesink";
291   run_pipeline (setup_pipeline (s), s,
292       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
293       GST_MESSAGE_UNKNOWN, target_state);
294 
295   s = "gltestsrc num-buffers=10 ! glmosaic ! fakesink";
296   run_pipeline (setup_pipeline (s), s,
297       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
298       GST_MESSAGE_UNKNOWN, target_state);
299 }
300 
301 GST_END_TEST
302 #ifdef HAVE_PNG
GST_START_TEST(test_gldifferencematte)303 GST_START_TEST (test_gldifferencematte)
304 {
305   const gchar *s;
306   GstState target_state = GST_STATE_PLAYING;
307 
308   s = "videotestsrc num-buffers=10 ! glupload ! gldifferencematte ! fakesink";
309   run_pipeline (setup_pipeline (s), s,
310       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
311       GST_MESSAGE_UNKNOWN, target_state);
312 
313   s = "gltestsrc num-buffers=10 ! gldifferencematte ! fakesink";
314   run_pipeline (setup_pipeline (s), s,
315       GST_MESSAGE_ANY & ~(GST_MESSAGE_ERROR | GST_MESSAGE_WARNING),
316       GST_MESSAGE_UNKNOWN, target_state);
317 }
318 
319 GST_END_TEST
320 #endif /* HAVE_PNG */
321 #endif /* GST_GL_HAVE_OPENGL */
322 #endif /* !GST_DISABLE_PARSE */
323 static Suite *
gl_launch_lines_suite(void)324 gl_launch_lines_suite (void)
325 {
326   Suite *s = suite_create ("OpenGL pipelines");
327   TCase *tc_chain = tcase_create ("linear");
328 
329   /* time out after 60s, not the default 3 */
330   tcase_set_timeout (tc_chain, 60);
331 
332   suite_add_tcase (s, tc_chain);
333 #ifndef GST_DISABLE_PARSE
334   tcase_add_test (tc_chain, test_glimagesink);
335   tcase_add_test (tc_chain, test_glfiltercube);
336   tcase_add_test (tc_chain, test_gleffects);
337   tcase_add_test (tc_chain, test_glshader);
338   tcase_add_test (tc_chain, test_glfilterapp);
339 #ifdef HAVE_PNG
340 #ifdef HAVE_JPEG
341   tcase_add_test (tc_chain, test_gloverlay);
342 #endif
343 #endif
344 #if GST_GL_HAVE_OPENGL
345   tcase_add_test (tc_chain, test_gltestsrc);
346   tcase_add_test (tc_chain, test_glfilterglass);
347 /*  tcase_add_test (tc_chain, test_glfilterreflectedscreen);*/
348   /* glmosaic is still in -bad because it relies on GstVideoAggregator */
349   if (gst_registry_check_feature_version (gst_registry_get (), "glmosaic", 1, 0,
350           0)) {
351     tcase_add_test (tc_chain, test_glmosaic);
352   }
353   tcase_add_test (tc_chain, test_gldeinterlace);
354 #ifdef HAVE_PNG
355   tcase_add_test (tc_chain, test_gldifferencematte);
356 /*  tcase_add_test (tc_chain, test_glbumper);*/
357 #ifdef HAVE_JPEG
358 #endif /* HAVE_JPEG */
359 #endif /* HAVE_PNG */
360 #endif /* GST_GL_HAVE_OPENGL */
361 #endif /* !GST_DISABLE_PARSE */
362   return s;
363 }
364 
365 GST_CHECK_MAIN (gl_launch_lines);
366