c8313b2b1cdc27b269eb89392b18bcbd56b65d15
[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 #GstAllocatorParams
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
1903  * used
1904  * @params: (out) (allow-none) (transfer full): the
1905  * #GstAllocatorParams of @allocator
1906  *
1907  * Gets the @allocator and its @params that has been decided to use after an
1908  * allocation query.
1909  *
1910  * MT safe.
1911  *
1912  * Since: 1.6
1913  */
1914 void
1915 gst_harness_get_allocator (GstHarness * h, GstAllocator ** allocator,
1916     GstAllocationParams * params)
1917 {
1918   GstHarnessPrivate *priv = h->priv;
1919   if (allocator)
1920     *allocator = priv->allocator;
1921   if (params)
1922     *params = priv->allocation_params;
1923 }
1924
1925
1926 /**
1927  * gst_harness_set_propose_allocator:
1928  * @h: a #GstHarness
1929  * @allocator: (allow-none) (transfer full): a #GstAllocator
1930  * @params: (allow-none) (transfer none): a #GstAllocationParams
1931  *
1932  * Sets the @allocator and @params to propose when receiving an allocation
1933  * query.
1934  *
1935  * MT safe.
1936  *
1937  * Since: 1.6
1938  */
1939 void
1940 gst_harness_set_propose_allocator (GstHarness * h, GstAllocator * allocator,
1941     const GstAllocationParams * params)
1942 {
1943   GstHarnessPrivate *priv = h->priv;
1944   if (allocator)
1945     priv->propose_allocator = allocator;
1946   if (params)
1947     priv->propose_allocation_params = *params;
1948 }
1949
1950 /**
1951  * gst_harness_add_src_harness:
1952  * @h: a #GstHarness
1953  * @src_harness: (transfer full): a #GstHarness to be added as a src-harness.
1954  * @has_clock_wait: a #gboolean specifying if the #GstElement uses
1955  * gst_clock_wait_id internally.
1956  *
1957  * A src-harness is a great way of providing the #GstHarness with data.
1958  * By adding a src-type #GstElement, it is then easy to use functions like
1959  * gst_harness_push_from_src or gst_harness_src_crank_and_push_many
1960  * to provide your harnessed element with input. The @has_clock_wait variable
1961  * is a greate way to control you src-element with, in that you can have it
1962  * produce a buffer for you by simply cranking the clock, and not have it
1963  * spin out of control producing buffers as fast as possible.
1964  *
1965  * If a src-harness already exists it will be replaced.
1966  *
1967  * MT safe.
1968  *
1969  * Since: 1.6
1970  */
1971 void
1972 gst_harness_add_src_harness (GstHarness * h,
1973     GstHarness * src_harness, gboolean has_clock_wait)
1974 {
1975   if (h->src_harness)
1976     gst_harness_teardown (h->src_harness);
1977   h->src_harness = src_harness;
1978
1979   h->src_harness->priv->sink_forward_pad = gst_object_ref (h->srcpad);
1980   gst_harness_use_testclock (h->src_harness);
1981   h->src_harness->priv->has_clock_wait = has_clock_wait;
1982 }
1983
1984 /**
1985  * gst_harness_add_src:
1986  * @h: a #GstHarness
1987  * @src_element_name: a #gchar with the name of a #GstElement
1988  * @has_clock_wait: a #gboolean specifying if the #GstElement uses
1989  * gst_clock_wait_id internally.
1990  *
1991  * Similar to gst_harness_add_src_harness, this is a convenience to
1992  * directly create a src-harness using the @src_element_name name specified.
1993  *
1994  * MT safe.
1995  *
1996  * Since: 1.6
1997  */
1998 void
1999 gst_harness_add_src (GstHarness * h,
2000     const gchar * src_element_name, gboolean has_clock_wait)
2001 {
2002   GstHarness *src_harness = gst_harness_new (src_element_name);
2003   gst_harness_add_src_harness (h, src_harness, has_clock_wait);
2004 }
2005
2006 /**
2007  * gst_harness_add_src_parse:
2008  * @h: a #GstHarness
2009  * @launchline: a #gchar describing a gst-launch type line
2010  * @has_clock_wait: a #gboolean specifying if the #GstElement uses
2011  * gst_clock_wait_id internally.
2012  *
2013  * Similar to gst_harness_add_src, this allows you to specify a launch-line,
2014  * which can be useful for both having more then one #GstElement acting as your
2015  * src (Like a src producing raw buffers, and then an encoder, providing encoded
2016  * data), but also by allowing you to set properties like "is-live" directly on
2017  * the elements.
2018  *
2019  * MT safe.
2020  *
2021  * Since: 1.6
2022  */
2023 void
2024 gst_harness_add_src_parse (GstHarness * h,
2025     const gchar * launchline, gboolean has_clock_wait)
2026 {
2027   GstHarness *src_harness = gst_harness_new_parse (launchline);
2028   gst_harness_add_src_harness (h, src_harness, has_clock_wait);
2029 }
2030
2031 /**
2032  * gst_harness_push_from_src:
2033  * @h: a #GstHarness
2034  *
2035  * Transfer data from the src-#GstHarness to the main-#GstHarness. It consists
2036  * of 4 steps:
2037  * 1: Make sure the src is started. (see: gst_harness_play)
2038  * 2: Crank the clock (see: gst_harness_crank_single_clock_wait)
2039  * 3: Pull a #GstBuffer from the src-#GstHarness (see: gst_harness_pull)
2040  * 4: Push the same #GstBuffer into the main-#GstHarness (see: gst_harness_push)
2041  *
2042  * MT safe.
2043  *
2044  * Returns: a #GstFlowReturn with the result of the push
2045  *
2046  * Since: 1.6
2047  */
2048 GstFlowReturn
2049 gst_harness_push_from_src (GstHarness * h)
2050 {
2051   GstBuffer *buf;
2052
2053   g_assert (h->src_harness);
2054
2055   /* FIXME: this *is* the right time to start the src,
2056      but maybe a flag so we don't keep telling it to play? */
2057   gst_harness_play (h->src_harness);
2058
2059   if (h->src_harness->priv->has_clock_wait) {
2060     g_assert (gst_harness_crank_single_clock_wait (h->src_harness));
2061   }
2062
2063   g_assert ((buf = gst_harness_pull (h->src_harness)) != NULL);
2064   return gst_harness_push (h, buf);
2065 }
2066
2067 /**
2068  * gst_harness_src_crank_and_push_many:
2069  * @h: a #GstHarness
2070  * @cranks: a #gint with the number of calls to gst_harness_crank_single_clock_wait
2071  * @pushes: a #gint with the number of calls to gst_harness_push
2072  *
2073  * Transfer data from the src-#GstHarness to the main-#GstHarness. Similar to
2074  * gst_harness_push_from_src, this variant allows you to specify how many cranks
2075  * and how many pushes to perform. This can be useful for both moving a lot
2076  * of data at the same time, as well as cases when one crank does not equal one
2077  * buffer to push and v.v.
2078  *
2079  * MT safe.
2080  *
2081  * Returns: a #GstFlowReturn with the result of the push
2082  *
2083  * Since: 1.6
2084  */
2085 GstFlowReturn
2086 gst_harness_src_crank_and_push_many (GstHarness * h, gint cranks, gint pushes)
2087 {
2088   GstFlowReturn ret = GST_FLOW_OK;
2089
2090   g_assert (h->src_harness);
2091   gst_harness_play (h->src_harness);
2092
2093   for (int i = 0; i < cranks; i++)
2094     g_assert (gst_harness_crank_single_clock_wait (h->src_harness));
2095
2096   for (int i = 0; i < pushes; i++) {
2097     GstBuffer *buf;
2098     g_assert ((buf = gst_harness_pull (h->src_harness)) != NULL);
2099     ret = gst_harness_push (h, buf);
2100     if (ret != GST_FLOW_OK)
2101       break;
2102   }
2103
2104   return ret;
2105 }
2106
2107 /**
2108  * gst_harness_src_push_event:
2109  * @h: a #GstHarness
2110  *
2111  * Similar to what gst_harness_src_push does with #GstBuffers, this transfers
2112  * a #GstEvent from the src-#GstHarness to the main-#GstHarness. Note that
2113  * some #GstEvents are being transferred automagically. Look at sink_forward_pad
2114  * for details.
2115  *
2116  * MT safe.
2117  *
2118  * Returns: a #gboolean with the result of the push
2119  *
2120  * Since: 1.6
2121  */
2122 gboolean
2123 gst_harness_src_push_event (GstHarness * h)
2124 {
2125   return gst_harness_push_event (h, gst_harness_pull_event (h->src_harness));
2126 }
2127
2128
2129 static gboolean
2130 forward_sticky_events (GstPad * pad, GstEvent ** ev, gpointer user_data)
2131 {
2132   GstHarness *h = user_data;
2133   return gst_pad_push_event (h->priv->sink_forward_pad, gst_event_ref (*ev));
2134 }
2135
2136 /**
2137  * gst_harness_add_sink_harness:
2138  * @h: a #GstHarness
2139  * @sink_harness: (transfer full): a #GstHarness to be added as a sink-harness.
2140  *
2141  * Similar to gst_harness_add_src, this allows you to send the data coming out
2142  * of your harnessed #GstElement to a sink-element, allowing to test different
2143  * responses the element output might create in sink elements. An example might
2144  * be an existing sink providing some analytical data on the input it receives that
2145  * can be useful to your testing. If the goal is to test a sink-element itself,
2146  * this is better acheived using gst_harness_new directly on the sink.
2147  *
2148  * If a sink-harness already exists it will be replaced.
2149  *
2150  * MT safe.
2151  *
2152  * Since: 1.6
2153  */
2154 void
2155 gst_harness_add_sink_harness (GstHarness * h, GstHarness * sink_harness)
2156 {
2157   GstHarnessPrivate *priv = h->priv;
2158
2159   if (h->sink_harness) {
2160     gst_harness_teardown (h->sink_harness);
2161     gst_object_unref (priv->sink_forward_pad);
2162   }
2163   h->sink_harness = sink_harness;
2164   priv->sink_forward_pad = gst_object_ref (h->sink_harness->srcpad);
2165   gst_harness_use_testclock (h->sink_harness);
2166   gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h);
2167 }
2168
2169 /**
2170  * gst_harness_add_sink:
2171  * @h: a #GstHarness
2172  * @sink_element_name: a #gchar with the name of a #GstElement
2173  *
2174  * Similar to gst_harness_add_sink_harness, this is a convenience to
2175  * directly create a sink-harness using the @sink_element_name name specified.
2176  *
2177  * MT safe.
2178  *
2179  * Since: 1.6
2180  */
2181 void
2182 gst_harness_add_sink (GstHarness * h, const gchar * sink_element_name)
2183 {
2184   GstHarness *sink_harness = gst_harness_new (sink_element_name);
2185   gst_harness_add_sink_harness (h, sink_harness);
2186 }
2187
2188 /**
2189  * gst_harness_add_sink_parse:
2190  * @h: a #GstHarness
2191  * @launchline: a #gchar with the name of a #GstElement
2192  *
2193  * Similar to gst_harness_add_sink, this allows you to specify a launch-line
2194  * instead of just an element name. See gst_harness_add_src_parse for details.
2195  *
2196  * MT safe.
2197  *
2198  * Since: 1.6
2199  */
2200 void
2201 gst_harness_add_sink_parse (GstHarness * h, const gchar * launchline)
2202 {
2203   GstHarness *sink_harness = gst_harness_new_parse (launchline);
2204   gst_harness_add_sink_harness (h, sink_harness);
2205 }
2206
2207 /**
2208  * gst_harness_push_to_sink:
2209  * @h: a #GstHarness
2210  *
2211  * Transfer one #GstBuffer from the main-#GstHarness to the sink-#GstHarness.
2212  * See gst_harness_push_from_src for details.
2213  *
2214  * MT safe.
2215  *
2216  * Returns: a #GstFlowReturn with the result of the push
2217  *
2218  * Since: 1.6
2219  */
2220 GstFlowReturn
2221 gst_harness_push_to_sink (GstHarness * h)
2222 {
2223   GstBuffer *buf;
2224   g_assert (h->sink_harness);
2225   g_assert ((buf = gst_harness_pull (h)) != NULL);
2226   return gst_harness_push (h->sink_harness, buf);
2227 }
2228
2229 /**
2230  * gst_harness_sink_push_many:
2231  * @h: a #GstHarness
2232  * @pushes: a #gint with the number of calls to gst_harness_push_to_sink
2233  *
2234  * Convenience that calls gst_harness_push_to_sink @pushes number of times.
2235  * Will abort the pushing if any one push fails.
2236  *
2237  * MT safe.
2238  *
2239  * Returns: a #GstFlowReturn with the result of the push
2240  *
2241  * Since: 1.6
2242  */
2243 GstFlowReturn
2244 gst_harness_sink_push_many (GstHarness * h, gint pushes)
2245 {
2246   GstFlowReturn ret = GST_FLOW_OK;
2247   g_assert (h->sink_harness);
2248   for (int i = 0; i < pushes; i++) {
2249     ret = gst_harness_push_to_sink (h);
2250     if (ret != GST_FLOW_OK)
2251       break;
2252   }
2253   return ret;
2254 }
2255
2256 /**
2257  * gst_harness_find_element:
2258  * @h: a #GstHarness
2259  * @element_name: a #gchar with a #GstElementFactory name
2260  *
2261  * Most useful in conjunction with gst_harness_new_parse, this will scan the
2262  * #GstElements inside the #GstHarness, and check if any of them matches
2263  * @element_name. Typical usecase being that you need to access one of the
2264  * harnessed elements for properties and/or signals.
2265  *
2266  * MT safe.
2267  *
2268  * Returns: (transfer full) (allow-none): a #GstElement or %NULL if not found
2269  *
2270  * Since: 1.6
2271  */
2272 GstElement *
2273 gst_harness_find_element (GstHarness * h, const gchar * element_name)
2274 {
2275   gboolean done = FALSE;
2276   GstIterator *iter;
2277   GValue data = G_VALUE_INIT;
2278
2279   iter = gst_bin_iterate_elements (GST_BIN (h->element));
2280   done = FALSE;
2281
2282   while (!done) {
2283     switch (gst_iterator_next (iter, &data)) {
2284       case GST_ITERATOR_OK:
2285       {
2286         GstElement *element = g_value_get_object (&data);
2287         GstPluginFeature *feature =
2288             GST_PLUGIN_FEATURE (gst_element_get_factory (element));
2289         if (!strcmp (element_name, gst_plugin_feature_get_name (feature))) {
2290           gst_iterator_free (iter);
2291           return element;
2292         }
2293         g_value_reset (&data);
2294         break;
2295       }
2296       case GST_ITERATOR_RESYNC:
2297         gst_iterator_resync (iter);
2298         break;
2299       case GST_ITERATOR_ERROR:
2300       case GST_ITERATOR_DONE:
2301         done = TRUE;
2302         break;
2303     }
2304   }
2305   gst_iterator_free (iter);
2306
2307   return NULL;
2308 }
2309
2310 /**
2311  * gst_harness_set:
2312  * @h: a #GstHarness
2313  * @element_name: a #gchar with a #GstElementFactory name
2314  * @first_property_name: a #gchar with the first property name
2315  * @...: value for the first property, followed optionally by more
2316  *  name/value pairs, followed by %NULL
2317  *
2318  * A convenience function to allows you to call g_object_set on a #GstElement
2319  * that are residing inside the #GstHarness, by using normal g_object_set
2320  * syntax.
2321  *
2322  * MT safe.
2323  *
2324  * Since: 1.6
2325  */
2326 void
2327 gst_harness_set (GstHarness * h,
2328     const gchar * element_name, const gchar * first_property_name, ...)
2329 {
2330   va_list var_args;
2331   GstElement *element = gst_harness_find_element (h, element_name);
2332   va_start (var_args, first_property_name);
2333   g_object_set_valist (G_OBJECT (element), first_property_name, var_args);
2334   va_end (var_args);
2335   gst_object_unref (element);
2336 }
2337
2338 /**
2339  * gst_harness_get:
2340  * @h: a #GstHarness
2341  * @element_name: a #gchar with a #GstElementFactory name
2342  * @first_property_name: a #gchar with the first property name
2343  * @...: return location for the first property, followed optionally by more
2344  *  name/return location pairs, followed by %NULL
2345  *
2346  * A convenience function to allows you to call g_object_get on a #GstElement
2347  * that are residing inside the #GstHarness, by using normal g_object_get
2348  * syntax.
2349  *
2350  * MT safe.
2351  *
2352  * Since: 1.6
2353  */
2354 void
2355 gst_harness_get (GstHarness * h,
2356     const gchar * element_name, const gchar * first_property_name, ...)
2357 {
2358   va_list var_args;
2359   GstElement *element = gst_harness_find_element (h, element_name);
2360   va_start (var_args, first_property_name);
2361   g_object_get_valist (G_OBJECT (element), first_property_name, var_args);
2362   va_end (var_args);
2363   gst_object_unref (element);
2364 }
2365
2366 /**
2367  * gst_harness_add_probe:
2368  * @h: a #GstHarness
2369  * @element_name: a #gchar with a #GstElementFactory name
2370  * @pad_name: a #gchar with the name of the pad to attach the probe to
2371  * @mask: a #GstPadProbeType (see gst_pad_add_probe)
2372  * @callback: a #GstPadProbeCallback (see gst_pad_add_probe)
2373  * @user_data: a #gpointer (see gst_pad_add_probe)
2374  * @destroy_data: a #GDestroyNotify (see gst_pad_add_probe)
2375  *
2376  * A convenience function to allows you to call gst_pad_add_probe on a
2377  * #GstPad of a #GstElement that are residing inside the #GstHarness,
2378  * by using normal gst_pad_add_probe syntax
2379  *
2380  * MT safe.
2381  *
2382  * Since: 1.6
2383  */
2384 void
2385 gst_harness_add_probe (GstHarness * h,
2386     const gchar * element_name, const gchar * pad_name, GstPadProbeType mask,
2387     GstPadProbeCallback callback, gpointer user_data,
2388     GDestroyNotify destroy_data)
2389 {
2390   GstElement *element = gst_harness_find_element (h, element_name);
2391   GstPad *pad = gst_element_get_static_pad (element, pad_name);
2392   gst_pad_add_probe (pad, mask, callback, user_data, destroy_data);
2393   gst_object_unref (pad);
2394   gst_object_unref (element);
2395 }
2396
2397 /******************************************************************************/
2398 /*       STRESS                                                               */
2399 /******************************************************************************/
2400 struct _GstHarnessThread
2401 {
2402   GstHarness *h;
2403   GThread *thread;
2404   gboolean running;
2405
2406   gulong sleep;
2407
2408   GDestroyNotify freefunc;
2409 };
2410
2411 typedef struct
2412 {
2413   GstHarnessThread t;
2414
2415   GFunc init;
2416   GFunc callback;
2417   gpointer data;
2418 } GstHarnessCustomThread;
2419
2420 typedef struct
2421 {
2422   GstHarnessThread t;
2423
2424   GstCaps *caps;
2425   GstSegment segment;
2426   GstHarnessPrepareBufferFunc func;
2427   gpointer data;
2428   GDestroyNotify notify;
2429 } GstHarnessPushBufferThread;
2430
2431 typedef struct
2432 {
2433   GstHarnessThread t;
2434
2435   GstEvent *event;
2436 } GstHarnessPushEventThread;
2437
2438 typedef struct
2439 {
2440   GstHarnessThread t;
2441
2442   gchar *name;
2443   GValue value;
2444 } GstHarnessPropThread;
2445
2446 typedef struct
2447 {
2448   GstHarnessThread t;
2449
2450   GstPadTemplate *templ;
2451   gchar *name;
2452   GstCaps *caps;
2453   gboolean release;
2454
2455   GSList *pads;
2456 } GstHarnessReqPadThread;
2457
2458 static void
2459 gst_harness_thread_init (GstHarnessThread * t, GDestroyNotify freefunc,
2460     GstHarness * h, gulong sleep)
2461 {
2462   t->freefunc = freefunc;
2463   t->h = h;
2464   t->sleep = sleep;
2465
2466   g_ptr_array_add (h->priv->stress, t);
2467 }
2468
2469 static void
2470 gst_harness_thread_free (GstHarnessThread * t)
2471 {
2472   g_slice_free (GstHarnessThread, t);
2473 }
2474
2475 static void
2476 gst_harness_custom_thread_free (GstHarnessCustomThread * t)
2477 {
2478   g_slice_free (GstHarnessCustomThread, t);
2479 }
2480
2481 static void
2482 gst_harness_push_buffer_thread_free (GstHarnessPushBufferThread * t)
2483 {
2484   if (t != NULL) {
2485     gst_caps_replace (&t->caps, NULL);
2486     if (t->notify != NULL)
2487       t->notify (t->data);
2488     g_slice_free (GstHarnessPushBufferThread, t);
2489   }
2490 }
2491
2492 static void
2493 gst_harness_push_event_thread_free (GstHarnessPushEventThread * t)
2494 {
2495   if (t != NULL) {
2496     gst_event_replace (&t->event, NULL);
2497     g_slice_free (GstHarnessPushEventThread, t);
2498   }
2499 }
2500
2501 static void
2502 gst_harness_property_thread_free (GstHarnessPropThread * t)
2503 {
2504   if (t != NULL) {
2505     g_free (t->name);
2506     g_value_unset (&t->value);
2507     g_slice_free (GstHarnessPropThread, t);
2508   }
2509 }
2510
2511 static void
2512 gst_harness_requestpad_release (GstPad * pad, GstElement * element)
2513 {
2514   gst_element_release_request_pad (element, pad);
2515   gst_object_unref (pad);
2516 }
2517
2518 static void
2519 gst_harness_requestpad_release_pads (GstHarnessReqPadThread * rpt)
2520 {
2521   g_slist_foreach (rpt->pads, (GFunc) gst_harness_requestpad_release,
2522       rpt->t.h->element);
2523   g_slist_free (rpt->pads);
2524   rpt->pads = NULL;
2525 }
2526
2527 static void
2528 gst_harness_requestpad_thread_free (GstHarnessReqPadThread * t)
2529 {
2530   if (t != NULL) {
2531     gst_object_replace ((GstObject **) & t->templ, NULL);
2532     g_free (t->name);
2533     gst_caps_replace (&t->caps, NULL);
2534
2535     gst_harness_requestpad_release_pads (t);
2536     g_slice_free (GstHarnessReqPadThread, t);
2537   }
2538 }
2539
2540 #define GST_HARNESS_THREAD_START(ID, t)                                        \
2541   (((GstHarnessThread *)t)->running = TRUE,                                    \
2542   ((GstHarnessThread *)t)->thread = g_thread_new (                             \
2543       "gst-harness-stress-"G_STRINGIFY(ID),                                    \
2544       (GThreadFunc)gst_harness_stress_##ID##_func, t))
2545 #define GST_HARNESS_THREAD_END(t)                                              \
2546    (t->running = FALSE,                                                        \
2547    GPOINTER_TO_UINT (g_thread_join (t->thread)))
2548
2549 static void
2550 gst_harness_stress_free (GstHarnessThread * t)
2551 {
2552   if (t != NULL && t->freefunc != NULL)
2553     t->freefunc (t);
2554 }
2555
2556 static gpointer
2557 gst_harness_stress_custom_func (GstHarnessThread * t)
2558 {
2559   GstHarnessCustomThread *ct = (GstHarnessCustomThread *) t;
2560   guint count = 0;
2561
2562   ct->init (ct, ct->data);
2563
2564   while (t->running) {
2565     ct->callback (ct, ct->data);
2566
2567     count++;
2568     g_usleep (t->sleep);
2569   }
2570   return GUINT_TO_POINTER (count);
2571 }
2572
2573
2574 static gpointer
2575 gst_harness_stress_statechange_func (GstHarnessThread * t)
2576 {
2577   guint count = 0;
2578
2579   while (t->running) {
2580     GstClock *clock = gst_element_get_clock (t->h->element);
2581     GstIterator *it;
2582     gboolean done = FALSE;
2583
2584     g_assert (gst_element_set_state (t->h->element, GST_STATE_NULL) ==
2585         GST_STATE_CHANGE_SUCCESS);
2586     g_thread_yield ();
2587
2588     it = gst_element_iterate_sink_pads (t->h->element);
2589     while (!done) {
2590       GValue item = G_VALUE_INIT;
2591       switch (gst_iterator_next (it, &item)) {
2592         case GST_ITERATOR_OK:
2593         {
2594           GstPad *sinkpad = g_value_get_object (&item);
2595           GstPad *srcpad = gst_pad_get_peer (sinkpad);
2596           if (srcpad != NULL) {
2597             gst_pad_unlink (srcpad, sinkpad);
2598             gst_pad_link (srcpad, sinkpad);
2599             gst_object_unref (srcpad);
2600           }
2601           g_value_reset (&item);
2602           break;
2603         }
2604         case GST_ITERATOR_RESYNC:
2605           gst_iterator_resync (it);
2606           break;
2607         case GST_ITERATOR_ERROR:
2608           g_assert_not_reached ();
2609         case GST_ITERATOR_DONE:
2610           done = TRUE;
2611           break;
2612       }
2613       g_value_unset (&item);
2614     }
2615     gst_iterator_free (it);
2616
2617     if (clock != NULL) {
2618       gst_element_set_clock (t->h->element, clock);
2619       gst_object_unref (clock);
2620     }
2621     g_assert (gst_element_set_state (t->h->element, GST_STATE_PLAYING) ==
2622         GST_STATE_CHANGE_SUCCESS);
2623
2624     count++;
2625     g_usleep (t->sleep);
2626   }
2627   return GUINT_TO_POINTER (count);
2628 }
2629
2630 static gpointer
2631 gst_harness_stress_buffer_func (GstHarnessThread * t)
2632 {
2633   GstHarnessPushBufferThread *pt = (GstHarnessPushBufferThread *) t;
2634   guint count = 0;
2635   gchar *sid;
2636
2637   /* Push stream start, caps and segment events */
2638   sid = g_strdup_printf ("%s-%p", GST_OBJECT_NAME (t->h->element), t->h);
2639   g_assert (gst_pad_push_event (t->h->srcpad,
2640           gst_event_new_stream_start (sid)));
2641   g_free (sid);
2642   g_assert (gst_pad_push_event (t->h->srcpad, gst_event_new_caps (pt->caps)));
2643   g_assert (gst_pad_push_event (t->h->srcpad,
2644           gst_event_new_segment (&pt->segment)));
2645
2646   while (t->running) {
2647     gst_harness_push (t->h, pt->func (t->h, pt->data));
2648
2649     count++;
2650     g_usleep (t->sleep);
2651   }
2652   return GUINT_TO_POINTER (count);
2653 }
2654
2655 static gpointer
2656 gst_harness_stress_event_func (GstHarnessThread * t)
2657 {
2658   GstHarnessPushEventThread *pet = (GstHarnessPushEventThread *) t;
2659   guint count = 0;
2660
2661   while (t->running) {
2662     gst_harness_push_event (t->h, gst_event_ref (pet->event));
2663
2664     count++;
2665     g_usleep (t->sleep);
2666   }
2667   return GUINT_TO_POINTER (count);
2668 }
2669
2670 static gpointer
2671 gst_harness_stress_upstream_event_func (GstHarnessThread * t)
2672 {
2673   GstHarnessPushEventThread *pet = (GstHarnessPushEventThread *) t;
2674   guint count = 0;
2675
2676   while (t->running) {
2677     gst_harness_push_upstream_event (t->h, gst_event_ref (pet->event));
2678
2679     count++;
2680     g_usleep (t->sleep);
2681   }
2682   return GUINT_TO_POINTER (count);
2683 }
2684
2685 static gpointer
2686 gst_harness_stress_property_func (GstHarnessThread * t)
2687 {
2688   GstHarnessPropThread *pt = (GstHarnessPropThread *) t;
2689   guint count = 0;
2690
2691   while (t->running) {
2692     GValue value = G_VALUE_INIT;
2693
2694     g_object_set_property (G_OBJECT (t->h->element), pt->name, &pt->value);
2695
2696     g_value_init (&value, G_VALUE_TYPE (&pt->value));
2697     g_object_get_property (G_OBJECT (t->h->element), pt->name, &value);
2698     g_value_reset (&value);
2699
2700     count++;
2701     g_usleep (t->sleep);
2702   }
2703   return GUINT_TO_POINTER (count);
2704 }
2705
2706 static gpointer
2707 gst_harness_stress_requestpad_func (GstHarnessThread * t)
2708 {
2709   GstHarnessReqPadThread *rpt = (GstHarnessReqPadThread *) t;
2710   guint count = 0;
2711
2712   while (t->running) {
2713     GstPad *reqpad;
2714
2715     if (rpt->release)
2716       gst_harness_requestpad_release_pads (rpt);
2717
2718     g_thread_yield ();
2719
2720     reqpad = gst_element_request_pad (t->h->element,
2721         rpt->templ, rpt->name, rpt->caps);
2722
2723     g_assert (reqpad != NULL);
2724
2725     rpt->pads = g_slist_prepend (rpt->pads, reqpad);
2726
2727     count++;
2728     g_usleep (t->sleep);
2729   }
2730   return GUINT_TO_POINTER (count);
2731 }
2732
2733 /**
2734  * gst_harness_stress_thread_stop:
2735  * @t: a #GstHarnessThread
2736  *
2737  * Stop the running #GstHarnessThread
2738  *
2739  * MT safe.
2740  *
2741  * Since: 1.6
2742  */
2743 guint
2744 gst_harness_stress_thread_stop (GstHarnessThread * t)
2745 {
2746   guint ret;
2747
2748   g_return_val_if_fail (t != NULL, 0);
2749
2750   ret = GST_HARNESS_THREAD_END (t);
2751   g_ptr_array_remove (t->h->priv->stress, t);
2752   return ret;
2753 }
2754
2755 /**
2756  * gst_harness_stress_custom_start: (skip)
2757  * @h: a #GstHarness
2758  * @init: a #GFunc that is called initially and only once
2759  * @callback: a #GFunc that is called as often as possible
2760  * @data: a #gpointer with custom data to pass to the @callback function
2761  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2762  * each call to the @callback
2763  *
2764  * Start a custom stress-thread that will call your @callback for every
2765  * iteration allowing you to do something nasty.
2766  *
2767  * MT safe.
2768  *
2769  * Returns: a #GstHarnessThread
2770  *
2771  * Since: 1.6
2772  */
2773 GstHarnessThread *
2774 gst_harness_stress_custom_start (GstHarness * h,
2775     GFunc init, GFunc callback, gpointer data, gulong sleep)
2776 {
2777   GstHarnessCustomThread *t = g_slice_new0 (GstHarnessCustomThread);
2778   gst_harness_thread_init (&t->t,
2779       (GDestroyNotify) gst_harness_custom_thread_free, h, sleep);
2780
2781   t->init = init;
2782   t->callback = callback;
2783   t->data = data;
2784
2785   GST_HARNESS_THREAD_START (custom, t);
2786   return &t->t;
2787 }
2788
2789 /**
2790  * gst_harness_stress_statechange_start_full: (skip)
2791  * @h: a #GstHarness
2792  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2793  * each state-change
2794  *
2795  * Change the state of your harnessed #GstElement from NULL to PLAYING and
2796  * back again, only pausing for @sleep microseconds every time.
2797  *
2798  * MT safe.
2799  *
2800  * Returns: a #GstHarnessThread
2801  *
2802  * Since: 1.6
2803  */
2804 GstHarnessThread *
2805 gst_harness_stress_statechange_start_full (GstHarness * h, gulong sleep)
2806 {
2807   GstHarnessThread *t = g_slice_new0 (GstHarnessThread);
2808   gst_harness_thread_init (t,
2809       (GDestroyNotify) gst_harness_thread_free, h, sleep);
2810   GST_HARNESS_THREAD_START (statechange, t);
2811   return t;
2812 }
2813
2814 static GstBuffer *
2815 gst_harness_ref_buffer (GstHarness * h, gpointer data)
2816 {
2817   (void) h;
2818   return gst_buffer_ref (GST_BUFFER_CAST (data));
2819 }
2820
2821 /**
2822  * gst_harness_stress_push_buffer_start_full: (skip)
2823  * @h: a #GstHarness
2824  * @caps: a #GstCaps for the #GstBuffer
2825  * @segment: a #GstSegment
2826  * @buf: a #GstBuffer to push
2827  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2828  * each call to gst_pad_push
2829  *
2830  * Push a #GstBuffer in intervals of @sleep microseconds.
2831  *
2832  * MT safe.
2833  *
2834  * Returns: a #GstHarnessThread
2835  *
2836  * Since: 1.6
2837  */
2838 GstHarnessThread *
2839 gst_harness_stress_push_buffer_start_full (GstHarness * h,
2840     GstCaps * caps, const GstSegment * segment, GstBuffer * buf, gulong sleep)
2841 {
2842   return gst_harness_stress_push_buffer_with_cb_start_full (h, caps, segment,
2843       gst_harness_ref_buffer, gst_buffer_ref (buf),
2844       (GDestroyNotify) gst_buffer_unref, sleep);
2845 }
2846
2847 /**
2848  * gst_harness_stress_push_buffer_with_cb_start_full: (skip)
2849  * @h: a #GstHarness
2850  * @caps: a #GstCaps for the #GstBuffer
2851  * @segment: a #GstSegment
2852  * @func: a #GstHarnessPrepareBufferFunc function called before every iteration
2853  * to prepare / create a #GstBuffer for pushing
2854  * @data: a #gpointer with data to the #GstHarnessPrepareBufferFunc function
2855  * @notify: a #GDestroyNotify that is called for every push to allow cleaning
2856  * up the #GstBuffer. (like gst_buffer_unref)
2857  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2858  * each call to gst_pad_push
2859  *
2860  * Push a #GstBuffer in intervals of @sleep microseconds.
2861  *
2862  * MT safe.
2863  *
2864  * Returns: a #GstHarnessThread
2865  *
2866  * Since: 1.6
2867  */
2868 GstHarnessThread *
2869 gst_harness_stress_push_buffer_with_cb_start_full (GstHarness * h,
2870     GstCaps * caps, const GstSegment * segment,
2871     GstHarnessPrepareBufferFunc func, gpointer data, GDestroyNotify notify,
2872     gulong sleep)
2873 {
2874   GstHarnessPushBufferThread *t = g_slice_new0 (GstHarnessPushBufferThread);
2875   gst_harness_thread_init (&t->t,
2876       (GDestroyNotify) gst_harness_push_buffer_thread_free, h, sleep);
2877
2878   gst_caps_replace (&t->caps, caps);
2879   t->segment = *segment;
2880   t->func = func;
2881   t->data = data;
2882   t->notify = notify;
2883
2884   GST_HARNESS_THREAD_START (buffer, t);
2885   return &t->t;
2886 }
2887
2888 /**
2889  * gst_harness_stress_push_event_start_full: (skip)
2890  * @h: a #GstHarness
2891  * @event: a #GstEvent to push
2892  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2893  * each gst_event_push with @event
2894  *
2895  * Push the @event onto the harnessed #GstElement sinkpad in intervals of
2896  * @sleep microseconds
2897  *
2898  * MT safe.
2899  *
2900  * Returns: a #GstHarnessThread
2901  *
2902  * Since: 1.6
2903  */
2904 GstHarnessThread *
2905 gst_harness_stress_push_event_start_full (GstHarness * h,
2906     GstEvent * event, gulong sleep)
2907 {
2908   GstHarnessPushEventThread *t = g_slice_new0 (GstHarnessPushEventThread);
2909   gst_harness_thread_init (&t->t,
2910       (GDestroyNotify) gst_harness_push_event_thread_free, h, sleep);
2911
2912   t->event = gst_event_ref (event);
2913   GST_HARNESS_THREAD_START (event, t);
2914   return &t->t;
2915 }
2916
2917 /**
2918  * gst_harness_stress_push_upstream_event_start_full: (skip)
2919  * @h: a #GstHarness
2920  * @event: a #GstEvent to push
2921  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2922  * each gst_event_push with @event
2923  *
2924  * Push the @event onto the harnessed #GstElement srcpad in intervals of
2925  * @sleep microseconds.
2926  * Pushing events should generally be OOB events.
2927  * If you need serialized events, you may use a custom stress thread which
2928  * both pushes buffers and events.
2929  *
2930  * MT safe.
2931  *
2932  * Returns: a #GstHarnessThread
2933  *
2934  * Since: 1.6
2935  */
2936 GstHarnessThread *
2937 gst_harness_stress_push_upstream_event_start_full (GstHarness * h,
2938     GstEvent * event, gulong sleep)
2939 {
2940   GstHarnessPushEventThread *t = g_slice_new0 (GstHarnessPushEventThread);
2941   gst_harness_thread_init (&t->t,
2942       (GDestroyNotify) gst_harness_push_event_thread_free, h, sleep);
2943
2944   t->event = gst_event_ref (event);
2945   GST_HARNESS_THREAD_START (upstream_event, t);
2946   return &t->t;
2947 }
2948
2949 /**
2950  * gst_harness_stress_property_start_full: (skip)
2951  * @h: a #GstHarness
2952  * @name: a #gchar specifying a property name
2953  * @value: a #GValue to set the property to
2954  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2955  * each g_object_set with @name and @value
2956  *
2957  * Call g_object_set with @name and @value in intervals of @sleep microseconds
2958  *
2959  * MT safe.
2960  *
2961  * Returns: a #GstHarnessThread
2962  *
2963  * Since: 1.6
2964  */
2965 GstHarnessThread *
2966 gst_harness_stress_property_start_full (GstHarness * h,
2967     const gchar * name, const GValue * value, gulong sleep)
2968 {
2969   GstHarnessPropThread *t = g_slice_new0 (GstHarnessPropThread);
2970   gst_harness_thread_init (&t->t,
2971       (GDestroyNotify) gst_harness_property_thread_free, h, sleep);
2972
2973   t->name = g_strdup (name);
2974   g_value_init (&t->value, G_VALUE_TYPE (value));
2975   g_value_copy (value, &t->value);
2976
2977   GST_HARNESS_THREAD_START (property, t);
2978   return &t->t;
2979 }
2980
2981 /**
2982  * gst_harness_stress_requestpad_start_full: (skip)
2983  * @h: a #GstHarness
2984  * @templ: a #GstPadTemplate
2985  * @name: a #gchar
2986  * @caps: a #GstCaps
2987  * @release: a #gboolean
2988  * @sleep: a #gulong specifying how long to sleep in (microseconds) for
2989  * each gst_element_request_pad
2990  *
2991  * Call gst_element_request_pad in intervals of @sleep microseconds
2992  *
2993  * MT safe.
2994  *
2995  * Returns: a #GstHarnessThread
2996  *
2997  * Since: 1.6
2998  */
2999 GstHarnessThread *
3000 gst_harness_stress_requestpad_start_full (GstHarness * h,
3001     GstPadTemplate * templ, const gchar * name, GstCaps * caps,
3002     gboolean release, gulong sleep)
3003 {
3004   GstHarnessReqPadThread *t = g_slice_new0 (GstHarnessReqPadThread);
3005   gst_harness_thread_init (&t->t,
3006       (GDestroyNotify) gst_harness_requestpad_thread_free, h, sleep);
3007
3008   t->templ = gst_object_ref (templ);
3009   t->name = g_strdup (name);
3010   gst_caps_replace (&t->caps, caps);
3011   t->release = release;
3012
3013   GST_HARNESS_THREAD_START (requestpad, t);
3014   return &t->t;
3015 }