|
1 /* GStreamer |
|
2 * |
|
3 * Common code for GStreamer unittests |
|
4 * |
|
5 * Copyright (C) 2004,2006 Thomas Vander Stichele <thomas at apestaart dot org> |
|
6 * Copyright (C) 2008 Thijs Vermeir <thijsvermeir@gmail.com> |
|
7 * |
|
8 * This library is free software; you can redistribute it and/or |
|
9 * modify it under the terms of the GNU Library General Public |
|
10 * License as published by the Free Software Foundation; either |
|
11 * version 2 of the License, or (at your option) any later version. |
|
12 * |
|
13 * This library is distributed in the hope that it will be useful, |
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
16 * Library General Public License for more details. |
|
17 * |
|
18 * You should have received a copy of the GNU Library General Public |
|
19 * License along with this library; if not, write to the |
|
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
|
21 * Boston, MA 02111-1307, USA. |
|
22 */ |
|
23 /** |
|
24 * SECTION:gstcheck |
|
25 * @short_description: Common code for GStreamer unit tests |
|
26 * |
|
27 * These macros and functions are for internal use of the unit tests found |
|
28 * inside the 'check' directories of various GStreamer packages. |
|
29 */ |
|
30 #include <string.h> |
|
31 #include "gstcheck.h" |
|
32 #include <glib_global.h> |
|
33 |
|
34 //#include "libgstreamer_wsd_solution.h" |
|
35 |
|
36 GST_DEBUG_CATEGORY (check_debug); |
|
37 |
|
38 /* logging function for tests |
|
39 * a test uses g_message() to log a debug line |
|
40 * a gst unit test can be run with GST_TEST_DEBUG env var set to see the |
|
41 * messages |
|
42 */ |
|
43 |
|
44 //gboolean _gst_check_threads_running = FALSE; |
|
45 //GList *thread_list = NULL; |
|
46 #if EMULATOR |
|
47 GET_GLOBAL_VAR_FROM_TLS(thread_list,gstcheck,GList*) |
|
48 #define thread_list (*GET_GSTREAMER_WSD_VAR_NAME(thread_list,gstcheck,g)()) |
|
49 #else |
|
50 EXPORT_C GList *thread_list = NULL; |
|
51 #endif |
|
52 |
|
53 //GMutex *mutex; |
|
54 #if EMULATOR |
|
55 GET_GLOBAL_VAR_FROM_TLS(mutex,gstcheck,GMutex*) |
|
56 #define mutex (*GET_GSTREAMER_WSD_VAR_NAME(mutex,gstcheck,g)()) |
|
57 #else |
|
58 EXPORT_C GMutex *mutex = NULL; |
|
59 #endif |
|
60 |
|
61 //GCond *start_cond; /* used to notify main thread of thread startups */ |
|
62 #if EMULATOR |
|
63 GET_GLOBAL_VAR_FROM_TLS(start_cond,gstcheck,GCond*) |
|
64 #define start_cond (*GET_GSTREAMER_WSD_VAR_NAME(start_cond,gstcheck,g)()) |
|
65 #else |
|
66 EXPORT_C GCond *start_cond = NULL; |
|
67 #endif |
|
68 |
|
69 //GCond *sync_cond; /* used to synchronize all threads and main thread */ |
|
70 #if EMULATOR |
|
71 GET_GLOBAL_VAR_FROM_TLS(sync_cond,gstcheck,GCond*) |
|
72 #define sync_cond (*GET_GSTREAMER_WSD_VAR_NAME(sync_cond,gstcheck,g)()) |
|
73 #else |
|
74 EXPORT_C GCond *sync_cond = NULL; |
|
75 #endif |
|
76 |
|
77 |
|
78 //GList *buffers = NULL; |
|
79 #if EMULATOR |
|
80 GET_GLOBAL_VAR_FROM_TLS(buffers,gstcheck,GList*) |
|
81 #define buffers (*GET_GSTREAMER_WSD_VAR_NAME(buffers,gstcheck,g)()) |
|
82 #else |
|
83 EXPORT_C GList *buffers = NULL; |
|
84 #endif |
|
85 |
|
86 //GMutex *check_mutex = NULL; |
|
87 #if EMULATOR |
|
88 GET_GLOBAL_VAR_FROM_TLS(check_mutex,gstcheck,GMutex *) |
|
89 #define check_mutex (*GET_GSTREAMER_WSD_VAR_NAME(check_mutex,gstcheck,g)()) |
|
90 #else |
|
91 EXPORT_C GMutex *check_mutex = NULL; |
|
92 #endif |
|
93 |
|
94 //GCond *check_cond = NULL; |
|
95 #if EMULATOR |
|
96 GET_GLOBAL_VAR_FROM_TLS(check_cond,gstcheck,GCond *) |
|
97 #define check_cond (*GET_GSTREAMER_WSD_VAR_NAME(check_cond,gstcheck,g)()) |
|
98 #else |
|
99 EXPORT_C GCond *check_cond = NULL; |
|
100 #endif |
|
101 |
|
102 |
|
103 /* FIXME 0.11: shouldn't _gst_check_debug be static? Not used anywhere */ |
|
104 EXPORT_C gboolean _gst_check_debug = FALSE; |
|
105 #if EMULATOR |
|
106 static GET_GLOBAL_VAR_FROM_TLS(raised_critical,gstcheck,gboolean) |
|
107 #define _gst_check_raised_critical (*GET_GSTREAMER_WSD_VAR_NAME(raised_critical,gstcheck,g)()) |
|
108 #else |
|
109 EXPORT_C gboolean _gst_check_raised_critical = FALSE; |
|
110 #endif |
|
111 //gboolean _gst_check_raised_warning = FALSE; |
|
112 #if EMULATOR |
|
113 static GET_GLOBAL_VAR_FROM_TLS(raised_warning,gstcheck,gboolean) |
|
114 #define _gst_check_raised_warning (*GET_GSTREAMER_WSD_VAR_NAME(raised_warning,gstcheck,g)()) |
|
115 #else |
|
116 EXPORT_C gboolean _gst_check_raised_warning = FALSE; |
|
117 #endif |
|
118 //gboolean _gst_check_expecting_log = FALSE; |
|
119 #if EMULATOR |
|
120 static GET_GLOBAL_VAR_FROM_TLS(expecting_log,gstcheck,gboolean) |
|
121 #define _gst_check_expecting_log (*GET_GSTREAMER_WSD_VAR_NAME(expecting_log,gstcheck,g)()) |
|
122 #else |
|
123 EXPORT_C gboolean _gst_check_expecting_log = FALSE; |
|
124 #endif |
|
125 |
|
126 //gboolean _gst_check_expecting_log = FALSE; |
|
127 #if EMULATOR |
|
128 static GET_GLOBAL_VAR_FROM_TLS(threads_running,gstcheck,gboolean) |
|
129 #define _gst_check_threads_running (*GET_GSTREAMER_WSD_VAR_NAME(threads_running,gstcheck,g)()) |
|
130 #else |
|
131 EXPORT_C gboolean _gst_check_threads_running = FALSE; |
|
132 #endif |
|
133 |
|
134 |
|
135 static void gst_check_log_message_func(const gchar * log_domain, GLogLevelFlags log_level, const gchar * message, gpointer user_data) |
|
136 { |
|
137 if (_gst_check_debug) { |
|
138 g_print ("%s", message); |
|
139 } |
|
140 } |
|
141 |
|
142 |
|
143 static void gst_check_log_critical_func |
|
144 (const gchar * log_domain, GLogLevelFlags log_level, |
|
145 const gchar * message, gpointer user_data) |
|
146 { |
|
147 if (!_gst_check_expecting_log) { |
|
148 g_print ("\n\nUnexpected critical/warning: %s\n", message); |
|
149 fail ("Unexpected critical/warning: %s", message); |
|
150 } |
|
151 |
|
152 if (_gst_check_debug) { |
|
153 g_print ("\nExpected critical/warning: %s\n", message); |
|
154 } |
|
155 |
|
156 if (log_level & G_LOG_LEVEL_CRITICAL) |
|
157 _gst_check_raised_critical = TRUE; |
|
158 if (log_level & G_LOG_LEVEL_WARNING) |
|
159 _gst_check_raised_warning = TRUE; |
|
160 } |
|
161 |
|
162 /* initialize GStreamer testing */ |
|
163 #ifdef __SYMBIAN32__ |
|
164 EXPORT_C |
|
165 #endif |
|
166 |
|
167 void |
|
168 gst_check_init (int *argc, char **argv[]) |
|
169 { |
|
170 gst_init (argc, argv); |
|
171 |
|
172 GST_DEBUG_CATEGORY_INIT (check_debug, "check", 0, "check regression tests"); |
|
173 |
|
174 if (g_getenv ("GST_TEST_DEBUG")) |
|
175 _gst_check_debug = TRUE; |
|
176 |
|
177 g_log_set_handler (NULL, G_LOG_LEVEL_MESSAGE, gst_check_log_message_func, |
|
178 NULL); |
|
179 g_log_set_handler (NULL, G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING, |
|
180 gst_check_log_critical_func, NULL); |
|
181 g_log_set_handler ("GStreamer", G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING, |
|
182 gst_check_log_critical_func, NULL); |
|
183 g_log_set_handler ("GLib-GObject", G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING, |
|
184 gst_check_log_critical_func, NULL); |
|
185 g_log_set_handler ("Gst-Phonon", G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING, |
|
186 gst_check_log_critical_func, NULL); |
|
187 |
|
188 check_cond = g_cond_new (); |
|
189 check_mutex = g_mutex_new (); |
|
190 } |
|
191 |
|
192 /* message checking */ |
|
193 #ifdef __SYMBIAN32__ |
|
194 EXPORT_C |
|
195 #endif |
|
196 |
|
197 void |
|
198 gst_check_message_error (GstMessage * message, GstMessageType type, |
|
199 GQuark domain, gint code) |
|
200 { |
|
201 GError *error; |
|
202 gchar *debug; |
|
203 |
|
204 fail_unless (GST_MESSAGE_TYPE (message) == type, |
|
205 "message is of type %s instead of expected type %s", |
|
206 gst_message_type_get_name (GST_MESSAGE_TYPE (message)), |
|
207 gst_message_type_get_name (type)); |
|
208 gst_message_parse_error (message, &error, &debug); |
|
209 fail_unless_equals_int (error->domain, domain); |
|
210 fail_unless_equals_int (error->code, code); |
|
211 g_error_free (error); |
|
212 g_free (debug); |
|
213 } |
|
214 |
|
215 /* helper functions */ |
|
216 #ifdef __SYMBIAN32__ |
|
217 EXPORT_C |
|
218 #endif |
|
219 |
|
220 GstFlowReturn |
|
221 gst_check_chain_func (GstPad * pad, GstBuffer * buffer) |
|
222 { |
|
223 GST_DEBUG ("chain_func: received buffer %p", buffer); |
|
224 buffers = g_list_append (buffers, buffer); |
|
225 |
|
226 g_mutex_lock (check_mutex); |
|
227 g_cond_signal (check_cond); |
|
228 g_mutex_unlock (check_mutex); |
|
229 |
|
230 return GST_FLOW_OK; |
|
231 } |
|
232 |
|
233 /* setup an element for a filter test with mysrcpad and mysinkpad */ |
|
234 #ifdef __SYMBIAN32__ |
|
235 EXPORT_C |
|
236 #endif |
|
237 |
|
238 GstElement * |
|
239 gst_check_setup_element (const gchar * factory) |
|
240 { |
|
241 GstElement *element; |
|
242 |
|
243 GST_DEBUG ("setup_element"); |
|
244 |
|
245 element = gst_element_factory_make (factory, factory); |
|
246 fail_if (element == NULL, "Could not create a '%s' element", factory); |
|
247 ASSERT_OBJECT_REFCOUNT (element, factory, 1); |
|
248 return element; |
|
249 } |
|
250 #ifdef __SYMBIAN32__ |
|
251 EXPORT_C |
|
252 #endif |
|
253 |
|
254 |
|
255 void |
|
256 gst_check_teardown_element (GstElement * element) |
|
257 { |
|
258 GST_DEBUG ("teardown_element"); |
|
259 |
|
260 fail_unless (gst_element_set_state (element, GST_STATE_NULL) == |
|
261 GST_STATE_CHANGE_SUCCESS, "could not set to null"); |
|
262 ASSERT_OBJECT_REFCOUNT (element, "element", 1); |
|
263 gst_object_unref (element); |
|
264 } |
|
265 |
|
266 /* FIXME: set_caps isn't that useful |
|
267 */ |
|
268 #ifdef __SYMBIAN32__ |
|
269 EXPORT_C |
|
270 #endif |
|
271 |
|
272 GstPad * |
|
273 gst_check_setup_src_pad (GstElement * element, |
|
274 GstStaticPadTemplate * template, GstCaps * caps) |
|
275 { |
|
276 GstPad *srcpad, *sinkpad; |
|
277 |
|
278 /* sending pad */ |
|
279 srcpad = gst_pad_new_from_static_template (template, "src"); |
|
280 GST_DEBUG_OBJECT (element, "setting up sending pad %p", srcpad); |
|
281 fail_if (srcpad == NULL, "Could not create a srcpad"); |
|
282 ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 1); |
|
283 |
|
284 sinkpad = gst_element_get_pad (element, "sink"); |
|
285 fail_if (sinkpad == NULL, "Could not get sink pad from %s", |
|
286 GST_ELEMENT_NAME (element)); |
|
287 ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 2); |
|
288 if (caps) |
|
289 fail_unless (gst_pad_set_caps (srcpad, caps), "could not set caps on pad"); |
|
290 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK, |
|
291 "Could not link source and %s sink pads", GST_ELEMENT_NAME (element)); |
|
292 gst_object_unref (sinkpad); /* because we got it higher up */ |
|
293 ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 1); |
|
294 |
|
295 return srcpad; |
|
296 } |
|
297 #ifdef __SYMBIAN32__ |
|
298 EXPORT_C |
|
299 #endif |
|
300 |
|
301 |
|
302 void |
|
303 gst_check_teardown_src_pad (GstElement * element) |
|
304 { |
|
305 GstPad *srcpad, *sinkpad; |
|
306 |
|
307 /* clean up floating src pad */ |
|
308 sinkpad = gst_element_get_pad (element, "sink"); |
|
309 ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 2); |
|
310 srcpad = gst_pad_get_peer (sinkpad); |
|
311 |
|
312 gst_pad_unlink (srcpad, sinkpad); |
|
313 |
|
314 /* caps could have been set, make sure they get unset */ |
|
315 gst_pad_set_caps (srcpad, NULL); |
|
316 |
|
317 /* pad refs held by both creator and this function (through _get) */ |
|
318 ASSERT_OBJECT_REFCOUNT (sinkpad, "element sinkpad", 2); |
|
319 gst_object_unref (sinkpad); |
|
320 /* one more ref is held by element itself */ |
|
321 |
|
322 /* pad refs held by both creator and this function (through _get_peer) */ |
|
323 ASSERT_OBJECT_REFCOUNT (srcpad, "check srcpad", 2); |
|
324 gst_object_unref (srcpad); |
|
325 gst_object_unref (srcpad); |
|
326 } |
|
327 |
|
328 /* FIXME: set_caps isn't that useful; might want to check if fixed, |
|
329 * then use set_use_fixed or somesuch */ |
|
330 #ifdef __SYMBIAN32__ |
|
331 EXPORT_C |
|
332 #endif |
|
333 |
|
334 GstPad * |
|
335 gst_check_setup_sink_pad (GstElement * element, GstStaticPadTemplate * template, |
|
336 GstCaps * caps) |
|
337 { |
|
338 GstPad *srcpad, *sinkpad; |
|
339 |
|
340 /* receiving pad */ |
|
341 sinkpad = gst_pad_new_from_static_template (template, "sink"); |
|
342 GST_DEBUG_OBJECT (element, "setting up receiving pad %p", sinkpad); |
|
343 fail_if (sinkpad == NULL, "Could not create a sinkpad"); |
|
344 |
|
345 srcpad = gst_element_get_pad (element, "src"); |
|
346 fail_if (srcpad == NULL, "Could not get source pad from %s", |
|
347 GST_ELEMENT_NAME (element)); |
|
348 if (caps) |
|
349 fail_unless (gst_pad_set_caps (sinkpad, caps), "Could not set pad caps"); |
|
350 gst_pad_set_chain_function (sinkpad, gst_check_chain_func); |
|
351 |
|
352 GST_DEBUG_OBJECT (element, "Linking element src pad and receiving sink pad"); |
|
353 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK, |
|
354 "Could not link %s source and sink pads", GST_ELEMENT_NAME (element)); |
|
355 gst_object_unref (srcpad); /* because we got it higher up */ |
|
356 ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 1); |
|
357 |
|
358 GST_DEBUG_OBJECT (element, "set up srcpad, refcount is 1"); |
|
359 return sinkpad; |
|
360 } |
|
361 #ifdef __SYMBIAN32__ |
|
362 EXPORT_C |
|
363 #endif |
|
364 |
|
365 |
|
366 void |
|
367 gst_check_teardown_sink_pad (GstElement * element) |
|
368 { |
|
369 GstPad *srcpad, *sinkpad; |
|
370 |
|
371 /* clean up floating sink pad */ |
|
372 srcpad = gst_element_get_pad (element, "src"); |
|
373 sinkpad = gst_pad_get_peer (srcpad); |
|
374 |
|
375 gst_pad_unlink (srcpad, sinkpad); |
|
376 |
|
377 /* pad refs held by both creator and this function (through _get_pad) */ |
|
378 ASSERT_OBJECT_REFCOUNT (srcpad, "element srcpad", 2); |
|
379 gst_object_unref (srcpad); |
|
380 /* one more ref is held by element itself */ |
|
381 |
|
382 /* pad refs held by both creator and this function (through _get_peer) */ |
|
383 ASSERT_OBJECT_REFCOUNT (sinkpad, "check sinkpad", 2); |
|
384 gst_object_unref (sinkpad); |
|
385 gst_object_unref (sinkpad); |
|
386 } |
|
387 |
|
388 /** |
|
389 * gst_check_drop_buffers: |
|
390 * |
|
391 * Unref and remove all buffers that are in the global @buffers GList, |
|
392 * emptying the list. |
|
393 * |
|
394 * Since: 0.10.18 |
|
395 */ |
|
396 #ifdef __SYMBIAN32__ |
|
397 EXPORT_C |
|
398 #endif |
|
399 |
|
400 void |
|
401 gst_check_drop_buffers (void) |
|
402 { |
|
403 GstBuffer *temp_buffer; |
|
404 |
|
405 while (g_list_length (buffers)) { |
|
406 temp_buffer = GST_BUFFER (buffers->data); |
|
407 gst_buffer_unref (temp_buffer); |
|
408 buffers = g_list_delete_link (buffers, buffers); |
|
409 } |
|
410 } |
|
411 |
|
412 /** |
|
413 * gst_check_caps_equal: |
|
414 * |
|
415 * @caps1: first caps to compare |
|
416 * @caps2: second caps to compare |
|
417 * |
|
418 * Compare two caps with gst_caps_is_equal and fail unless they are |
|
419 * equal. |
|
420 * |
|
421 * Since: 0.10.18 |
|
422 */ |
|
423 #ifdef __SYMBIAN32__ |
|
424 EXPORT_C |
|
425 #endif |
|
426 |
|
427 void |
|
428 gst_check_caps_equal (GstCaps * caps1, GstCaps * caps2) |
|
429 { |
|
430 gchar *name1 = gst_caps_to_string (caps1); |
|
431 gchar *name2 = gst_caps_to_string (caps2); |
|
432 |
|
433 fail_unless (gst_caps_is_equal (caps1, caps2), |
|
434 "caps ('%s') is not equal to caps ('%s')", name1, name2); |
|
435 g_free (name1); |
|
436 g_free (name2); |
|
437 } |
|
438 |
|
439 /** |
|
440 * gst_check_element_push_buffer: |
|
441 * @element: name of the element that needs to be created |
|
442 * @buffer_in: a list of buffers that needs to be puched to the element |
|
443 * @buffer_out: a list of buffers that we expect from the element |
|
444 * @last_flow_return: the last buffer push needs to give this GstFlowReturn |
|
445 * |
|
446 * Create an @element with the factory with the name and push the buffers in |
|
447 * @buffer_in to this element. The element should create the buffers equal to |
|
448 * the buffers in @buffer_out. We only check the caps, size and the data of the |
|
449 * buffers. This function unrefs the buffers in the two lists. |
|
450 * The last_flow_return parameter indicates the expected flow return value from |
|
451 * pushing the final buffer in the list. |
|
452 * This can be used to set up a test which pushes some buffers and then an |
|
453 * invalid buffer, when the final buffer is expected to fail, for example. |
|
454 * |
|
455 * Since: 0.10.18 |
|
456 */ |
|
457 #ifdef __SYMBIAN32__ |
|
458 EXPORT_C |
|
459 #endif |
|
460 |
|
461 void |
|
462 gst_check_element_push_buffer_list (const gchar * element_name, |
|
463 GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return) |
|
464 { |
|
465 GstCaps *sink_caps; |
|
466 GstCaps *src_caps = NULL; |
|
467 GstElement *element; |
|
468 GstPad *pad_peer; |
|
469 GstPad *sink_pad = NULL; |
|
470 GstPad *src_pad; |
|
471 GstBuffer *buffer; |
|
472 |
|
473 /* check that there are no buffers waiting */ |
|
474 gst_check_drop_buffers (); |
|
475 /* create the element */ |
|
476 element = gst_check_setup_element (element_name); |
|
477 fail_if (element == NULL, "failed to create the element '%s'", element_name); |
|
478 fail_unless (GST_IS_ELEMENT (element), "the element is no element"); |
|
479 /* create the src pad */ |
|
480 buffer = GST_BUFFER (buffer_in->data); |
|
481 |
|
482 fail_unless (GST_IS_BUFFER (buffer), "There should be a buffer in buffer_in"); |
|
483 src_caps = GST_BUFFER_CAPS (buffer); |
|
484 src_pad = gst_pad_new (NULL, GST_PAD_SRC); |
|
485 gst_pad_set_caps (src_pad, src_caps); |
|
486 pad_peer = gst_element_get_pad (element, "sink"); |
|
487 fail_if (pad_peer == NULL, ""); |
|
488 fail_unless (gst_pad_link (src_pad, pad_peer) == GST_PAD_LINK_OK, |
|
489 "Could not link source and %s sink pads", GST_ELEMENT_NAME (element)); |
|
490 gst_object_unref (pad_peer); |
|
491 /* activate the pad */ |
|
492 gst_pad_set_active (src_pad, TRUE); |
|
493 GST_DEBUG ("src pad activated"); |
|
494 /* don't create the sink_pad if there is no buffer_out list */ |
|
495 if (buffer_out != NULL) { |
|
496 gchar *temp; |
|
497 |
|
498 GST_DEBUG ("buffer out detected, creating the sink pad"); |
|
499 /* get the sink caps */ |
|
500 sink_caps = (GstCaps*)GST_BUFFER_CAPS (GST_BUFFER (buffer_out->data)); |
|
501 fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps"); |
|
502 temp = gst_caps_to_string (sink_caps); |
|
503 |
|
504 GST_DEBUG ("sink caps requested by buffer out: '%s'", temp); |
|
505 g_free (temp); |
|
506 fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps"); |
|
507 /* get the sink pad */ |
|
508 sink_pad = gst_pad_new ('\0', GST_PAD_SINK); |
|
509 fail_unless (GST_IS_PAD (sink_pad), ""); |
|
510 gst_pad_set_caps (sink_pad, sink_caps); |
|
511 /* get the peer pad */ |
|
512 pad_peer = gst_element_get_pad (element, "src"); |
|
513 fail_unless (gst_pad_link (pad_peer, sink_pad) == GST_PAD_LINK_OK, |
|
514 "Could not link sink and %s source pads", GST_ELEMENT_NAME (element)); |
|
515 gst_object_unref (pad_peer); |
|
516 /* configure the sink pad */ |
|
517 gst_pad_set_chain_function (sink_pad, gst_check_chain_func); |
|
518 gst_pad_set_active (sink_pad, TRUE); |
|
519 } |
|
520 fail_unless (gst_element_set_state (element, |
|
521 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, |
|
522 "could not set to playing"); |
|
523 /* push all the buffers in the buffer_in list */ |
|
524 fail_unless (g_list_length (buffer_in) > 0, "the buffer_in list is empty"); |
|
525 while (g_list_length (buffer_in) > 0) { |
|
526 GstBuffer *next_buffer = (GstBuffer*)GST_BUFFER (buffer_in->data); |
|
527 |
|
528 fail_unless (GST_IS_BUFFER (next_buffer), |
|
529 "data in buffer_in should be a buffer"); |
|
530 /* remove the buffer from the list */ |
|
531 buffer_in = g_list_remove (buffer_in, next_buffer); |
|
532 if (g_list_length (buffer_in) == 0) { |
|
533 fail_unless (gst_pad_push (src_pad, next_buffer) == last_flow_return, |
|
534 "we expect something else from the last buffer"); |
|
535 } else { |
|
536 fail_unless (gst_pad_push (src_pad, next_buffer) == GST_FLOW_OK, |
|
537 "Failed to push buffer in"); |
|
538 } |
|
539 } |
|
540 fail_unless (gst_element_set_state (element, |
|
541 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null"); |
|
542 /* check that there is a buffer out */ |
|
543 fail_unless (g_list_length (buffers) == g_list_length (buffer_out), |
|
544 "We expected %d buffers, but there are %d buffers", |
|
545 g_list_length (buffer_out), g_list_length (buffers)); |
|
546 while (g_list_length (buffers) > 0) { |
|
547 GstBuffer *new = (GstBuffer*)GST_BUFFER (buffers->data); |
|
548 GstBuffer *orig = (GstBuffer*)GST_BUFFER (buffer_out->data); |
|
549 |
|
550 /* remove the buffers */ |
|
551 buffers = g_list_remove (buffers, new); |
|
552 buffer_out = g_list_remove (buffer_out, orig); |
|
553 fail_unless (GST_BUFFER_SIZE (orig) == GST_BUFFER_SIZE (new), |
|
554 "size of the buffers are not the same"); |
|
555 fail_unless (memcmp ((const void*)GST_BUFFER_DATA (orig), (const void*)GST_BUFFER_DATA (new), |
|
556 GST_BUFFER_SIZE (new)) == 0, "data is not the same"); |
|
557 gst_check_caps_equal ((GstCaps *)GST_BUFFER_CAPS (orig), (GstCaps *)GST_BUFFER_CAPS (new)); |
|
558 gst_buffer_unref (new); |
|
559 gst_buffer_unref (orig); |
|
560 } |
|
561 /* teardown the element and pads */ |
|
562 gst_pad_set_active (src_pad, FALSE); |
|
563 gst_check_teardown_src_pad (element); |
|
564 gst_pad_set_active (sink_pad, FALSE); |
|
565 gst_check_teardown_sink_pad (element); |
|
566 gst_check_teardown_element (element); |
|
567 } |
|
568 |
|
569 /** |
|
570 * gst_check_element_push_buffer: |
|
571 * @element: name of the element that needs to be created |
|
572 * @buffer_in: push this buffer to the element |
|
573 * @buffer_out: compare the result with this buffer |
|
574 * |
|
575 * Create an @element with the factory with the name and push the |
|
576 * @buffer_in to this element. The element should create one buffer |
|
577 * and this will be compared with @buffer_out. We only check the caps |
|
578 * and the data of the buffers. This function unrefs the buffers. |
|
579 * |
|
580 * Since: 0.10.18 |
|
581 */ |
|
582 #ifdef __SYMBIAN32__ |
|
583 EXPORT_C |
|
584 #endif |
|
585 |
|
586 void |
|
587 gst_check_element_push_buffer (const gchar * element_name, |
|
588 GstBuffer * buffer_in, GstBuffer * buffer_out) |
|
589 { |
|
590 GList *in = NULL; |
|
591 GList *out = NULL; |
|
592 |
|
593 in = g_list_append (in, buffer_in); |
|
594 out = g_list_append (out, buffer_out); |
|
595 |
|
596 gst_check_element_push_buffer_list (element_name, in, out, GST_FLOW_OK); |
|
597 |
|
598 g_list_free (in); |
|
599 g_list_free (out); |
|
600 } |
|
601 #ifdef __SYMBIAN32__ |
|
602 EXPORT_C |
|
603 #endif |
|
604 |
|
605 |
|
606 void |
|
607 gst_check_abi_list (GstCheckABIStruct list[], gboolean have_abi_sizes) |
|
608 { |
|
609 if (have_abi_sizes) { |
|
610 gboolean ok = TRUE; |
|
611 gint i; |
|
612 |
|
613 for (i = 0; list[i].name; i++) { |
|
614 if (list[i].size != list[i].abi_size) { |
|
615 ok = FALSE; |
|
616 g_print ("sizeof(%s) is %d, expected %d\n", |
|
617 list[i].name, list[i].size, list[i].abi_size); |
|
618 } |
|
619 } |
|
620 fail_unless (ok, "failed ABI check"); |
|
621 } else { |
|
622 const gchar *fn; |
|
623 |
|
624 if ((fn = g_getenv ("GST_ABI"))) { |
|
625 GError *err = NULL; |
|
626 GString *s; |
|
627 gint i; |
|
628 |
|
629 s = g_string_new ("\nGstCheckABIStruct list[] = {\n"); |
|
630 for (i = 0; list[i].name; i++) { |
|
631 g_string_append_printf (s, " {\"%s\", sizeof (%s), %d},\n", |
|
632 list[i].name, list[i].name, list[i].size); |
|
633 } |
|
634 g_string_append (s, " {NULL, 0, 0}\n"); |
|
635 g_string_append (s, "};\n"); |
|
636 if (!g_file_set_contents (fn, s->str, s->len, &err)) { |
|
637 g_print ("%s", s->str); |
|
638 g_printerr ("\nFailed to write ABI information: %s\n", err->message); |
|
639 } else { |
|
640 g_print ("\nWrote ABI information to '%s'.\n", fn); |
|
641 } |
|
642 g_string_free (s, TRUE); |
|
643 } else { |
|
644 g_print ("No structure size list was generated for this architecture.\n"); |
|
645 g_print ("Run with GST_ABI environment variable set to output header.\n"); |
|
646 } |
|
647 } |
|
648 } |
|
649 |
|
650 /* |
|
651 gint |
|
652 gst_check_run_suite (Suite * suite, const gchar * name, const gchar * fname) |
|
653 { |
|
654 gint nf; |
|
655 |
|
656 SRunner *sr = srunner_create (suite); |
|
657 |
|
658 if (g_getenv ("GST_CHECK_XML")) { |
|
659 // how lucky we are to have __FILE__ end in .c |
|
660 gchar *xmlfilename = g_strdup_printf ("%sheck.xml", fname); |
|
661 |
|
662 srunner_set_xml (sr, xmlfilename); |
|
663 } |
|
664 |
|
665 srunner_run_all (sr, CK_NORMAL); |
|
666 nf = srunner_ntests_failed (sr); |
|
667 srunner_free (sr); |
|
668 return nf; |
|
669 } |
|
670 */ |
|
671 #ifdef __SYMBIAN32__ |
|
672 EXPORT_C |
|
673 #endif |
|
674 |
|
675 gboolean |
|
676 _gst_check_run_test_func (const gchar * func_name) |
|
677 { |
|
678 const gchar *gst_checks; |
|
679 gboolean res = FALSE; |
|
680 gchar **funcs, **f; |
|
681 |
|
682 gst_checks = g_getenv ("GST_CHECKS"); |
|
683 |
|
684 /* no filter specified => run all checks */ |
|
685 if (gst_checks == NULL || *gst_checks == '\0') |
|
686 return TRUE; |
|
687 |
|
688 /* only run specified functions */ |
|
689 funcs = g_strsplit (gst_checks, ",", -1); |
|
690 for (f = funcs; f != NULL && *f != NULL; ++f) { |
|
691 if (strcmp (*f, func_name) == 0) { |
|
692 res = TRUE; |
|
693 break; |
|
694 } |
|
695 } |
|
696 g_strfreev (funcs); |
|
697 return res; |
|
698 } |