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