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