gstreamer_core/libs/gst/check/gstcheck.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     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 }