harness: misc bugfixes
[platform/upstream/gstreamer.git] / libs / gst / check / gstharness.c
1 /* GstHarness - A test-harness for GStreamer testing
2  *
3  * Copyright (C) 2012-2015 Pexip <pexip.com>
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 /**
22  * SECTION:gstharness
23  * @short_description: A test-harness for writing GStreamer unit tests
24  * @see_also: #GstTestClock,\
25  *
26  * #GstHarness is ment to make writing unit test for GStreamer much easier.
27  * It can be though of as a way of treating a #GstElement as a black box,
28  * deterministially feeding it data, and controlling what data it outputs.
29  *
30  * The basic structure of #GstHarness is two "floating" #GstPads, that connects
31  * to the harnessed #GstElement src and sink #GstPads like so:
32  *
33  * <programlisting>
34  *           __________________________
35  *  _____   |  _____            _____  |   _____
36  * |     |  | |     |          |     | |  |     |
37  * | src |--+-| sink|  Element | src |-+--| sink|
38  * |_____|  | |_____|          |_____| |  |_____|
39  *          |__________________________|
40  *
41  * </programlisting>
42  *
43  * With this, you can now simulate any environment the #GstElement might find
44  * itself in. By specifying the #GstCaps of the harness #GstPads, using
45  * functions like gst_harness_set_src_caps or gst_harness_set_sink_caps_str,
46  * you can test how the #GstElement interacts with different capssets.
47  *
48  * Your harnessed #GstElement can of course also be a bin, and using
49  * gst_harness_new_parse supporting standard gst-launch syntax, you can
50  * easily test a whole pipeline instead of just one element.
51  *
52  * You can then go on to push #GstBuffers and #GstEvents on to the srcpad,
53  * using functions like gst_harness_push and gst_harness_push_event, and
54  * then pull them out to examine them with gst_harness_pull and
55  * gst_harness_pull_event.
56  *
57  * <example>
58  * <title>A simple buffer-in buffer-out example</title>
59  *   <programlisting language="c">
60  *   #include &lt;gst/gst.h&gt;
61  *   #include &lt;gst/check/gstharness.h&gt;
62  *   GstHarness *h;
63  *   GstBuffer *in_buf;
64  *   GstBuffer *out_buf;
65  *
66  *   // attach the harness to the src and sink pad of GstQueue
67  *   h = gst_harness_new ("queue");
68  *
69  *   // we must specify a caps before pushing buffers
70  *   gst_harness_set_src_caps_str (h, "mycaps");
71  *
72  *   // create a buffer of size 42
73  *   in_buf = gst_harness_create_buffer (h, 42);
74  *
75  *   // push the buffer into the queue
76  *   gst_harness_push (h, in_buf);
77  *
78  *   // pull the buffer from the queue
79  *   out_buf = gst_harness_pull (h);
80  *
81  *   // validate the buffer in is the same as buffer out
82  *   fail_unless (in_buf == out_buf);
83  *
84  *   // cleanup
85  *   gst_buffer_unref (out_buf);
86  *   gst_harness_teardown (h);
87  *
88  *   </programlisting>
89  * </example>
90  *
91  * Another main feature of the #GstHarness is its integration with the
92  * #GstTestClock. Operating the #GstTestClock can be very challenging, but
93  * #GstHarness simplifies some of the most desired actions a lot, like wanting
94  * to manually advance the clock while at the same time releasing a #GstClockID
95  * that is waiting, with functions like gst_harness_crank_single_clock_wait.
96  *
97  * #GstHarness also supports sub-harnesses, as a way of generating and
98  * validating data. A sub-harness is another #GstHarness that is managed by
99  * the "parent" harness, and can either be created by using the standard
100  * gst_harness_new type functions directly on the (GstHarness *)->src_harness,
101  * or using the much more convenient gst_harness_add_src or
102  * gst_harness_add_sink_parse. If you have a decoder-element you want to test,
103  * (like vp8dec) it can be very useful to add a src-harness with both a
104  * src-element (videotestsrc) and an encoder (vp8enc) to feed the decoder data
105  * with different configurations, by simply doing:
106  *
107  * <example>
108  * <programlisting language="c">
109  *   GstHarness * h = gst_harness_new (h, "vp8dec");
110  *   gst_harness_add_src_parse (h, "videotestsrc is-live=1 ! vp8enc", TRUE);
111  * </programlisting>
112  * </example>
113  *
114  * and then feeding it data with:
115  *
116  * <example>
117  * <programlisting language="c">
118  * gst_harness_push_from_src (h);
119  * </programlisting>
120  * </example>
121  *
122  */
123 #ifdef HAVE_CONFIG_H
124 #include "config.h"
125 #endif
126
127 /* we have code with side effects in asserts, so make sure they are active */
128 #ifdef G_DISABLE_ASSERT
129 #error "GstHarness must be compiled with G_DISABLE_ASSERT undefined"
130 #endif
131
132 #include "gstharness.h"
133
134 #include <stdio.h>
135 #include <string.h>
136 #include <math.h>
137
138 static void gst_harness_stress_free (GstHarnessThread * t);
139
140 #define HARNESS_KEY "harness"
141 #define HARNESS_REF "harness-ref"
142
143 static GstStaticPadTemplate hsrctemplate = GST_STATIC_PAD_TEMPLATE ("src",
144     GST_PAD_SRC,
145     GST_PAD_ALWAYS,
146     GST_STATIC_CAPS_ANY);
147 static GstStaticPadTemplate hsinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
148     GST_PAD_SINK,
149     GST_PAD_ALWAYS,
150     GST_STATIC_CAPS_ANY);
151
152 struct _GstHarnessPrivate
153 {
154   gchar *element_sinkpad_name;
155   gchar *element_srcpad_name;
156
157   GstCaps *src_caps;
158   GstCaps *sink_caps;
159
160   gboolean forwarding;
161   GstPad *sink_forward_pad;
162
163   volatile gint recv_buffers;
164   volatile gint recv_events;
165   volatile gint recv_upstream_events;
166
167   GAsyncQueue *buffer_queue;
168   GAsyncQueue *src_event_queue;
169   GAsyncQueue *sink_event_queue;
170
171   GstClockTime latency_min;
172   GstClockTime latency_max;
173   gboolean has_clock_wait;
174   gboolean drop_buffers;
175   GstClockTime last_push_ts;
176
177   GstBufferPool *pool;
178   GstAllocator *allocator;
179   GstAllocationParams allocation_params;
180   GstAllocator *propose_allocator;
181   GstAllocationParams propose_allocation_params;
182
183   gboolean blocking_push_mode;
184   GCond blocking_push_cond;
185   GMutex blocking_push_mutex;
186
187   GPtrArray *stress;
188 };
189
190 static GstFlowReturn
191 gst_harness_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
192 {
193   GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
194   GstHarnessPrivate *priv = h->priv;
195   (void) parent;
196   g_assert (h != NULL);
197   g_mutex_lock (&priv->blocking_push_mutex);
198   g_atomic_int_inc (&priv->recv_buffers);
199
200   if (priv->drop_buffers)
201     gst_buffer_unref (buffer);
202   else
203     g_async_queue_push (priv->buffer_queue, buffer);
204
205   if (priv->blocking_push_mode) {
206     g_cond_wait (&priv->blocking_push_cond, &priv->blocking_push_mutex);
207   }
208   g_mutex_unlock (&priv->blocking_push_mutex);
209
210   return GST_FLOW_OK;
211 }
212
213 static gboolean
214 gst_harness_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
215 {
216   GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
217   GstHarnessPrivate *priv = h->priv;
218   (void) parent;
219   g_assert (h != NULL);
220   g_atomic_int_inc (&priv->recv_upstream_events);
221   g_async_queue_push (priv->src_event_queue, event);
222   return TRUE;
223 }
224
225 static gboolean
226 gst_harness_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
227 {
228   GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
229   GstHarnessPrivate *priv = h->priv;
230   gboolean forward;
231
232   g_assert (h != NULL);
233   (void) parent;
234   g_atomic_int_inc (&priv->recv_events);
235
236   switch (GST_EVENT_TYPE (event)) {
237     case GST_EVENT_STREAM_START:
238     case GST_EVENT_CAPS:
239     case GST_EVENT_SEGMENT:
240       forward = TRUE;
241       break;
242     default:
243       forward = FALSE;
244       break;
245   }
246
247   if (priv->forwarding && forward && priv->sink_forward_pad) {
248     gst_pad_push_event (priv->sink_forward_pad, event);
249   } else {
250     g_async_queue_push (priv->sink_event_queue, event);
251   }
252
253   return TRUE;
254 }
255
256 static void
257 gst_harness_decide_allocation (GstHarness * h, GstCaps * caps)
258 {
259   GstHarnessPrivate *priv = h->priv;
260   GstQuery *query;
261   GstAllocator *allocator;
262   GstAllocationParams params;
263   GstBufferPool *pool = NULL;
264   guint size, min, max;
265
266   query = gst_query_new_allocation (caps, FALSE);
267   gst_pad_peer_query (h->srcpad, query);
268
269   if (gst_query_get_n_allocation_params (query) > 0) {
270     gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
271   } else {
272     allocator = NULL;
273     gst_allocation_params_init (&params);
274   }
275
276   if (gst_query_get_n_allocation_pools (query) > 0) {
277     gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
278 #if 0
279     /* Most elements create their own pools if pool == NULL. Not sure if we
280      * want to do that in the harness since we may want to test the pool
281      * implementation of the elements. Not creating a pool will however ignore
282      * the returned size. */
283     if (pool == NULL)
284       pool = gst_buffer_pool_new ();
285 #endif
286   } else {
287     pool = NULL;
288     size = min = max = 0;
289   }
290   gst_query_unref (query);
291
292   if (pool) {
293     GstStructure *config = gst_buffer_pool_get_config (pool);
294     gst_buffer_pool_config_set_params (config, caps, size, min, max);
295     gst_buffer_pool_config_set_allocator (config, allocator, &params);
296     gst_buffer_pool_set_config (pool, config);
297   }
298
299   if (pool != priv->pool) {
300     if (priv->pool != NULL)
301       gst_buffer_pool_set_active (priv->pool, FALSE);
302     if (pool)
303       gst_buffer_pool_set_active (pool, TRUE);
304   }
305
306   priv->allocation_params = params;
307   if (priv->allocator)
308     gst_object_unref (priv->allocator);
309   priv->allocator = allocator;
310   if (priv->pool)
311     gst_object_unref (priv->pool);
312   priv->pool = pool;
313 }
314
315 static void
316 gst_harness_negotiate (GstHarness * h)
317 {
318   GstCaps *caps;
319
320   caps = gst_pad_get_current_caps (h->srcpad);
321   if (caps != NULL) {
322     gst_harness_decide_allocation (h, caps);
323     gst_caps_unref (caps);
324   } else {
325     GST_FIXME_OBJECT (h, "Cannot negotiate allocation because caps is not set");
326   }
327 }
328
329 static gboolean
330 gst_harness_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
331 {
332   GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
333   GstHarnessPrivate *priv = h->priv;
334   gboolean res = TRUE;
335   g_assert (h != NULL);
336
337   // FIXME: forward all queries?
338
339   switch (GST_QUERY_TYPE (query)) {
340     case GST_QUERY_LATENCY:
341       gst_query_set_latency (query, TRUE, priv->latency_min, priv->latency_max);
342       break;
343     case GST_QUERY_CAPS:
344     {
345       GstCaps *caps, *filter = NULL;
346
347       if (priv->sink_caps) {
348         caps = gst_caps_ref (priv->sink_caps);
349       } else {
350         caps = gst_pad_get_pad_template_caps (pad);
351       }
352
353       gst_query_parse_caps (query, &filter);
354       if (filter != NULL) {
355         gst_caps_take (&caps,
356             gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST));
357       }
358
359       gst_query_set_caps_result (query, caps);
360       gst_caps_unref (caps);
361     }
362       break;
363     case GST_QUERY_ALLOCATION:
364     {
365       if (priv->forwarding && priv->sink_forward_pad != NULL) {
366         GstPad *peer = gst_pad_get_peer (priv->sink_forward_pad);
367         g_assert (peer != NULL);
368         res = gst_pad_query (peer, query);
369         gst_object_unref (peer);
370       } else {
371         GstCaps *caps;
372         gboolean need_pool;
373         guint size;
374
375         gst_query_parse_allocation (query, &caps, &need_pool);
376
377         /* FIXME: Can this be removed? */
378         size = gst_query_get_n_allocation_params (query);
379         g_assert_cmpuint (0, ==, size);
380         gst_query_add_allocation_param (query,
381             priv->propose_allocator, &priv->propose_allocation_params);
382
383         GST_DEBUG_OBJECT (pad, "proposing allocation %" GST_PTR_FORMAT,
384             priv->propose_allocator);
385       }
386       break;
387     }
388     default:
389       res = gst_pad_query_default (pad, parent, query);
390   }
391
392   return res;
393 }
394
395 static gboolean
396 gst_harness_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
397 {
398   GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
399   GstHarnessPrivate *priv = h->priv;
400   gboolean res = TRUE;
401   g_assert (h != NULL);
402
403   switch (GST_QUERY_TYPE (query)) {
404     case GST_QUERY_LATENCY:
405       gst_query_set_latency (query, TRUE, priv->latency_min, priv->latency_max);
406       break;
407     case GST_QUERY_CAPS:
408     {
409       GstCaps *caps, *filter = NULL;
410
411       if (priv->src_caps) {
412         caps = gst_caps_ref (priv->src_caps);
413       } else {
414         caps = gst_pad_get_pad_template_caps (pad);
415       }
416
417       gst_query_parse_caps (query, &filter);
418       if (filter != NULL) {
419         gst_caps_take (&caps,
420             gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST));
421       }
422
423       gst_query_set_caps_result (query, caps);
424       gst_caps_unref (caps);
425     }
426       break;
427     default:
428       res = gst_pad_query_default (pad, parent, query);
429   }
430   return res;
431 }
432
433 static void
434 gst_harness_element_ref (GstHarness * h)
435 {
436   guint *data = g_object_get_data (G_OBJECT (h->element), HARNESS_REF);
437   if (data == NULL) {
438     data = g_new0 (guint, 1);
439     *data = 1;
440     g_object_set_data_full (G_OBJECT (h->element), HARNESS_REF, data, g_free);
441   } else {
442     (*data)++;
443   }
444 }
445
446 static guint
447 gst_harness_element_unref (GstHarness * h)
448 {
449   guint *data = g_object_get_data (G_OBJECT (h->element), HARNESS_REF);
450   g_assert (data != NULL);
451   (*data)--;
452   return *data;
453 }
454
455 static void
456 gst_harness_link_element_srcpad (GstHarness * h,
457     const gchar * element_srcpad_name)
458 {
459   GstHarnessPrivate *priv = h->priv;
460   GstPad *srcpad = gst_element_get_static_pad (h->element,
461       element_srcpad_name);
462   GstPadLinkReturn link;
463   if (srcpad == NULL)
464     srcpad = gst_element_get_request_pad (h->element, element_srcpad_name);
465   g_assert (srcpad);
466   link = gst_pad_link (srcpad, h->sinkpad);
467   g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
468   g_free (priv->element_srcpad_name);
469   priv->element_srcpad_name = gst_pad_get_name (srcpad);
470
471   gst_object_unref (srcpad);
472 }
473
474 static void
475 gst_harness_link_element_sinkpad (GstHarness * h,
476     const gchar * element_sinkpad_name)
477 {
478   GstHarnessPrivate *priv = h->priv;
479   GstPad *sinkpad = gst_element_get_static_pad (h->element,
480       element_sinkpad_name);
481   GstPadLinkReturn link;
482   if (sinkpad == NULL)
483     sinkpad = gst_element_get_request_pad (h->element, element_sinkpad_name);
484   g_assert (sinkpad);
485   link = gst_pad_link (h->srcpad, sinkpad);
486   g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
487   g_free (priv->element_sinkpad_name);
488   priv->element_sinkpad_name = gst_pad_get_name (sinkpad);
489
490   gst_object_unref (sinkpad);
491 }
492
493 static void
494 gst_harness_setup_src_pad (GstHarness * h,
495     GstStaticPadTemplate * src_tmpl, const gchar * element_sinkpad_name)
496 {
497   GstHarnessPrivate *priv = h->priv;
498   g_assert (src_tmpl);
499   g_assert (h->srcpad == NULL);
500
501   priv->src_event_queue =
502       g_async_queue_new_full ((GDestroyNotify) gst_event_unref);
503
504   /* sending pad */
505   h->srcpad = gst_pad_new_from_static_template (src_tmpl, "src");
506   g_assert (h->srcpad);
507   g_object_set_data (G_OBJECT (h->srcpad), HARNESS_KEY, h);
508
509   gst_pad_set_query_function (h->srcpad, gst_harness_src_query);
510   gst_pad_set_event_function (h->srcpad, gst_harness_src_event);
511
512   gst_pad_set_active (h->srcpad, TRUE);
513
514   if (element_sinkpad_name)
515     gst_harness_link_element_sinkpad (h, element_sinkpad_name);
516 }
517
518 static void
519 gst_harness_setup_sink_pad (GstHarness * h,
520     GstStaticPadTemplate * sink_tmpl, const gchar * element_srcpad_name)
521 {
522   GstHarnessPrivate *priv = h->priv;
523   g_assert (sink_tmpl);
524   g_assert (h->sinkpad == NULL);
525
526   priv->buffer_queue = g_async_queue_new_full (
527       (GDestroyNotify) gst_buffer_unref);
528   priv->sink_event_queue = g_async_queue_new_full (
529       (GDestroyNotify) gst_event_unref);
530
531   /* receiving pad */
532   h->sinkpad = gst_pad_new_from_static_template (sink_tmpl, "sink");
533   g_assert (h->sinkpad);
534   g_object_set_data (G_OBJECT (h->sinkpad), HARNESS_KEY, h);
535
536   gst_pad_set_chain_function (h->sinkpad, gst_harness_chain);
537   gst_pad_set_query_function (h->sinkpad, gst_harness_sink_query);
538   gst_pad_set_event_function (h->sinkpad, gst_harness_sink_event);
539
540   gst_pad_set_active (h->sinkpad, TRUE);
541
542   if (element_srcpad_name)
543     gst_harness_link_element_srcpad (h, element_srcpad_name);
544 }
545
546 static void
547 check_element_type (GstElement * element, gboolean * has_sinkpad,
548     gboolean * has_srcpad)
549 {
550   GstElementClass *element_class = GST_ELEMENT_GET_CLASS (element);
551   const GList *tmpl_list;
552
553   *has_srcpad = element->numsrcpads > 0;
554   *has_sinkpad = element->numsinkpads > 0;
555
556   tmpl_list = gst_element_class_get_pad_template_list (element_class);
557
558   while (tmpl_list) {
559     GstPadTemplate *pad_tmpl = (GstPadTemplate *) tmpl_list->data;
560     tmpl_list = g_list_next (tmpl_list);
561     if (GST_PAD_TEMPLATE_DIRECTION (pad_tmpl) == GST_PAD_SRC)
562       *has_srcpad |= TRUE;
563     if (GST_PAD_TEMPLATE_DIRECTION (pad_tmpl) == GST_PAD_SINK)
564       *has_sinkpad |= TRUE;
565   }
566 }
567
568 static void
569 turn_async_and_sync_off (GstElement * element)
570 {
571   GObjectClass *class = G_OBJECT_GET_CLASS (element);
572   if (g_object_class_find_property (class, "async"))
573     g_object_set (element, "async", FALSE, NULL);
574   if (g_object_class_find_property (class, "sync"))
575     g_object_set (element, "sync", FALSE, NULL);
576 }
577
578 static gboolean
579 gst_pad_is_request_pad (GstPad * pad)
580 {
581   GstPadTemplate *temp;
582   gboolean is_request;
583
584   if (pad == NULL)
585     return FALSE;
586   temp = gst_pad_get_pad_template (pad);
587   if (temp == NULL)
588     return FALSE;
589   is_request = GST_PAD_TEMPLATE_PRESENCE (temp) == GST_PAD_REQUEST;
590   gst_object_unref (temp);
591   return is_request;
592 }
593
594 /**
595  * gst_harness_new_full: (skip)
596  * @element: a #GstElement to attach the harness to (transfer none)
597  * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad.
598  * %NULL will not create a harness srcpad.
599  * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
600  * sinkpad that is then linked to the harness srcpad. Can be a static or request
601  * or a sometimes pad that has been added. %NULL will not get/request a sinkpad
602  * from the element. (Like if the element is a src.)
603  * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad.
604  * %NULL will not create a harness sinkpad.
605  * @element_srcpad_name: (allow-none): a #gchar with the name of the element
606  * srcpad that is then linked to the harness sinkpad, similar to the
607  * @element_sinkpad_name.
608  *
609  * Creates a new harness.
610  *
611  * MT safe.
612  *
613  * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
614  * not be created
615  *
616  * Since: 1.6
617  */
618 GstHarness *
619 gst_harness_new_full (GstElement * element,
620     GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name,
621     GstStaticPadTemplate * hsink, const gchar * element_srcpad_name)
622 {
623   GstHarness *h;
624   GstHarnessPrivate *priv;
625   gboolean has_sinkpad, has_srcpad;
626
627   g_return_val_if_fail (element != NULL, NULL);
628
629   h = g_new0 (GstHarness, 1);
630   g_assert (h != NULL);
631   h->priv = g_new0 (GstHarnessPrivate, 1);
632   priv = h->priv;
633
634   GST_DEBUG_OBJECT (h, "about to create new harness %p", h);
635   h->element = gst_object_ref (element);
636   priv->last_push_ts = GST_CLOCK_TIME_NONE;
637   priv->latency_min = 0;
638   priv->latency_max = GST_CLOCK_TIME_NONE;
639   priv->drop_buffers = FALSE;
640
641   priv->propose_allocator = NULL;
642   gst_allocation_params_init (&priv->propose_allocation_params);
643
644   g_mutex_init (&priv->blocking_push_mutex);
645   g_cond_init (&priv->blocking_push_cond);
646
647   check_element_type (element, &has_sinkpad, &has_srcpad);
648
649   /* setup the loose srcpad linked to the element sinkpad */
650   if (has_sinkpad)
651     gst_harness_setup_src_pad (h, hsrc, element_sinkpad_name);
652
653   /* setup the loose sinkpad linked to the element srcpad */
654   if (has_srcpad)
655     gst_harness_setup_sink_pad (h, hsink, element_srcpad_name);
656
657   /* as a harness sink, we should not need sync and async */
658   if (has_sinkpad && !has_srcpad)
659     turn_async_and_sync_off (h->element);
660
661   if (h->srcpad != NULL) {
662     gboolean handled;
663     gchar *stream_id = g_strdup_printf ("%s-%p",
664         GST_OBJECT_NAME (h->element), h);
665     handled = gst_pad_push_event (h->srcpad,
666         gst_event_new_stream_start (stream_id));
667     g_assert (handled);
668     g_free (stream_id);
669   }
670
671   /* don't start sources, they start producing data! */
672   if (has_sinkpad)
673     gst_harness_play (h);
674
675   gst_harness_element_ref (h);
676
677   GST_DEBUG_OBJECT (h, "created new harness %p "
678       "with element_srcpad_name (%p, %s, %s) and element_sinkpad_name (%p, %s, %s)",
679       h, h->srcpad, GST_DEBUG_PAD_NAME (h->srcpad),
680       h->sinkpad, GST_DEBUG_PAD_NAME (h->sinkpad));
681
682   priv->stress = g_ptr_array_new_with_free_func (
683       (GDestroyNotify) gst_harness_stress_free);
684
685   /* we have forwarding on as a default */
686   gst_harness_set_forwarding (h, TRUE);
687
688   return h;
689 }
690
691 /**
692  * gst_harness_new_with_element: (skip)
693  * @element: a #GstElement to attach the harness to (transfer none)
694  * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
695  * sinkpad that is then linked to the harness srcpad. %NULL does not attach a
696  * sinkpad
697  * @element_srcpad_name: (allow-none): a #gchar with the name of the element
698  * srcpad that is then linked to the harness sinkpad. %NULL does not attach a
699  * srcpad
700  *
701  * Creates a new harness. Works in the same way as gst_harness_new_full, only
702  * that generic padtemplates are used for the harness src and sinkpads, which
703  * will be sufficient in most usecases.
704  *
705  * MT safe.
706  *
707  * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
708  * not be created
709  *
710  * Since: 1.6
711  */
712 GstHarness *
713 gst_harness_new_with_element (GstElement * element,
714     const gchar * element_sinkpad_name, const gchar * element_srcpad_name)
715 {
716   return gst_harness_new_full (element,
717       &hsrctemplate, element_sinkpad_name, &hsinktemplate, element_srcpad_name);
718 }
719
720 /**
721  * gst_harness_new_with_padnames: (skip)
722  * @element_name: a #gchar describing the #GstElement name
723  * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
724  * sinkpad that is then linked to the harness srcpad. %NULL does not attach a
725  * sinkpad
726  * @element_srcpad_name: (allow-none): a #gchar with the name of the element
727  * srcpad that is then linked to the harness sinkpad. %NULL does not attach a
728  * srcpad
729  *
730  * Creates a new harness. Works in the same way as gst_harness_new_with_element,
731  * except you specify the factoryname of the #GstElement
732  *
733  * MT safe.
734  *
735  * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
736  * not be created
737  *
738  * Since: 1.6
739  */
740 GstHarness *
741 gst_harness_new_with_padnames (const gchar * element_name,
742     const gchar * element_sinkpad_name, const gchar * element_srcpad_name)
743 {
744   GstHarness *h;
745   GstElement *element = gst_element_factory_make (element_name, NULL);
746   g_assert (element != NULL);
747
748   h = gst_harness_new_with_element (element, element_sinkpad_name,
749       element_srcpad_name);
750   gst_object_unref (element);
751   return h;
752 }
753
754 /**
755  * gst_harness_new_with_templates: (skip)
756  * @element_name: a #gchar describing the #GstElement name
757  * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad.
758  * %NULL will not create a harness srcpad.
759  * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad.
760  * %NULL will not create a harness sinkpad.
761  *
762  * Creates a new harness, like gst_harness_new_full, except it
763  * assumes the #GstElement sinkpad is named "sink" and srcpad is named "src"
764  *
765  * MT safe.
766  *
767  * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
768  * not be created
769  *
770  * Since: 1.6
771  */
772 GstHarness *
773 gst_harness_new_with_templates (const gchar * element_name,
774     GstStaticPadTemplate * hsrc, GstStaticPadTemplate * hsink)
775 {
776   GstHarness *h;
777   GstElement *element = gst_element_factory_make (element_name, NULL);
778   g_assert (element != NULL);
779
780   h = gst_harness_new_full (element, hsrc, "sink", hsink, "src");
781   gst_object_unref (element);
782   return h;
783 }
784
785 /**
786  * gst_harness_new: (skip)
787  * @element_name: a #gchar describing the #GstElement name
788  *
789  * Creates a new harness. Works like gst_harness_new_with_padnames, except it
790  * assumes the #GstElement sinkpad is named "sink" and srcpad is named "src"
791  *
792  * MT safe.
793  *
794  * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
795  * not be created
796  *
797  * Since: 1.6
798  */
799 GstHarness *
800 gst_harness_new (const gchar * element_name)
801 {
802   return gst_harness_new_with_padnames (element_name, "sink", "src");
803 }
804
805 /**
806  * gst_harness_new_parse: (skip)
807  * @launchline: a #gchar describing a gst-launch type line
808  *
809  * Creates a new harness, parsing the @launchline and putting that in a #GstBin,
810  * and then attches the harness to the bin.
811  *
812  * MT safe.
813  *
814  * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
815  * not be created
816  *
817  * Since: 1.6
818  */
819 GstHarness *
820 gst_harness_new_parse (const gchar * launchline)
821 {
822   GstHarness *h;
823   GstBin *bin;
824   gchar *desc;
825   GstPad *pad;
826   GstIterator *iter;
827   gboolean done = FALSE;
828
829   g_return_val_if_fail (launchline != NULL, NULL);
830
831   desc = g_strdup_printf ("bin.( %s )", launchline);
832   bin =
833       (GstBin *) gst_parse_launch_full (desc, NULL, GST_PARSE_FLAG_NONE, NULL);
834   g_free (desc);
835
836   if (G_UNLIKELY (bin == NULL))
837     return NULL;
838
839   /* find pads and ghost them if necessary */
840   if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC)) != NULL) {
841     gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("src", pad));
842     gst_object_unref (pad);
843   }
844   if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SINK)) != NULL) {
845     gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad));
846     gst_object_unref (pad);
847   }
848
849   iter = gst_bin_iterate_sinks (bin);
850   while (!done) {
851     GValue item = { 0, };
852
853     switch (gst_iterator_next (iter, &item)) {
854       case GST_ITERATOR_OK:
855         turn_async_and_sync_off (GST_ELEMENT (g_value_get_object (&item)));
856         g_value_reset (&item);
857         break;
858       case GST_ITERATOR_DONE:
859         done = TRUE;
860         break;
861       case GST_ITERATOR_RESYNC:
862         gst_iterator_resync (iter);
863         break;
864       case GST_ITERATOR_ERROR:
865         gst_object_unref (bin);
866         gst_iterator_free (iter);
867         g_return_val_if_reached (NULL);
868         break;
869     }
870   }
871   gst_iterator_free (iter);
872
873   h = gst_harness_new_full (GST_ELEMENT_CAST (bin),
874       &hsrctemplate, "sink", &hsinktemplate, "src");
875   gst_object_unref (bin);
876   return h;
877 }
878
879 /**
880  * gst_harness_teardown:
881  * @h: a #GstHarness
882  *
883  * Tears down a @GstHarness, freeing all resources allocated using it.
884  *
885  * MT safe.
886  *
887  * Since: 1.6
888  */
889 void
890 gst_harness_teardown (GstHarness * h)
891 {
892   GstHarnessPrivate *priv = h->priv;
893
894   if (priv->blocking_push_mode) {
895     g_mutex_lock (&priv->blocking_push_mutex);
896     priv->blocking_push_mode = FALSE;
897     g_cond_signal (&priv->blocking_push_cond);
898     g_mutex_unlock (&priv->blocking_push_mutex);
899   }
900
901   if (h->src_harness) {
902     gst_harness_teardown (h->src_harness);
903   }
904
905   if (h->sink_harness) {
906     gst_harness_teardown (h->sink_harness);
907   }
908
909   if (priv->src_caps)
910     gst_caps_unref (priv->src_caps);
911
912   if (priv->sink_caps)
913     gst_caps_unref (priv->sink_caps);
914
915   if (h->srcpad) {
916     if (gst_pad_is_request_pad (GST_PAD_PEER (h->srcpad)))
917       gst_element_release_request_pad (h->element, GST_PAD_PEER (h->srcpad));
918     g_free (priv->element_sinkpad_name);
919
920     gst_pad_set_active (h->srcpad, FALSE);
921     gst_object_unref (h->srcpad);
922
923     g_async_queue_unref (priv->src_event_queue);
924   }
925
926   if (h->sinkpad) {
927     if (gst_pad_is_request_pad (GST_PAD_PEER (h->sinkpad)))
928       gst_element_release_request_pad (h->element, GST_PAD_PEER (h->sinkpad));
929     g_free (priv->element_srcpad_name);
930
931     gst_pad_set_active (h->sinkpad, FALSE);
932     gst_object_unref (h->sinkpad);
933
934     g_async_queue_unref (priv->buffer_queue);
935     g_async_queue_unref (priv->sink_event_queue);
936   }
937
938   if (priv->sink_forward_pad)
939     gst_object_unref (priv->sink_forward_pad);
940
941   gst_object_replace ((GstObject **) & priv->propose_allocator, NULL);
942   gst_object_replace ((GstObject **) & priv->allocator, NULL);
943   gst_object_replace ((GstObject **) & priv->pool, NULL);
944
945   /* if we hold the last ref, set to NULL */
946   if (gst_harness_element_unref (h) == 0) {
947     gboolean state_change;
948     GstState state, pending;
949     state_change = gst_element_set_state (h->element, GST_STATE_NULL);
950     g_assert (state_change == GST_STATE_CHANGE_SUCCESS);
951     state_change = gst_element_get_state (h->element, &state, &pending, 0);
952     g_assert (state_change == GST_STATE_CHANGE_SUCCESS);
953     g_assert (state == GST_STATE_NULL);
954   }
955
956   g_cond_clear (&priv->blocking_push_cond);
957   g_mutex_clear (&priv->blocking_push_mutex);
958
959   g_ptr_array_unref (priv->stress);
960
961   gst_object_unref (h->element);
962   g_free (h->priv);
963   g_free (h);
964 }
965
966 /**
967  * gst_harness_add_element_src_pad:
968  * @h: a #GstHarness
969  * @srcpad: a #GstPad to link to the harness sinkpad
970  *
971  * Links the specifed #GstPad the @GstHarness sinkpad. This can be useful if
972  * perhaps the srcpad did not exist at the time of creating the harness,
973  * like a demuxer that provides a sometimes-pad after receiving data.
974  *
975  * MT safe.
976  *
977  * Since: 1.6
978  */
979 void
980 gst_harness_add_element_src_pad (GstHarness * h, GstPad * srcpad)
981 {
982   GstHarnessPrivate *priv = h->priv;
983   GstPadLinkReturn link;
984   if (h->sinkpad == NULL)
985     gst_harness_setup_sink_pad (h, &hsinktemplate, NULL);
986   link = gst_pad_link (srcpad, h->sinkpad);
987   g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
988   g_free (priv->element_srcpad_name);
989   priv->element_srcpad_name = gst_pad_get_name (srcpad);
990 }
991
992 /**
993  * gst_harness_add_element_sink_pad:
994  * @h: a #GstHarness
995  * @sinkpad: a #GstPad to link to the harness srcpad
996  *
997  * Links the specifed #GstPad the @GstHarness srcpad.
998  *
999  * MT safe.
1000  *
1001  * Since: 1.6
1002  */
1003 void
1004 gst_harness_add_element_sink_pad (GstHarness * h, GstPad * sinkpad)
1005 {
1006   GstHarnessPrivate *priv = h->priv;
1007   GstPadLinkReturn link;
1008   if (h->srcpad == NULL)
1009     gst_harness_setup_src_pad (h, &hsrctemplate, NULL);
1010   link = gst_pad_link (h->srcpad, sinkpad);
1011   g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
1012   g_free (priv->element_sinkpad_name);
1013   priv->element_sinkpad_name = gst_pad_get_name (sinkpad);
1014 }
1015
1016 /**
1017  * gst_harness_set_src_caps:
1018  * @h: a #GstHarness
1019  * @caps: (transfer full): a #GstCaps to set on the harness srcpad
1020  *
1021  * Sets the @GstHarness srcpad caps. This must be done before any buffers
1022  * can legally be pushed from the harness to the element.
1023  *
1024  * MT safe.
1025  *
1026  * Since: 1.6
1027  */
1028 void
1029 gst_harness_set_src_caps (GstHarness * h, GstCaps * caps)
1030 {
1031   GstHarnessPrivate *priv = h->priv;
1032   GstSegment segment;
1033   gboolean handled;
1034
1035   handled = gst_pad_push_event (h->srcpad, gst_event_new_caps (caps));
1036   g_assert (handled);
1037   gst_caps_take (&priv->src_caps, caps);
1038
1039   gst_segment_init (&segment, GST_FORMAT_TIME);
1040   handled = gst_pad_push_event (h->srcpad, gst_event_new_segment (&segment));
1041 }
1042
1043 /**
1044  * gst_harness_set_sink_caps:
1045  * @h: a #GstHarness
1046  * @caps: (transfer full): a #GstCaps to set on the harness sinkpad
1047  *
1048  * Sets the @GstHarness sinkpad caps.
1049  *
1050  * MT safe.
1051  *
1052  * Since: 1.6
1053  */
1054 void
1055 gst_harness_set_sink_caps (GstHarness * h, GstCaps * caps)
1056 {
1057   GstHarnessPrivate *priv = h->priv;
1058
1059   gst_caps_take (&priv->sink_caps, caps);
1060   gst_pad_push_event (h->sinkpad, gst_event_new_reconfigure ());
1061 }
1062
1063 /**
1064  * gst_harness_set_caps:
1065  * @h: a #GstHarness
1066  * @in: (transfer full): a #GstCaps to set on the harness srcpad
1067  * @out: (transfer full): a #GstCaps to set on the harness sinkpad
1068  *
1069  * Sets the @GstHarness srcpad and sinkpad caps.
1070  *
1071  * MT safe.
1072  *
1073  * Since: 1.6
1074  */
1075 void
1076 gst_harness_set_caps (GstHarness * h, GstCaps * in, GstCaps * out)
1077 {
1078   gst_harness_set_sink_caps (h, out);
1079   gst_harness_set_src_caps (h, in);
1080 }
1081
1082 /**
1083  * gst_harness_set_src_caps_str:
1084  * @h: a #GstHarness
1085  * @str: a @gchar describing a #GstCaps to set on the harness srcpad
1086  *
1087  * Sets the @GstHarness srcpad caps using a string. This must be done before
1088  * any buffers can legally be pushed from the harness to the element.
1089  *
1090  * MT safe.
1091  *
1092  * Since: 1.6
1093  */
1094 void
1095 gst_harness_set_src_caps_str (GstHarness * h, const gchar * str)
1096 {
1097   gst_harness_set_src_caps (h, gst_caps_from_string (str));
1098 }
1099
1100 /**
1101  * gst_harness_set_sink_caps_str:
1102  * @h: a #GstHarness
1103  * @str: a @gchar describing a #GstCaps to set on the harness sinkpad
1104  *
1105  * Sets the @GstHarness sinkpad caps using a string.
1106  *
1107  * MT safe.
1108  *
1109  * Since: 1.6
1110  */
1111 void
1112 gst_harness_set_sink_caps_str (GstHarness * h, const gchar * str)
1113 {
1114   gst_harness_set_sink_caps (h, gst_caps_from_string (str));
1115 }
1116
1117 /**
1118  * gst_harness_set_caps_str:
1119  * @h: a #GstHarness
1120  * @in: a @gchar describing a #GstCaps to set on the harness srcpad
1121  * @out: a @gchar describing a #GstCaps to set on the harness sinkpad
1122  *
1123  * Sets the @GstHarness srcpad and sinkpad caps using strings.
1124  *
1125  * MT safe.
1126  *
1127  * Since: 1.6
1128  */
1129 void
1130 gst_harness_set_caps_str (GstHarness * h, const gchar * in, const gchar * out)
1131 {
1132   gst_harness_set_sink_caps_str (h, out);
1133   gst_harness_set_src_caps_str (h, in);
1134 }
1135
1136 /**
1137  * gst_harness_use_systemclock:
1138  * @h: a #GstHarness
1139  *
1140  * Sets the system #GstClock on the @GstHarness #GstElement
1141  *
1142  * MT safe.
1143  *
1144  * Since: 1.6
1145  */
1146 void
1147 gst_harness_use_systemclock (GstHarness * h)
1148 {
1149   GstClock *clock = gst_system_clock_obtain ();
1150   g_assert (clock != NULL);
1151   gst_element_set_clock (h->element, clock);
1152   gst_object_unref (clock);
1153 }
1154
1155 /**
1156  * gst_harness_use_testclock:
1157  * @h: a #GstHarness
1158  *
1159  * Sets the #GstTestClock on the #GstHarness #GstElement
1160  *
1161  * MT safe.
1162  *
1163  * Since: 1.6
1164  */
1165 void
1166 gst_harness_use_testclock (GstHarness * h)
1167 {
1168   GstClock *clock = gst_test_clock_new ();
1169   g_assert (clock != NULL);
1170   gst_element_set_clock (h->element, clock);
1171   gst_object_unref (clock);
1172 }
1173
1174 /**
1175  * gst_harness_get_testclock:
1176  * @h: a #GstHarness
1177  *
1178  * Get the #GstTestClock. Useful if specific operations on the testclock is
1179  * needed.
1180  *
1181  * MT safe.
1182  *
1183  * Returns: (transfer full): a #GstTestClock, or %NULL if the testclock is not
1184  * present.
1185  *
1186  * Since: 1.6
1187  */
1188 GstTestClock *
1189 gst_harness_get_testclock (GstHarness * h)
1190 {
1191   GstTestClock *testclock = NULL;
1192   GstClock *clock;
1193
1194   clock = gst_element_get_clock (h->element);
1195   if (clock) {
1196     if (GST_IS_TEST_CLOCK (clock))
1197       testclock = GST_TEST_CLOCK (clock);
1198     else
1199       gst_object_unref (clock);
1200   }
1201   return testclock;
1202 }
1203
1204 /**
1205  * gst_harness_set_time:
1206  * @h: a #GstHarness
1207  * @time: a #GstClockTime to advance the clock to
1208  *
1209  * Advance the #GstTestClock to a specific time.
1210  *
1211  * MT safe.
1212  *
1213  * Returns: a @gboolean %TRUE if the time could be set. %FALSE if not.
1214  *
1215  * Since: 1.6
1216  */
1217 gboolean
1218 gst_harness_set_time (GstHarness * h, GstClockTime time)
1219 {
1220   GstTestClock *testclock;
1221   testclock = gst_harness_get_testclock (h);
1222   if (testclock == NULL)
1223     return FALSE;
1224
1225   gst_test_clock_set_time (testclock, time);
1226   gst_object_unref (testclock);
1227   return TRUE;
1228 }
1229
1230 /**
1231  * gst_harness_wait_for_clock_id_waits:
1232  * @h: a #GstHarness
1233  * @waits: a #guint describing the numbers of #GstClockID registered with
1234  * the #GstTestClock
1235  * @timeout: a #guint describing how many seconds to wait for @waits to be true
1236  *
1237  * Waits for @timeout seconds until @waits number of #GstClockID waits is
1238  * registered with the #GstTestClock. Useful for writing deterministic tests,
1239  * where you want to make sure that an expected number of waits have been
1240  * reached.
1241  *
1242  * MT safe.
1243  *
1244  * Returns: a @gboolean %TRUE if the waits have been registered, %FALSE if not.
1245  * (Could be that it timed out waiting or that more waits then waits was found)
1246  *
1247  * Since: 1.6
1248  */
1249 gboolean
1250 gst_harness_wait_for_clock_id_waits (GstHarness * h, guint waits, guint timeout)
1251 {
1252   GstTestClock *testclock = gst_harness_get_testclock (h);
1253   gint64 start_time;
1254   gboolean ret;
1255
1256   if (testclock == NULL)
1257     return FALSE;
1258
1259   start_time = g_get_monotonic_time ();
1260   while (gst_test_clock_peek_id_count (testclock) < waits) {
1261     gint64 time_spent;
1262
1263     g_usleep (G_USEC_PER_SEC / 1000);
1264     time_spent = g_get_monotonic_time () - start_time;
1265     if ((time_spent / G_USEC_PER_SEC) > timeout)
1266       break;
1267   }
1268
1269   ret = (waits == gst_test_clock_peek_id_count (testclock));
1270
1271   gst_object_unref (testclock);
1272   return ret;
1273 }
1274
1275 /**
1276  * gst_harness_crank_single_clock_wait:
1277  * @h: a #GstHarness
1278  *
1279  * A "crank" consists of three steps:
1280  * 1: Wait for a #GstClockID to be registered with the #GstTestClock.
1281  * 2: Advance the #GstTestClock to the time the #GstClockID is waiting for.
1282  * 3: Release the #GstClockID wait.
1283  * Together, this provides an easy way to not have to think about the details
1284  * around clocks and time, but still being able to write deterministic tests
1285  * that are dependant on this. A "crank" can be though of as the notion of
1286  * manually driving the clock forward to its next logical step.
1287  *
1288  * MT safe.
1289  *
1290  * Returns: a @gboolean %TRUE if the "crank" was successful, %FALSE if not.
1291  *
1292  * Since: 1.6
1293  */
1294 gboolean
1295 gst_harness_crank_single_clock_wait (GstHarness * h)
1296 {
1297   GstTestClock *testclock = gst_harness_get_testclock (h);
1298   GstClockID res, pending;
1299   gboolean ret = FALSE;
1300
1301   if (G_LIKELY (testclock != NULL)) {
1302     gst_test_clock_wait_for_next_pending_id (testclock, &pending);
1303
1304     gst_test_clock_set_time (testclock, gst_clock_id_get_time (pending));
1305     res = gst_test_clock_process_next_clock_id (testclock);
1306     if (res == pending) {
1307       GST_DEBUG ("cranked time %" GST_TIME_FORMAT,
1308           GST_TIME_ARGS (gst_clock_get_time (GST_CLOCK (testclock))));
1309       ret = TRUE;
1310     } else {
1311       GST_WARNING ("testclock next id != pending (%p != %p)", res, pending);
1312     }
1313
1314     gst_clock_id_unref (res);
1315     gst_clock_id_unref (pending);
1316
1317     gst_object_unref (testclock);
1318   } else {
1319     GST_WARNING ("No testclock on element %s", GST_ELEMENT_NAME (h->element));
1320   }
1321
1322   return ret;
1323 }
1324
1325 /**
1326  * gst_harness_crank_multiple_clock_waits:
1327  * @h: a #GstHarness
1328  * @waits: a #guint describing the number of #GstClockIDs to crank
1329  *
1330  * Similar to gst_harness_crank_single_clock_wait, this is the function to use
1331  * if your harnessed element(s) are using more then one gst_clock_id_wait.
1332  * Failing to do so can (and will) make it racy which #GstClockID you actually
1333  * are releasing, where as this function will process all the waits at the
1334  * same time, ensuring that one thread can't register another wait before
1335  * both are released.
1336  *
1337  * MT safe.
1338  *
1339  * Returns: a @gboolean %TRUE if the "crank" was successful, %FALSE if not.
1340  *
1341  * Since: 1.6
1342  */
1343 gboolean
1344 gst_harness_crank_multiple_clock_waits (GstHarness * h, guint waits)
1345 {
1346   GstTestClock *testclock;
1347   GList *pending;
1348   guint processed;
1349
1350   testclock = gst_harness_get_testclock (h);
1351   if (testclock == NULL)
1352     return FALSE;
1353
1354   gst_test_clock_wait_for_multiple_pending_ids (testclock, waits, &pending);
1355   gst_harness_set_time (h, gst_test_clock_id_list_get_latest_time (pending));
1356   processed = gst_test_clock_process_id_list (testclock, pending);
1357
1358   g_list_free_full (pending, gst_clock_id_unref);
1359   gst_object_unref (testclock);
1360   return processed == waits;
1361 }
1362
1363 /**
1364  * gst_harness_play:
1365  * @h: a #GstHarness
1366  *
1367  * This will set the harnessed #GstElement to %GST_STATE_PLAYING.
1368  * #GstElements without a sink-#GstPad and with the %GST_ELEMENT_FLAG_SOURCE
1369  * flag set is concidered a src #GstElement
1370  * Non-src #GstElements (like sinks and filters) are automatically set to
1371  * playing by the #GstHarness, but src #GstElements are not to avoid them
1372  * starting to produce buffers.
1373  * Hence, for src #GstElement you will need to call gst_harness_play explicitly.
1374  *
1375  * MT safe.
1376  *
1377  * Since: 1.6
1378  */
1379 void
1380 gst_harness_play (GstHarness * h)
1381 {
1382   GstState state, pending;
1383   gboolean state_change;
1384   state_change = gst_element_set_state (h->element, GST_STATE_PLAYING);
1385   g_assert_cmpint (GST_STATE_CHANGE_SUCCESS, ==, state_change);
1386   state_change = gst_element_get_state (h->element, &state, &pending, 0);
1387   g_assert_cmpint (GST_STATE_CHANGE_SUCCESS, ==, state_change);
1388   g_assert_cmpint (GST_STATE_PLAYING, ==, state);
1389 }
1390
1391 /**
1392  * gst_harness_set_blocking_push_mode:
1393  * @h: a #GstHarness
1394  *
1395  * Setting this will make the harness block in the chain-function, and
1396  * then release when gst_harness_pull or gst_harness_try_pull is called.
1397  * Can be useful when wanting to control a src-element that is not implementing
1398  * gst_clock_id_wait so it can't be controlled by the #GstTestClock, since
1399  * it otherwise would produce buffers as fast as possible.
1400  *
1401  * MT safe.
1402  *
1403  * Since: 1.6
1404  */
1405 void
1406 gst_harness_set_blocking_push_mode (GstHarness * h)
1407 {
1408   GstHarnessPrivate *priv = h->priv;
1409   priv->blocking_push_mode = TRUE;
1410 }
1411
1412 /**
1413  * gst_harness_set_forwarding:
1414  * @h: a #GstHarness
1415  * @forwarding: a #gboolean to enable/disable forwarding
1416  *
1417  * As a convenience, a src-harness will forward %GST_EVENT_STREAM_START,
1418  * %GST_EVENT_CAPS and %GST_EVENT_SEGMENT to the main-harness if forwarding
1419  * is enabled, and forward any sticky-events from the main-harness to
1420  * the sink-harness. It will also forward the %GST_QUERY_ALLOCATION.
1421  *
1422  * If forwarding is disabled, the user will have to either manually push
1423  * these events from the src-harness using gst_harness_src_push_event, or
1424  * create and push them manually. While this will allow full control and
1425  * inspection of these events, for the most cases having forwarding enabled
1426  * will be sufficient when writing a test where the src-harness' main function
1427  * is providing data for the main-harness.
1428  *
1429  * Forwarding is enabled by default.
1430  *
1431  * MT safe.
1432  *
1433  * Since: 1.6
1434  */
1435 void
1436 gst_harness_set_forwarding (GstHarness * h, gboolean forwarding)
1437 {
1438   GstHarnessPrivate *priv = h->priv;
1439   priv->forwarding = forwarding;
1440   if (h->src_harness)
1441     gst_harness_set_forwarding (h->src_harness, forwarding);
1442   if (h->sink_harness)
1443     gst_harness_set_forwarding (h->sink_harness, forwarding);
1444 }
1445
1446 /**
1447  * gst_harness_create_buffer:
1448  * @h: a #GstHarness
1449  * @size: a #gsize specifying the size of the buffer
1450  *
1451  * Allocates a buffer using a #GstBufferPool if present, or else using the
1452  * configured #GstAllocator and #GstAllocationParams
1453  *
1454  * MT safe.
1455  *
1456  * Returns: a #GstBuffer of size @size
1457  *
1458  * Since: 1.6
1459  */
1460 GstBuffer *
1461 gst_harness_create_buffer (GstHarness * h, gsize size)
1462 {
1463   GstHarnessPrivate *priv = h->priv;
1464   GstBuffer *ret = NULL;
1465   GstFlowReturn flow;
1466
1467   if (gst_pad_check_reconfigure (h->srcpad))
1468     gst_harness_negotiate (h);
1469
1470   if (priv->pool) {
1471     flow = gst_buffer_pool_acquire_buffer (priv->pool, &ret, NULL);
1472     g_assert_cmpint (flow, ==, GST_FLOW_OK);
1473     if (gst_buffer_get_size (ret) != size) {
1474       GST_DEBUG_OBJECT (h,
1475           "use fallback, pool is configured with a different size (%zu != %zu)",
1476           size, gst_buffer_get_size (ret));
1477       gst_buffer_unref (ret);
1478       ret = NULL;
1479     }
1480   }
1481
1482   if (!ret)
1483     ret =
1484         gst_buffer_new_allocate (priv->allocator, size,
1485         &priv->allocation_params);
1486
1487   g_assert (ret != NULL);
1488   return ret;
1489 }
1490
1491 /**
1492  * gst_harness_push:
1493  * @h: a #GstHarness
1494  * @buffer: a #GstBuffer to push
1495  *
1496  * Pushes a #GstBuffer on the #GstHarness srcpad. The standard way of
1497  * interacting with an harnessed element.
1498  *
1499  * MT safe.
1500  *
1501  * Returns: a #GstFlowReturn with the result from the push
1502  *
1503  * Since: 1.6
1504  */
1505 GstFlowReturn
1506 gst_harness_push (GstHarness * h, GstBuffer * buffer)
1507 {
1508   GstHarnessPrivate *priv = h->priv;
1509   g_assert (buffer != NULL);
1510   priv->last_push_ts = GST_BUFFER_TIMESTAMP (buffer);
1511   return gst_pad_push (h->srcpad, buffer);
1512 }
1513
1514 /**
1515  * gst_harness_pull:
1516  * @h: a #GstHarness
1517  *
1518  * Pulls a #GstBuffer from the #GAsyncQueue on the #GstHarness sinkpad. The pull
1519  * will timeout in 60 seconds. This is the standard way of getting a buffer
1520  * from a harnessed #GstElement.
1521  *
1522  * MT safe.
1523  *
1524  * Returns: a #GstBuffer or %NULL if timed out.
1525  *
1526  * Since: 1.6
1527  */
1528 GstBuffer *
1529 gst_harness_pull (GstHarness * h)
1530 {
1531   GstHarnessPrivate *priv = h->priv;
1532
1533   if (priv->blocking_push_mode) {
1534     g_mutex_lock (&priv->blocking_push_mutex);
1535     g_cond_signal (&priv->blocking_push_cond);
1536     g_mutex_unlock (&priv->blocking_push_mutex);
1537   }
1538
1539   return (GstBuffer *) g_async_queue_timeout_pop (priv->buffer_queue,
1540       G_USEC_PER_SEC * 60);
1541 }
1542
1543 /**
1544  * gst_harness_try_pull:
1545  * @h: a #GstHarness
1546  *
1547  * Pulls a #GstBuffer from the #GAsyncQueue on the #GstHarness sinkpad. Unlike
1548  * gst_harness_pull this will not wait for any buffers if not any are present,
1549  * and return %NULL straight away.
1550  *
1551  * MT safe.
1552  *
1553  * Returns: a #GstBuffer or %NULL if no buffers are present in the #GAsyncQueue
1554  *
1555  * Since: 1.6
1556  */
1557 GstBuffer *
1558 gst_harness_try_pull (GstHarness * h)
1559 {
1560   GstHarnessPrivate *priv = h->priv;
1561
1562   if (priv->blocking_push_mode) {
1563     g_mutex_lock (&priv->blocking_push_mutex);
1564     g_cond_signal (&priv->blocking_push_cond);
1565     g_mutex_unlock (&priv->blocking_push_mutex);
1566   }
1567
1568   return (GstBuffer *) g_async_queue_try_pop (priv->buffer_queue);
1569 }
1570
1571 /**
1572  * gst_harness_push_and_pull:
1573  * @h: a #GstHarness
1574  * @buffer: a #GstBuffer to push
1575  *
1576  * Basically a gst_harness_push and a gst_harness_pull in one line. Reflects
1577  * the fact that you often want to do exactly this in your test: Push one buffer
1578  * in, and inspect the outcome.
1579  *
1580  * MT safe.
1581  *
1582  * Returns: a #GstBuffer or %NULL if timed out.
1583  *
1584  * Since: 1.6
1585  */
1586 GstBuffer *
1587 gst_harness_push_and_pull (GstHarness * h, GstBuffer * buffer)
1588 {
1589   gst_harness_push (h, buffer);
1590   return gst_harness_pull (h);
1591 }
1592
1593 /**
1594  * gst_harness_buffers_received:
1595  * @h: a #GstHarness
1596  *
1597  * The total number of #GstBuffers that has arrived on the #GstHarness sinkpad.
1598  * This number includes buffers that have been dropped as well as buffers
1599  * that have already been pulled out.
1600  *
1601  * MT safe.
1602  *
1603  * Returns: a #guint number of buffers received
1604  *
1605  * Since: 1.6
1606  */
1607 guint
1608 gst_harness_buffers_received (GstHarness * h)
1609 {
1610   GstHarnessPrivate *priv = h->priv;
1611   return g_atomic_int_get (&priv->recv_buffers);
1612 }
1613
1614 /**
1615  * gst_harness_buffers_in_queue:
1616  * @h: a #GstHarness
1617  *
1618  * The number of #GstBuffers currently in the #GstHarness sinkpad #GAsyncQueue
1619  *
1620  * MT safe.
1621  *
1622  * Returns: a #guint number of buffers in the queue
1623  *
1624  * Since: 1.6
1625  */
1626 guint
1627 gst_harness_buffers_in_queue (GstHarness * h)
1628 {
1629   GstHarnessPrivate *priv = h->priv;
1630   return g_async_queue_length (priv->buffer_queue);
1631 }
1632
1633 /**
1634  * gst_harness_set_drop_buffers:
1635  * @h: a #GstHarness
1636  * @drop_buffers: a #gboolean specifying to drop outgoing buffers or not
1637  *
1638  * When set to %TRUE, instead of placing the buffers arriving from the harnessed
1639  * #GstElement inside the sinkpads #GAsyncQueue, they are instead unreffed.
1640  *
1641  * MT safe.
1642  *
1643  * Since: 1.6
1644  */
1645 void
1646 gst_harness_set_drop_buffers (GstHarness * h, gboolean drop_buffers)
1647 {
1648   GstHarnessPrivate *priv = h->priv;
1649   priv->drop_buffers = drop_buffers;
1650 }
1651
1652 /**
1653  * gst_harness_dump_to_file:
1654  * @h: a #GstHarness
1655  * @filename: a #gchar with a the name of a file
1656  *
1657  * Allows you to dump the #GstBuffers the #GstHarness sinkpad #GAsyncQueue
1658  * to a file.
1659  *
1660  * MT safe.
1661  *
1662  * Since: 1.6
1663  */
1664 void
1665 gst_harness_dump_to_file (GstHarness * h, const gchar * filename)
1666 {
1667   GstHarnessPrivate *priv = h->priv;
1668   FILE *fd;
1669   GstBuffer *buf;
1670   fd = fopen (filename, "wb");
1671   g_assert (fd);
1672
1673   while ((buf = g_async_queue_try_pop (priv->buffer_queue))) {
1674     GstMapInfo info;
1675     gst_buffer_map (buf, &info, GST_MAP_READ);
1676     fwrite (info.data, 1, info.size, fd);
1677     gst_buffer_unmap (buf, &info);
1678     gst_buffer_unref (buf);
1679   }
1680
1681   fflush (fd);
1682   fclose (fd);
1683 }
1684
1685 /**
1686  * gst_harness_get_last_pushed_timestamp:
1687  * @h: a #GstHarness
1688  *
1689  * Get the timestamp of the last #GstBuffer pushed on the #GstHarness srcpad,
1690  * typically with gst_harness_push or gst_harness_push_from_src.
1691  *
1692  * MT safe.
1693  *
1694  * Returns: a #GstClockTime with the timestamp or %GST_CLOCK_TIME_NONE if no
1695  * #GstBuffer has been pushed on the #GstHarness srcpad
1696  *
1697  * Since: 1.6
1698  */
1699 GstClockTime
1700 gst_harness_get_last_pushed_timestamp (GstHarness * h)
1701 {
1702   GstHarnessPrivate *priv = h->priv;
1703   return priv->last_push_ts;
1704 }
1705
1706 /**
1707  * gst_harness_push_event:
1708  * @h: a #GstHarness
1709  * @event: a #GstEvent to push
1710  *
1711  * Pushes an #GstEvent on the #GstHarness srcpad.
1712  *
1713  * MT safe.
1714  *
1715  * Returns: a #gboolean with the result from the push
1716  *
1717  * Since: 1.6
1718  */
1719 gboolean
1720 gst_harness_push_event (GstHarness * h, GstEvent * event)
1721 {
1722   return gst_pad_push_event (h->srcpad, event);
1723 }
1724
1725 /**
1726  * gst_harness_pull_event:
1727  * @h: a #GstHarness
1728  *
1729  * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness sinkpad.
1730  * Timeouts after 60 seconds similar to gst_harness_pull.
1731  *
1732  * MT safe.
1733  *
1734  * Returns: a #GstEvent or %NULL if timed out.
1735  *
1736  * Since: 1.6
1737  */
1738 GstEvent *
1739 gst_harness_pull_event (GstHarness * h)
1740 {
1741   GstHarnessPrivate *priv = h->priv;
1742   return (GstEvent *) g_async_queue_timeout_pop (priv->sink_event_queue,
1743       G_USEC_PER_SEC * 60);
1744 }
1745
1746 /**
1747  * gst_harness_try_pull_event:
1748  * @h: a #GstHarness
1749  *
1750  * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness sinkpad.
1751  * See gst_harness_try_pull for details.
1752  *
1753  * MT safe.
1754  *
1755  * Returns: a #GstEvent or %NULL if no buffers are present in the #GAsyncQueue
1756  *
1757  * Since: 1.6
1758  */
1759 GstEvent *
1760 gst_harness_try_pull_event (GstHarness * h)
1761 {
1762   GstHarnessPrivate *priv = h->priv;
1763   return (GstEvent *) g_async_queue_try_pop (priv->sink_event_queue);
1764 }
1765
1766 /**
1767  * gst_harness_events_received:
1768  * @h: a #GstHarness
1769  *
1770  * The total number of #GstEvents that has arrived on the #GstHarness sinkpad
1771  * This number includes events handled by the harness as well as events
1772  * that have already been pulled out.
1773  *
1774  * MT safe.
1775  *
1776  * Returns: a #guint number of events received
1777  *
1778  * Since: 1.6
1779  */
1780 guint
1781 gst_harness_events_received (GstHarness * h)
1782 {
1783   GstHarnessPrivate *priv = h->priv;
1784   return g_atomic_int_get (&priv->recv_events);
1785 }
1786
1787 /**
1788  * gst_harness_events_in_queue:
1789  * @h: a #GstHarness
1790  *
1791  * The number of #GstEvents currently in the #GstHarness sinkpad #GAsyncQueue
1792  *
1793  * MT safe.
1794  *
1795  * Returns: a #guint number of events in the queue
1796  *
1797  * Since: 1.6
1798  */
1799 guint
1800 gst_harness_events_in_queue (GstHarness * h)
1801 {
1802   GstHarnessPrivate *priv = h->priv;
1803   return g_async_queue_length (priv->sink_event_queue);
1804 }
1805
1806 /**
1807  * gst_harness_push_upstream_event:
1808  * @h: a #GstHarness
1809  * @event: a #GstEvent to push
1810  *
1811  * Pushes an #GstEvent on the #GstHarness sinkpad.
1812  *
1813  * MT safe.
1814  *
1815  * Returns: a #gboolean with the result from the push
1816  *
1817  * Since: 1.6
1818  */
1819 gboolean
1820 gst_harness_push_upstream_event (GstHarness * h, GstEvent * event)
1821 {
1822   g_return_val_if_fail (event != NULL, FALSE);
1823   g_return_val_if_fail (GST_EVENT_IS_UPSTREAM (event), FALSE);
1824
1825   return gst_pad_push_event (h->sinkpad, event);
1826 }
1827
1828 /**
1829  * gst_harness_pull_upstream_event:
1830  * @h: a #GstHarness
1831  *
1832  * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness srcpad.
1833  * Timeouts after 60 seconds similar to gst_harness_pull.
1834  *
1835  * MT safe.
1836  *
1837  * Returns: a #GstEvent or %NULL if timed out.
1838  *
1839  * Since: 1.6
1840  */
1841 GstEvent *
1842 gst_harness_pull_upstream_event (GstHarness * h)
1843 {
1844   GstHarnessPrivate *priv = h->priv;
1845   return (GstEvent *) g_async_queue_timeout_pop (priv->src_event_queue,
1846       G_USEC_PER_SEC * 60);
1847 }
1848
1849 /**
1850  * gst_harness_try_pull_upstream_event:
1851  * @h: a #GstHarness
1852  *
1853  * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness srcpad.
1854  * See gst_harness_try_pull for details.
1855  *
1856  * MT safe.
1857  *
1858  * Returns: a #GstEvent or %NULL if no buffers are present in the #GAsyncQueue
1859  *
1860  * Since: 1.6
1861  */
1862 GstEvent *
1863 gst_harness_try_pull_upstream_event (GstHarness * h)
1864 {
1865   GstHarnessPrivate *priv = h->priv;
1866   return (GstEvent *) g_async_queue_try_pop (priv->src_event_queue);
1867 }
1868
1869 /**
1870  * gst_harness_upstream_events_received:
1871  * @h: a #GstHarness
1872  *
1873  * The total number of #GstEvents that has arrived on the #GstHarness srcpad
1874  * This number includes events handled by the harness as well as events
1875  * that have already been pulled out.
1876  *
1877  * MT safe.
1878  *
1879  * Returns: a #guint number of events received
1880  *
1881  * Since: 1.6
1882  */
1883 guint
1884 gst_harness_upstream_events_received (GstHarness * h)
1885 {
1886   GstHarnessPrivate *priv = h->priv;
1887   return g_atomic_int_get (&priv->recv_upstream_events);
1888 }
1889
1890 /**
1891  * gst_harness_upstream_events_in_queue:
1892  * @h: a #GstHarness
1893  *
1894  * The number of #GstEvents currently in the #GstHarness srcpad #GAsyncQueue
1895  *
1896  * MT safe.
1897  *
1898  * Returns: a #guint number of events in the queue
1899  *
1900  * Since: 1.6
1901  */
1902 guint
1903 gst_harness_upstream_events_in_queue (GstHarness * h)
1904 {
1905   GstHarnessPrivate *priv = h->priv;
1906   return g_async_queue_length (priv->src_event_queue);
1907 }
1908
1909 /**
1910  * gst_harness_query_latency:
1911  * @h: a #GstHarness
1912  *
1913  * Get the min latency reported by any harnessed #GstElement.
1914  *
1915  * MT safe.
1916  *
1917  * Returns: a #GstClockTime with min latency
1918  *
1919  * Since: 1.6
1920  */
1921 GstClockTime
1922 gst_harness_query_latency (GstHarness * h)
1923 {
1924   GstQuery *query;
1925   gboolean is_live;
1926   GstClockTime min = GST_CLOCK_TIME_NONE;
1927   GstClockTime max;
1928
1929   query = gst_query_new_latency ();
1930
1931   if (gst_pad_peer_query (h->sinkpad, query)) {
1932     gst_query_parse_latency (query, &is_live, &min, &max);
1933   }
1934   gst_query_unref (query);
1935
1936   return min;
1937 }
1938
1939 /**
1940  * gst_harness_set_upstream_latency:
1941  * @h: a #GstHarness
1942  * @latency: a #GstClockTime specifying the latency
1943  *
1944  * Sets the min latency reported by #GstHarness when receiving a latency-query
1945  *
1946  * MT safe.
1947  *
1948  * Returns: a #GstClockTime with min latency
1949  *
1950  * Since: 1.6
1951  */
1952 void
1953 gst_harness_set_upstream_latency (GstHarness * h, GstClockTime latency)
1954 {
1955   GstHarnessPrivate *priv = h->priv;
1956   priv->latency_min = latency;
1957 }
1958
1959 /**
1960  * gst_harness_get_allocator:
1961  * @h: a #GstHarness
1962  * @allocator: (out) (allow-none) (transfer none): the #GstAllocator used
1963  * @params: (out) (allow-none) (transfer full): the #GstAllocationParams of
1964  *   @allocator
1965  *
1966  * Gets the @allocator and its @params that has been decided to use after an
1967  * allocation query.
1968  *
1969  * MT safe.
1970  *
1971  * Since: 1.6
1972  */
1973 void
1974 gst_harness_get_allocator (GstHarness * h, GstAllocator ** allocator,
1975     GstAllocationParams * params)
1976 {
1977   GstHarnessPrivate *priv = h->priv;
1978   if (allocator)
1979     *allocator = priv->allocator;
1980   if (params)
1981     *params = priv->allocation_params;
1982 }
1983
1984
1985 /**
1986  * gst_harness_set_propose_allocator:
1987  * @h: a #GstHarness
1988  * @allocator: (allow-none) (transfer full): a #GstAllocator
1989  * @params: (allow-none) (transfer none): a #GstAllocationParams
1990  *
1991  * Sets the @allocator and @params to propose when receiving an allocation
1992  * query.
1993  *
1994  * MT safe.
1995  *
1996  * Since: 1.6
1997  */
1998 void
1999 gst_harness_set_propose_allocator (GstHarness * h, GstAllocator * allocator,
2000     const GstAllocationParams * params)
2001 {
2002   GstHarnessPrivate *priv = h->priv;
2003   if (allocator)
2004     priv->propose_allocator = allocator;
2005   if (params)
2006     priv->propose_allocation_params = *params;
2007 }
2008
2009 /**
2010  * gst_harness_add_src_harness:
2011  * @h: a #GstHarness
2012  * @src_harness: (transfer full): a #GstHarness to be added as a src-harness.
2013  * @has_clock_wait: a #gboolean specifying if the #GstElement uses
2014  * gst_clock_wait_id internally.
2015  *
2016  * A src-harness is a great way of providing the #GstHarness with data.
2017  * By adding a src-type #GstElement, it is then easy to use functions like
2018  * gst_harness_push_from_src or gst_harness_src_crank_and_push_many
2019  * to provide your harnessed element with input. The @has_clock_wait variable
2020  * is a greate way to control you src-element with, in that you can have it
2021  * produce a buffer for you by simply cranking the clock, and not have it
2022  * spin out of control producing buffers as fast as possible.
2023  *
2024  * If a src-harness already exists it will be replaced.
2025  *
2026  * MT safe.
2027  *
2028  * Since: 1.6
2029  */
2030 void
2031 gst_harness_add_src_harness (GstHarness * h,
2032     GstHarness * src_harness, gboolean has_clock_wait)
2033 {
2034   if (h->src_harness)
2035     gst_harness_teardown (h->src_harness);
2036   h->src_harness = src_harness;
2037
2038   h->src_harness->priv->sink_forward_pad = gst_object_ref (h->srcpad);
2039   gst_harness_use_testclock (h->src_harness);
2040   h->src_harness->priv->has_clock_wait = has_clock_wait;
2041   gst_harness_set_forwarding (h->src_harness, h->priv->forwarding);
2042 }
2043
2044 /**
2045  * gst_harness_add_src:
2046  * @h: a #GstHarness
2047  * @src_element_name: a #gchar with the name of a #GstElement
2048  * @has_clock_wait: a #gboolean specifying if the #GstElement uses
2049  * gst_clock_wait_id internally.
2050  *
2051  * Similar to gst_harness_add_src_harness, this is a convenience to
2052  * directly create a src-harness using the @src_element_name name specified.
2053  *
2054  * MT safe.
2055  *
2056  * Since: 1.6
2057  */
2058 void
2059 gst_harness_add_src (GstHarness * h,
2060     const gchar * src_element_name, gboolean has_clock_wait)
2061 {
2062   GstHarness *src_harness = gst_harness_new (src_element_name);
2063   gst_harness_add_src_harness (h, src_harness, has_clock_wait);
2064 }
2065
2066 /**
2067  * gst_harness_add_src_parse:
2068  * @h: a #GstHarness
2069  * @launchline: a #gchar describing a gst-launch type line
2070  * @has_clock_wait: a #gboolean specifying if the #GstElement uses
2071  * gst_clock_wait_id internally.
2072  *
2073  * Similar to gst_harness_add_src, this allows you to specify a launch-line,
2074  * which can be useful for both having more then one #GstElement acting as your
2075  * src (Like a src producing raw buffers, and then an encoder, providing encoded
2076  * data), but also by allowing you to set properties like "is-live" directly on
2077  * the elements.
2078  *
2079  * MT safe.
2080  *
2081  * Since: 1.6
2082  */
2083 void
2084 gst_harness_add_src_parse (GstHarness * h,
2085     const gchar * launchline, gboolean has_clock_wait)
2086 {
2087   GstHarness *src_harness = gst_harness_new_parse (launchline);
2088   gst_harness_add_src_harness (h, src_harness, has_clock_wait);
2089 }
2090
2091 /**
2092  * gst_harness_push_from_src:
2093  * @h: a #GstHarness
2094  *
2095  * Transfer data from the src-#GstHarness to the main-#GstHarness. It consists
2096  * of 4 steps:
2097  * 1: Make sure the src is started. (see: gst_harness_play)
2098  * 2: Crank the clock (see: gst_harness_crank_single_clock_wait)
2099  * 3: Pull a #GstBuffer from the src-#GstHarness (see: gst_harness_pull)
2100  * 4: Push the same #GstBuffer into the main-#GstHarness (see: gst_harness_push)
2101  *
2102  * MT safe.
2103  *
2104  * Returns: a #GstFlowReturn with the result of the push
2105  *
2106  * Since: 1.6
2107  */
2108 GstFlowReturn
2109 gst_harness_push_from_src (GstHarness * h)
2110 {
2111   GstBuffer *buf;
2112   gboolean crank;
2113
2114   g_assert (h->src_harness);
2115
2116   /* FIXME: this *is* the right time to start the src,
2117      but maybe a flag so we don't keep telling it to play? */
2118   gst_harness_play (h->src_harness);
2119
2120   if (h->src_harness->priv->has_clock_wait) {
2121     crank = gst_harness_crank_single_clock_wait (h->src_harness);
2122     g_assert (crank);
2123   }
2124
2125   buf = gst_harness_pull (h->src_harness);
2126   g_assert (buf != NULL);
2127   return gst_harness_push (h, buf);
2128 }
2129
2130 /**
2131  * gst_harness_src_crank_and_push_many:
2132  * @h: a #GstHarness
2133  * @cranks: a #gint with the number of calls to gst_harness_crank_single_clock_wait
2134  * @pushes: a #gint with the number of calls to gst_harness_push
2135  *
2136  * Transfer data from the src-#GstHarness to the main-#GstHarness. Similar to
2137  * gst_harness_push_from_src, this variant allows you to specify how many cranks
2138  * and how many pushes to perform. This can be useful for both moving a lot
2139  * of data at the same time, as well as cases when one crank does not equal one
2140  * buffer to push and v.v.
2141  *
2142  * MT safe.
2143  *
2144  * Returns: a #GstFlowReturn with the result of the push
2145  *
2146  * Since: 1.6
2147  */
2148 GstFlowReturn
2149 gst_harness_src_crank_and_push_many (GstHarness * h, gint cranks, gint pushes)
2150 {
2151   GstFlowReturn ret = GST_FLOW_OK;
2152   gboolean crank;
2153
2154   g_assert (h->src_harness);
2155   gst_harness_play (h->src_harness);
2156
2157   for (int i = 0; i < cranks; i++) {
2158     crank = gst_harness_crank_single_clock_wait (h->src_harness);
2159     g_assert (crank);
2160   }
2161
2162   for (int i = 0; i < pushes; i++) {
2163     GstBuffer *buf;
2164     buf = gst_harness_pull (h->src_harness);
2165     g_assert (buf != NULL);
2166     ret = gst_harness_push (h, buf);
2167     if (ret != GST_FLOW_OK)
2168       break;
2169   }
2170
2171   return ret;
2172 }
2173
2174 /**
2175  * gst_harness_src_push_event:
2176  * @h: a #GstHarness
2177  *
2178  * Similar to what gst_harness_src_push does with #GstBuffers, this transfers
2179  * a #GstEvent from the src-#GstHarness to the main-#GstHarness. Note that
2180  * some #GstEvents are being transferred automagically. Look at sink_forward_pad
2181  * for details.
2182  *
2183  * MT safe.
2184  *
2185  * Returns: a #gboolean with the result of the push
2186  *
2187  * Since: 1.6
2188  */
2189 gboolean
2190 gst_harness_src_push_event (GstHarness * h)
2191 {
2192   return gst_harness_push_event (h, gst_harness_pull_event (h->src_harness));
2193 }
2194
2195
2196 static gboolean
2197 forward_sticky_events (GstPad * pad, GstEvent ** ev, gpointer user_data)
2198 {
2199   GstHarness *h = user_data;
2200   return gst_pad_push_event (h->priv->sink_forward_pad, gst_event_ref (*ev));
2201 }
2202
2203 /**
2204  * gst_harness_add_sink_harness:
2205  * @h: a #GstHarness
2206  * @sink_harness: (transfer full): a #GstHarness to be added as a sink-harness.
2207  *
2208  * Similar to gst_harness_add_src, this allows you to send the data coming out
2209  * of your harnessed #GstElement to a sink-element, allowing to test different
2210  * responses the element output might create in sink elements. An example might
2211  * be an existing sink providing some analytical data on the input it receives that
2212  * can be useful to your testing. If the goal is to test a sink-element itself,
2213  * this is better acheived using gst_harness_new directly on the sink.
2214  *
2215  * If a sink-harness already exists it will be replaced.
2216  *
2217  * MT safe.
2218  *
2219  * Since: 1.6
2220  */
2221 void
2222 gst_harness_add_sink_harness (GstHarness * h, GstHarness * sink_harness)
2223 {
2224   GstHarnessPrivate *priv = h->priv;
2225
2226   if (h->sink_harness) {
2227     gst_harness_teardown (h->sink_harness);
2228     gst_object_unref (priv->sink_forward_pad);
2229   }
2230   h->sink_harness = sink_harness;
2231   priv->sink_forward_pad = gst_object_ref (h->sink_harness->srcpad);
2232   gst_harness_use_testclock (h->sink_harness);
2233   if (priv->forwarding)
2234     gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h);
2235   gst_harness_set_forwarding (h->sink_harness, priv->forwarding);
2236 }
2237
2238 /**
2239  * gst_harness_add_sink:
2240  * @h: a #GstHarness
2241  * @sink_element_name: a #gchar with the name of a #GstElement
2242  *
2243  * Similar to gst_harness_add_sink_harness, this is a convenience to
2244  * directly create a sink-harness using the @sink_element_name name specified.
2245  *
2246  * MT safe.
2247  *
2248  * Since: 1.6
2249  */
2250 void
2251 gst_harness_add_sink (GstHarness * h, const gchar * sink_element_name)
2252 {
2253   GstHarness *sink_harness = gst_harness_new (sink_element_name);
2254   gst_harness_add_sink_harness (h, sink_harness);
2255 }
2256
2257 /**
2258  * gst_harness_add_sink_parse:
2259  * @h: a #GstHarness
2260  * @launchline: a #gchar with the name of a #GstElement
2261  *
2262  * Similar to gst_harness_add_sink, this allows you to specify a launch-line
2263  * instead of just an element name. See gst_harness_add_src_parse for details.
2264  *
2265  * MT safe.
2266  *
2267  * Since: 1.6
2268  */
2269 void
2270 gst_harness_add_sink_parse (GstHarness * h, const gchar * launchline)
2271 {
2272   GstHarness *sink_harness = gst_harness_new_parse (launchline);
2273   gst_harness_add_sink_harness (h, sink_harness);
2274 }
2275
2276 /**
2277  * gst_harness_push_to_sink:
2278  * @h: a #GstHarness
2279  *
2280  * Transfer one #GstBuffer from the main-#GstHarness to the sink-#GstHarness.
2281  * See gst_harness_push_from_src for details.
2282  *
2283  * MT safe.
2284  *
2285  * Returns: a #GstFlowReturn with the result of the push
2286  *
2287  * Since: 1.6
2288  */
2289 GstFlowReturn
2290 gst_harness_push_to_sink (GstHarness * h)
2291 {
2292   GstBuffer *buf;
2293   g_assert (h->sink_harness);
2294   buf = gst_harness_pull (h);
2295   g_assert (buf != NULL);
2296   return gst_harness_push (h->sink_harness, buf);
2297 }
2298
2299 /**
2300  * gst_harness_sink_push_many:
2301  * @h: a #GstHarness
2302  * @pushes: a #gint with the number of calls to gst_harness_push_to_sink
2303  *
2304  * Convenience that calls gst_harness_push_to_sink @pushes number of times.
2305  * Will abort the pushing if any one push fails.
2306  *
2307  * MT safe.
2308  *
2309  * Returns: a #GstFlowReturn with the result of the push
2310  *
2311  * Since: 1.6
2312  */
2313 GstFlowReturn
2314 gst_harness_sink_push_many (GstHarness * h, gint pushes)
2315 {
2316   GstFlowReturn ret = GST_FLOW_OK;
2317   g_assert (h->sink_harness);
2318   for (int i = 0; i < pushes; i++) {
2319     ret = gst_harness_push_to_sink (h);
2320     if (ret != GST_FLOW_OK)
2321       break;
2322   }
2323   return ret;
2324 }
2325
2326 /**
2327  * gst_harness_find_element:
2328  * @h: a #GstHarness
2329  * @element_name: a #gchar with a #GstElementFactory name
2330  *
2331  * Most useful in conjunction with gst_harness_new_parse, this will scan the
2332  * #GstElements inside the #GstHarness, and check if any of them matches
2333  * @element_name. Typical usecase being that you need to access one of the
2334  * harnessed elements for properties and/or signals.
2335  *
2336  * MT safe.
2337  *
2338  * Returns: (transfer full) (allow-none): a #GstElement or %NULL if not found
2339  *
2340  * Since: 1.6
2341  */
2342 GstElement *
2343 gst_harness_find_element (GstHarness * h, const gchar * element_name)
2344 {
2345   gboolean done = FALSE;
2346   GstIterator *iter;
2347   GValue data = G_VALUE_INIT;
2348
2349   iter = gst_bin_iterate_elements (GST_BIN (h->element));
2350   done = FALSE;
2351
2352   while (!done) {
2353     switch (gst_iterator_next (iter, &data)) {
2354       case GST_ITERATOR_OK:
2355       {
2356         GstElement *element = g_value_get_object (&data);
2357         GstPluginFeature *feature =
2358             GST_PLUGIN_FEATURE (gst_element_get_factory (element));
2359         if (!strcmp (element_name, gst_plugin_feature_get_name (feature))) {
2360           gst_iterator_free (iter);
2361           return element;
2362         }
2363         g_value_reset (&data);
2364         break;
2365       }
2366       case GST_ITERATOR_RESYNC:
2367         gst_iterator_resync (iter);
2368         break;
2369       case GST_ITERATOR_ERROR:
2370       case GST_ITERATOR_DONE:
2371         done = TRUE;
2372         break;
2373     }
2374   }
2375   gst_iterator_free (iter);
2376
2377   return NULL;
2378 }
2379
2380 /**
2381  * gst_harness_set:
2382  * @h: a #GstHarness
2383  * @element_name: a #gchar with a #GstElementFactory name
2384  * @first_property_name: a #gchar with the first property name
2385  * @...: value for the first property, followed optionally by more
2386  *  name/value pairs, followed by %NULL
2387  *
2388  * A convenience function to allows you to call g_object_set on a #GstElement
2389  * that are residing inside the #GstHarness, by using normal g_object_set
2390  * syntax.
2391  *
2392  * MT safe.
2393  *
2394  * Since: 1.6
2395  */
2396 void
2397 gst_harness_set (GstHarness * h,
2398     const gchar * element_name, const gchar * first_property_name, ...)
2399 {
2400   va_list var_args;
2401   GstElement *element = gst_harness_find_element (h, element_name);
2402   va_start (var_args, first_property_name);
2403   g_object_set_valist (G_OBJECT (element), first_property_name, var_args);
2404   va_end (var_args);
2405   gst_object_unref (element);
2406 }
2407
2408 /**
2409  * gst_harness_get:
2410  * @h: a #GstHarness
2411  * @element_name: a #gchar with a #GstElementFactory name
2412  * @first_property_name: a #gchar with the first property name
2413  * @...: return location for the first property, followed optionally by more
2414  *  name/return location pairs, followed by %NULL
2415  *
2416  * A convenience function to allows you to call g_object_get on a #GstElement
2417  * that are residing inside the #GstHarness, by using normal g_object_get
2418  * syntax.
2419  *
2420  * MT safe.
2421  *
2422  * Since: 1.6
2423  */
2424 void
2425 gst_harness_get (GstHarness * h,
2426     const gchar * element_name, const gchar * first_property_name, ...)
2427 {
2428   va_list var_args;
2429   GstElement *element = gst_harness_find_element (h, element_name);
2430   va_start (var_args, first_property_name);
2431   g_object_get_valist (G_OBJECT (element), first_property_name, var_args);
2432   va_end (var_args);
2433   gst_object_unref (element);
2434 }
2435
2436 /**
2437  * gst_harness_add_probe:
2438  * @h: a #GstHarness
2439  * @element_name: a #gchar with a #GstElementFactory name
2440  * @pad_name: a #gchar with the name of the pad to attach the probe to
2441  * @mask: a #GstPadProbeType (see gst_pad_add_probe)
2442  * @callback: a #GstPadProbeCallback (see gst_pad_add_probe)
2443  * @user_data: a #gpointer (see gst_pad_add_probe)
2444  * @destroy_data: a #GDestroyNotify (see gst_pad_add_probe)
2445  *
2446  * A convenience function to allows you to call gst_pad_add_probe on a
2447  * #GstPad of a #GstElement that are residing inside the #GstHarness,
2448  * by using normal gst_pad_add_probe syntax
2449  *
2450  * MT safe.
2451  *
2452  * Since: 1.6
2453  */
2454 void
2455 gst_harness_add_probe (GstHarness * h,
2456     const gchar * element_name, const gchar * pad_name, GstPadProbeType mask,
2457     GstPadProbeCallback callback, gpointer user_data,
2458     GDestroyNotify destroy_data)
2459 {
2460   GstElement *element = gst_harness_find_element (h, element_name);
2461   GstPad *pad = gst_element_get_static_pad (element, pad_name);
2462   gst_pad_add_probe (pad, mask, callback, user_data, destroy_data);
2463   gst_object_unref (pad);
2464   gst_object_unref (element);
2465 }
2466
2467 /******************************************************************************/
2468 /*       STRESS                                                               */
2469 /******************************************************************************/
2470 struct _GstHarnessThread
2471 {
2472   GstHarness *h;
2473   GThread *thread;
2474   gboolean running;
2475
2476   gulong sleep;
2477
2478   GDestroyNotify freefunc;
2479 };
2480
2481 typedef struct
2482 {
2483   GstHarnessThread t;
2484
2485   GFunc init;
2486   GFunc callback;
2487   gpointer data;
2488 } GstHarnessCustomThread;
2489
2490 typedef struct
2491 {
2492   GstHarnessThread t;
2493
2494   GstCaps *caps;
2495   GstSegment segment;
2496   GstHarnessPrepareBufferFunc func;
2497   gpointer data;
2498   GDestroyNotify notify;
2499 } GstHarnessPushBufferThread;
2500
2501 typedef struct
2502 {
2503   GstHarnessThread t;
2504
2505   GstEvent *event;
2506 } GstHarnessPushEventThread;
2507
2508 typedef struct
2509 {
2510   GstHarnessThread t;
2511
2512   gchar *name;
2513   GValue value;
2514 } GstHarnessPropThread;
2515
2516 typedef struct
2517 {
2518   GstHarnessThread t;
2519
2520   GstPadTemplate *templ;
2521   gchar *name;
2522   GstCaps *caps;
2523   gboolean release;
2524
2525   GSList *pads;
2526 } GstHarnessReqPadThread;
2527
2528 static void
2529 gst_harness_thread_init (GstHarnessThread * t, GDestroyNotify freefunc,
2530     GstHarness * h, gulong sleep)
2531 {
2532   t->freefunc = freefunc;
2533   t->h = h;
2534   t->sleep = sleep;
2535
2536   g_ptr_array_add (h->priv->stress, t);
2537 }
2538
2539 static void
2540 gst_harness_thread_free (GstHarnessThread * t)
2541 {
2542   g_slice_free (GstHarnessThread, t);
2543 }
2544
2545 static void
2546 gst_harness_custom_thread_free (GstHarnessCustomThread * t)
2547 {
2548   g_slice_free (GstHarnessCustomThread, t);
2549 }
2550
2551 static void
2552 gst_harness_push_buffer_thread_free (GstHarnessPushBufferThread * t)
2553 {
2554   if (t != NULL) {
2555     gst_caps_replace (&t->caps, NULL);
2556     if (t->notify != NULL)
2557       t->notify (t->data);
2558     g_slice_free (GstHarnessPushBufferThread, t);
2559   }
2560 }
2561
2562 static void
2563 gst_harness_push_event_thread_free (GstHarnessPushEventThread * t)
2564 {
2565   if (t != NULL) {
2566     gst_event_replace (&t->event, NULL);
2567     g_slice_free (GstHarnessPushEventThread, t);
2568   }
2569 }
2570
2571 static void
2572 gst_harness_property_thread_free (GstHarnessPropThread * t)
2573 {
2574   if (t != NULL) {
2575     g_free (t->name);
2576     g_value_unset (&t->value);
2577     g_slice_free (GstHarnessPropThread, t);
2578   }
2579 }
2580
2581 static void
2582 gst_harness_requestpad_release (GstPad * pad, GstElement * element)
2583 {
2584   gst_element_release_request_pad (element, pad);
2585   gst_object_unref (pad);
2586 }
2587
2588 static void
2589 gst_harness_requestpad_release_pads (GstHarnessReqPadThread * rpt)
2590 {
2591   g_slist_foreach (rpt->pads, (GFunc) gst_harness_requestpad_release,
2592       rpt->t.h->element);
2593   g_slist_free (rpt->pads);
2594   rpt->pads = NULL;
2595 }
2596
2597 static void
2598 gst_harness_requestpad_thread_free (GstHarnessReqPadThread * t)
2599 {
2600   if (t != NULL) {
2601     gst_object_replace ((GstObject **) & t->templ, NULL);
2602     g_free (t->name);
2603     gst_caps_replace (&t->caps, NULL);
2604
2605     gst_harness_requestpad_release_pads (t);
2606     g_slice_free (GstHarnessReqPadThread, t);
2607   }
2608 }
2609
2610 #define GST_HARNESS_THREAD_START(ID, t)                                        \
2611   (((GstHarnessThread *)t)->running = TRUE,                                    \
2612   ((GstHarnessThread *)t)->thread = g_thread_new (                             \
2613       "gst-harness-stress-"G_STRINGIFY(ID),                                    \
2614       (GThreadFunc)gst_harness_stress_##ID##_func, t))
2615 #define GST_HARNESS_THREAD_END(t)                                              \
2616    (t->running = FALSE,                                                        \
2617    GPOINTER_TO_UINT (g_thread_join (t->thread)))
2618
2619 static void
2620 gst_harness_stress_free (GstHarnessThread * t)
2621 {
2622   if (t != NULL && t->freefunc != NULL)
2623     t->freefunc (t);
2624 }
2625
2626 static gpointer
2627 gst_harness_stress_custom_func (GstHarnessThread * t)
2628 {
2629   GstHarnessCustomThread *ct = (GstHarnessCustomThread *) t;
2630   guint count = 0;
2631
2632   ct->init (ct, ct->data);
2633
2634   while (t->running) {
2635     ct->callback (ct, ct->data);
2636
2637     count++;
2638     g_usleep (t->sleep);
2639   }
2640   return GUINT_TO_POINTER (count);
2641 }
2642
2643
2644 static gpointer
2645 gst_harness_stress_statechange_func (GstHarnessThread * t)
2646 {
2647   guint count = 0;
2648
2649   while (t->running) {
2650     GstClock *clock = gst_element_get_clock (t->h->element);
2651     GstIterator *it;
2652     gboolean done = FALSE;
2653     gboolean change;
2654
2655     change = gst_element_set_state (t->h->element, GST_STATE_NULL);
2656     g_assert (change == GST_STATE_CHANGE_SUCCESS);
2657     g_thread_yield ();
2658
2659     it = gst_element_iterate_sink_pads (t->h->element);
2660     while (!done) {
2661       GValue item = G_VALUE_INIT;
2662       switch (gst_iterator_next (it, &item)) {
2663         case GST_ITERATOR_OK:
2664         {
2665           GstPad *sinkpad = g_value_get_object (&item);
2666           GstPad *srcpad = gst_pad_get_peer (sinkpad);
2667           if (srcpad != NULL) {
2668             gst_pad_unlink (srcpad, sinkpad);
2669             gst_pad_link (srcpad, sinkpad);
2670             gst_object_unref (srcpad);
2671           }
2672           g_value_reset (&item);
2673           break;
2674         }
2675         case GST_ITERATOR_RESYNC:
2676           gst_iterator_resync (it);
2677           break;
2678         case GST_ITERATOR_ERROR:
2679           g_assert_not_reached ();
2680         case GST_ITERATOR_DONE:
2681           done = TRUE;
2682           break;
2683       }
2684       g_value_unset (&item);
2685     }
2686     gst_iterator_free (it);
2687
2688     if (clock != NULL) {
2689       gst_element_set_clock (t->h->element, clock);
2690       gst_object_unref (clock);
2691     }
2692     change = gst_element_set_state (t->h->element, GST_STATE_PLAYING);
2693     g_assert (change == GST_STATE_CHANGE_SUCCESS);
2694
2695     count++;
2696     g_usleep (t->sleep);
2697   }
2698   return GUINT_TO_POINTER (count);
2699 }
2700
2701 static gpointer
2702 gst_harness_stress_buffer_func (GstHarnessThread * t)
2703 {
2704   GstHarnessPushBufferThread *pt = (GstHarnessPushBufferThread *) t;
2705   guint count = 0;
2706   gchar *sid;
2707   gboolean handled;
2708
2709   /* Push stream start, caps and segment events */
2710   sid = g_strdup_printf ("%s-%p", GST_OBJECT_NAME (t->h->element), t->h);
2711   handled = gst_pad_push_event (t->h->srcpad, gst_event_new_stream_start (sid));
2712   g_assert (handled);
2713   g_free (sid);
2714   handled = gst_pad_push_event (t->h->srcpad, gst_event_new_caps (pt->caps));
2715   g_assert (handled);
2716   handled = gst_pad_push_event (t->h->srcpad,
2717       gst_event_new_segment (&pt->segment));
2718   g_assert (handled);
2719
2720   while (t->running) {
2721     gst_harness_push (t->h, pt->func (t->h, pt->data));
2722
2723     count++;
2724     g_usleep (t->sleep);
2725   }
2726   return GUINT_TO_POINTER (count);
2727 }
2728
2729 static gpointer
2730 gst_harness_stress_event_func (GstHarnessThread * t)
2731 {
2732   GstHarnessPushEventThread *pet = (GstHarnessPushEventThread *) t;
2733   guint count = 0;
2734
2735   while (t->running) {
2736     gst_harness_push_event (t->h, gst_event_ref (pet->event));
2737
2738     count++;
2739     g_usleep (t->sleep);
2740   }
2741   return GUINT_TO_POINTER (count);
2742 }
2743
2744 static gpointer
2745 gst_harness_stress_upstream_event_func (GstHarnessThread * t)
2746 {
2747   GstHarnessPushEventThread *pet = (GstHarnessPushEventThread *) t;
2748   guint count = 0;
2749
2750   while (t->running) {
2751     gst_harness_push_upstream_event (t->h, gst_event_ref (pet->event));
2752
2753     count++;
2754     g_usleep (t->sleep);
2755   }
2756   return GUINT_TO_POINTER (count);
2757 }
2758
2759 static gpointer
2760 gst_harness_stress_property_func (GstHarnessThread * t)
2761 {
2762   GstHarnessPropThread *pt = (GstHarnessPropThread *) t;
2763   guint count = 0;
2764
2765   while (t->running) {
2766     GValue value = G_VALUE_INIT;
2767
2768     g_object_set_property (G_OBJECT (t->h->element), pt->name, &pt->value);
2769
2770     g_value_init (&value, G_VALUE_TYPE (&pt->value));
2771     g_object_get_property (G_OBJECT (t->h->element), pt->name, &value);
2772     g_value_reset (&value);
2773
2774     count++;
2775     g_usleep (t->sleep);
2776   }
2777   return GUINT_TO_POINTER (count);
2778 }
2779
2780 static gpointer
2781 gst_harness_stress_requestpad_func (GstHarnessThread * t)
2782 {
2783   GstHarnessReqPadThread *rpt = (GstHarnessReqPadThread *) t;
2784   guint count = 0;
2785
2786   while (t->running) {
2787     GstPad *reqpad;
2788
2789     if (rpt->release)
2790       gst_harness_requestpad_release_pads (rpt);
2791
2792     g_thread_yield ();
2793
2794     reqpad = gst_element_request_pad (t->h->element,
2795         rpt->templ, rpt->name, rpt->caps);
2796
2797     g_assert (reqpad != NULL);
2798
2799     rpt->pads = g_slist_prepend (rpt->pads, reqpad);
2800
2801     count++;
2802     g_usleep (t->sleep);
2803   }
2804   return GUINT_TO_POINTER (count);
2805 }
2806
2807 /**
2808  * gst_harness_stress_thread_stop:
2809  * @t: a #GstHarnessThread
2810  *
2811  * Stop the running #GstHarnessThread
2812  *
2813  * MT safe.
2814  *
2815  * Since: 1.6
2816  */
2817 guint
2818 gst_harness_stress_thread_stop (GstHarnessThread * t)
2819 {
2820   guint ret;
2821
2822   g_return_val_if_fail (t != NULL, 0);
2823
2824   ret = GST_HARNESS_THREAD_END (t);
2825   g_ptr_array_remove (t->h->priv->stress, t);
2826   return ret;
2827 }
2828
2829 /**
2830  * gst_harness_stress_custom_start: (skip)
2831  * @h: a #GstHarness
2832  * @init: a #GFunc that is called initially and only once
2833  * @callback: a #GFunc that is called as often as possible
2834  * @data: a #gpointer with custom data to pass to the @callback function
2835  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2836  * each call to the @callback
2837  *
2838  * Start a custom stress-thread that will call your @callback for every
2839  * iteration allowing you to do something nasty.
2840  *
2841  * MT safe.
2842  *
2843  * Returns: a #GstHarnessThread
2844  *
2845  * Since: 1.6
2846  */
2847 GstHarnessThread *
2848 gst_harness_stress_custom_start (GstHarness * h,
2849     GFunc init, GFunc callback, gpointer data, gulong sleep)
2850 {
2851   GstHarnessCustomThread *t = g_slice_new0 (GstHarnessCustomThread);
2852   gst_harness_thread_init (&t->t,
2853       (GDestroyNotify) gst_harness_custom_thread_free, h, sleep);
2854
2855   t->init = init;
2856   t->callback = callback;
2857   t->data = data;
2858
2859   GST_HARNESS_THREAD_START (custom, t);
2860   return &t->t;
2861 }
2862
2863 /**
2864  * gst_harness_stress_statechange_start_full: (skip)
2865  * @h: a #GstHarness
2866  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2867  * each state-change
2868  *
2869  * Change the state of your harnessed #GstElement from NULL to PLAYING and
2870  * back again, only pausing for @sleep microseconds every time.
2871  *
2872  * MT safe.
2873  *
2874  * Returns: a #GstHarnessThread
2875  *
2876  * Since: 1.6
2877  */
2878 GstHarnessThread *
2879 gst_harness_stress_statechange_start_full (GstHarness * h, gulong sleep)
2880 {
2881   GstHarnessThread *t = g_slice_new0 (GstHarnessThread);
2882   gst_harness_thread_init (t,
2883       (GDestroyNotify) gst_harness_thread_free, h, sleep);
2884   GST_HARNESS_THREAD_START (statechange, t);
2885   return t;
2886 }
2887
2888 static GstBuffer *
2889 gst_harness_ref_buffer (GstHarness * h, gpointer data)
2890 {
2891   (void) h;
2892   return gst_buffer_ref (GST_BUFFER_CAST (data));
2893 }
2894
2895 /**
2896  * gst_harness_stress_push_buffer_start_full: (skip)
2897  * @h: a #GstHarness
2898  * @caps: a #GstCaps for the #GstBuffer
2899  * @segment: a #GstSegment
2900  * @buf: a #GstBuffer to push
2901  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2902  * each call to gst_pad_push
2903  *
2904  * Push a #GstBuffer in intervals of @sleep microseconds.
2905  *
2906  * MT safe.
2907  *
2908  * Returns: a #GstHarnessThread
2909  *
2910  * Since: 1.6
2911  */
2912 GstHarnessThread *
2913 gst_harness_stress_push_buffer_start_full (GstHarness * h,
2914     GstCaps * caps, const GstSegment * segment, GstBuffer * buf, gulong sleep)
2915 {
2916   return gst_harness_stress_push_buffer_with_cb_start_full (h, caps, segment,
2917       gst_harness_ref_buffer, gst_buffer_ref (buf),
2918       (GDestroyNotify) gst_buffer_unref, sleep);
2919 }
2920
2921 /**
2922  * gst_harness_stress_push_buffer_with_cb_start_full: (skip)
2923  * @h: a #GstHarness
2924  * @caps: a #GstCaps for the #GstBuffer
2925  * @segment: a #GstSegment
2926  * @func: a #GstHarnessPrepareBufferFunc function called before every iteration
2927  * to prepare / create a #GstBuffer for pushing
2928  * @data: a #gpointer with data to the #GstHarnessPrepareBufferFunc function
2929  * @notify: a #GDestroyNotify that is called for every push to allow cleaning
2930  * up the #GstBuffer. (like gst_buffer_unref)
2931  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2932  * each call to gst_pad_push
2933  *
2934  * Push a #GstBuffer in intervals of @sleep microseconds.
2935  *
2936  * MT safe.
2937  *
2938  * Returns: a #GstHarnessThread
2939  *
2940  * Since: 1.6
2941  */
2942 GstHarnessThread *
2943 gst_harness_stress_push_buffer_with_cb_start_full (GstHarness * h,
2944     GstCaps * caps, const GstSegment * segment,
2945     GstHarnessPrepareBufferFunc func, gpointer data, GDestroyNotify notify,
2946     gulong sleep)
2947 {
2948   GstHarnessPushBufferThread *t = g_slice_new0 (GstHarnessPushBufferThread);
2949   gst_harness_thread_init (&t->t,
2950       (GDestroyNotify) gst_harness_push_buffer_thread_free, h, sleep);
2951
2952   gst_caps_replace (&t->caps, caps);
2953   t->segment = *segment;
2954   t->func = func;
2955   t->data = data;
2956   t->notify = notify;
2957
2958   GST_HARNESS_THREAD_START (buffer, t);
2959   return &t->t;
2960 }
2961
2962 /**
2963  * gst_harness_stress_push_event_start_full: (skip)
2964  * @h: a #GstHarness
2965  * @event: a #GstEvent to push
2966  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2967  * each gst_event_push with @event
2968  *
2969  * Push the @event onto the harnessed #GstElement sinkpad in intervals of
2970  * @sleep microseconds
2971  *
2972  * MT safe.
2973  *
2974  * Returns: a #GstHarnessThread
2975  *
2976  * Since: 1.6
2977  */
2978 GstHarnessThread *
2979 gst_harness_stress_push_event_start_full (GstHarness * h,
2980     GstEvent * event, gulong sleep)
2981 {
2982   GstHarnessPushEventThread *t = g_slice_new0 (GstHarnessPushEventThread);
2983   gst_harness_thread_init (&t->t,
2984       (GDestroyNotify) gst_harness_push_event_thread_free, h, sleep);
2985
2986   t->event = gst_event_ref (event);
2987   GST_HARNESS_THREAD_START (event, t);
2988   return &t->t;
2989 }
2990
2991 /**
2992  * gst_harness_stress_push_upstream_event_start_full: (skip)
2993  * @h: a #GstHarness
2994  * @event: a #GstEvent to push
2995  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2996  * each gst_event_push with @event
2997  *
2998  * Push the @event onto the harnessed #GstElement srcpad in intervals of
2999  * @sleep microseconds.
3000  * Pushing events should generally be OOB events.
3001  * If you need serialized events, you may use a custom stress thread which
3002  * both pushes buffers and events.
3003  *
3004  * MT safe.
3005  *
3006  * Returns: a #GstHarnessThread
3007  *
3008  * Since: 1.6
3009  */
3010 GstHarnessThread *
3011 gst_harness_stress_push_upstream_event_start_full (GstHarness * h,
3012     GstEvent * event, gulong sleep)
3013 {
3014   GstHarnessPushEventThread *t = g_slice_new0 (GstHarnessPushEventThread);
3015   gst_harness_thread_init (&t->t,
3016       (GDestroyNotify) gst_harness_push_event_thread_free, h, sleep);
3017
3018   t->event = gst_event_ref (event);
3019   GST_HARNESS_THREAD_START (upstream_event, t);
3020   return &t->t;
3021 }
3022
3023 /**
3024  * gst_harness_stress_property_start_full: (skip)
3025  * @h: a #GstHarness
3026  * @name: a #gchar specifying a property name
3027  * @value: a #GValue to set the property to
3028  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
3029  * each g_object_set with @name and @value
3030  *
3031  * Call g_object_set with @name and @value in intervals of @sleep microseconds
3032  *
3033  * MT safe.
3034  *
3035  * Returns: a #GstHarnessThread
3036  *
3037  * Since: 1.6
3038  */
3039 GstHarnessThread *
3040 gst_harness_stress_property_start_full (GstHarness * h,
3041     const gchar * name, const GValue * value, gulong sleep)
3042 {
3043   GstHarnessPropThread *t = g_slice_new0 (GstHarnessPropThread);
3044   gst_harness_thread_init (&t->t,
3045       (GDestroyNotify) gst_harness_property_thread_free, h, sleep);
3046
3047   t->name = g_strdup (name);
3048   g_value_init (&t->value, G_VALUE_TYPE (value));
3049   g_value_copy (value, &t->value);
3050
3051   GST_HARNESS_THREAD_START (property, t);
3052   return &t->t;
3053 }
3054
3055 /**
3056  * gst_harness_stress_requestpad_start_full: (skip)
3057  * @h: a #GstHarness
3058  * @templ: a #GstPadTemplate
3059  * @name: a #gchar
3060  * @caps: a #GstCaps
3061  * @release: a #gboolean
3062  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
3063  * each gst_element_request_pad
3064  *
3065  * Call gst_element_request_pad in intervals of @sleep microseconds
3066  *
3067  * MT safe.
3068  *
3069  * Returns: a #GstHarnessThread
3070  *
3071  * Since: 1.6
3072  */
3073 GstHarnessThread *
3074 gst_harness_stress_requestpad_start_full (GstHarness * h,
3075     GstPadTemplate * templ, const gchar * name, GstCaps * caps,
3076     gboolean release, gulong sleep)
3077 {
3078   GstHarnessReqPadThread *t = g_slice_new0 (GstHarnessReqPadThread);
3079   gst_harness_thread_init (&t->t,
3080       (GDestroyNotify) gst_harness_requestpad_thread_free, h, sleep);
3081
3082   t->templ = gst_object_ref (templ);
3083   t->name = g_strdup (name);
3084   gst_caps_replace (&t->caps, caps);
3085   t->release = release;
3086
3087   GST_HARNESS_THREAD_START (requestpad, t);
3088   return &t->t;
3089 }