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