From: Havard Graff Date: Wed, 9 Dec 2015 02:43:38 +0000 (+1100) Subject: harness: enable empty harness creation and refactor around this X-Git-Tag: 1.10.4~429 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cc4e4ae029f7541c4b4702abaa29515245e791c6;p=platform%2Fupstream%2Fgstreamer.git harness: enable empty harness creation and refactor around this Also make the testclock a member of the harness, allowing some more interactions with the clock prior to adding elements. https://bugzilla.gnome.org/show_bug.cgi?id=761905 --- diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 8ce50f1..36f3141 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -1215,12 +1215,15 @@ gst_consistency_checker_add_pad gst/check/check.h GstHarness +gst_harness_new_empty gst_harness_new_full gst_harness_new_with_element gst_harness_new_with_padnames gst_harness_new_with_templates gst_harness_new gst_harness_new_parse +gst_harness_add_element_full +gst_harness_add_parse gst_harness_teardown gst_harness_add_element_src_pad diff --git a/libs/gst/check/Makefile.am b/libs/gst/check/Makefile.am index 57593ea..aada085 100644 --- a/libs/gst/check/Makefile.am +++ b/libs/gst/check/Makefile.am @@ -96,7 +96,9 @@ LIBGSTCHECK_EXPORTED_FUNCS = \ gst_consistency_checker_new \ gst_consistency_checker_reset \ gst_consistency_checker_free \ + gst_harness_add_element_full \ gst_harness_add_element_src_pad \ + gst_harness_add_parse \ gst_harness_add_probe \ gst_harness_add_sink \ gst_harness_add_sink_harness \ @@ -118,6 +120,7 @@ LIBGSTCHECK_EXPORTED_FUNCS = \ gst_harness_get_last_pushed_timestamp \ gst_harness_get_testclock \ gst_harness_new \ + gst_harness_new_empty \ gst_harness_new_full \ gst_harness_new_parse \ gst_harness_new_with_element \ diff --git a/libs/gst/check/gstharness.c b/libs/gst/check/gstharness.c index 955e929..ccacd4d 100644 --- a/libs/gst/check/gstharness.c +++ b/libs/gst/check/gstharness.c @@ -159,6 +159,7 @@ struct _GstHarnessPrivate gboolean forwarding; GstPad *sink_forward_pad; + GstTestClock *testclock; volatile gint recv_buffers; volatile gint recv_events; @@ -603,39 +604,23 @@ gst_pad_is_request_pad (GstPad * pad) } /** - * gst_harness_new_full: (skip) - * @element: a #GstElement to attach the harness to (transfer none) - * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad. - * %NULL will not create a harness srcpad. - * @element_sinkpad_name: (allow-none): a #gchar with the name of the element - * sinkpad that is then linked to the harness srcpad. Can be a static or request - * or a sometimes pad that has been added. %NULL will not get/request a sinkpad - * from the element. (Like if the element is a src.) - * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad. - * %NULL will not create a harness sinkpad. - * @element_srcpad_name: (allow-none): a #gchar with the name of the element - * srcpad that is then linked to the harness sinkpad, similar to the - * @element_sinkpad_name. + * gst_harness_new_empty: (skip) * - * Creates a new harness. + * Creates a new empty harness. Use gst_harness_add_element_full() to add + * an #GstElement to it. * * MT safe. * * Returns: (transfer full): a #GstHarness, or %NULL if the harness could * not be created * - * Since: 1.6 + * Since: 1.8 */ GstHarness * -gst_harness_new_full (GstElement * element, - GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name, - GstStaticPadTemplate * hsink, const gchar * element_srcpad_name) +gst_harness_new_empty (void) { GstHarness *h; GstHarnessPrivate *priv; - gboolean has_sinkpad, has_srcpad; - - g_return_val_if_fail (element != NULL, NULL); h = g_new0 (GstHarness, 1); g_assert (h != NULL); @@ -643,11 +628,11 @@ gst_harness_new_full (GstElement * element, priv = h->priv; GST_DEBUG_OBJECT (h, "about to create new harness %p", h); - h->element = gst_object_ref (element); priv->last_push_ts = GST_CLOCK_TIME_NONE; priv->latency_min = 0; priv->latency_max = GST_CLOCK_TIME_NONE; priv->drop_buffers = FALSE; + priv->testclock = GST_TEST_CLOCK_CAST (gst_test_clock_new ()); priv->propose_allocator = NULL; gst_allocation_params_init (&priv->propose_allocation_params); @@ -655,6 +640,48 @@ gst_harness_new_full (GstElement * element, g_mutex_init (&priv->blocking_push_mutex); g_cond_init (&priv->blocking_push_cond); + priv->stress = g_ptr_array_new_with_free_func ( + (GDestroyNotify) gst_harness_stress_free); + + /* we have forwarding on as a default */ + gst_harness_set_forwarding (h, TRUE); + + return h; +} + +/** + * gst_harness_add_element_full: (skip) + * @h: a #GstHarness + * @element: a #GstElement to add to the harness (transfer none) + * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad. + * %NULL will not create a harness srcpad. + * @element_sinkpad_name: (allow-none): a #gchar with the name of the element + * sinkpad that is then linked to the harness srcpad. Can be a static or request + * or a sometimes pad that has been added. %NULL will not get/request a sinkpad + * from the element. (Like if the element is a src.) + * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad. + * %NULL will not create a harness sinkpad. + * @element_srcpad_name: (allow-none): a #gchar with the name of the element + * srcpad that is then linked to the harness sinkpad, similar to the + * @element_sinkpad_name. + * + * Adds a #GstElement to an empty #GstHarness + * + * MT safe. + * + * Since: 1.6 + */ +void +gst_harness_add_element_full (GstHarness * h, GstElement * element, + GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name, + GstStaticPadTemplate * hsink, const gchar * element_srcpad_name) +{ + gboolean has_sinkpad, has_srcpad; + + g_return_if_fail (element != NULL); + g_return_if_fail (h->element == NULL); + + h->element = gst_object_ref (element); check_element_type (element, &has_sinkpad, &has_srcpad); /* setup the loose srcpad linked to the element sinkpad */ @@ -683,19 +710,53 @@ gst_harness_new_full (GstElement * element, if (has_sinkpad) gst_harness_play (h); + /* if the element already has a testclock attached, we replace our own with it */ + if (GST_ELEMENT_CLOCK (element) && GST_IS_TEST_CLOCK (GST_ELEMENT_CLOCK (element))) { + gst_object_replace ((GstObject **) & h->priv->testclock, + (GstObject *) GST_ELEMENT_CLOCK (element)); + } + gst_harness_element_ref (h); - GST_DEBUG_OBJECT (h, "created new harness %p " + GST_DEBUG_OBJECT (h, "added element to harness %p " "with element_srcpad_name (%p, %s, %s) and element_sinkpad_name (%p, %s, %s)", h, h->srcpad, GST_DEBUG_PAD_NAME (h->srcpad), h->sinkpad, GST_DEBUG_PAD_NAME (h->sinkpad)); +} - priv->stress = g_ptr_array_new_with_free_func ( - (GDestroyNotify) gst_harness_stress_free); - - /* we have forwarding on as a default */ - gst_harness_set_forwarding (h, TRUE); - +/** + * gst_harness_new_full: (skip) + * @element: a #GstElement to attach the harness to (transfer none) + * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad. + * %NULL will not create a harness srcpad. + * @element_sinkpad_name: (allow-none): a #gchar with the name of the element + * sinkpad that is then linked to the harness srcpad. Can be a static or request + * or a sometimes pad that has been added. %NULL will not get/request a sinkpad + * from the element. (Like if the element is a src.) + * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad. + * %NULL will not create a harness sinkpad. + * @element_srcpad_name: (allow-none): a #gchar with the name of the element + * srcpad that is then linked to the harness sinkpad, similar to the + * @element_sinkpad_name. + * + * Creates a new harness. + * + * MT safe. + * + * Returns: (transfer full): a #GstHarness, or %NULL if the harness could + * not be created + * + * Since: 1.6 + */ +GstHarness * +gst_harness_new_full (GstElement * element, + GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name, + GstStaticPadTemplate * hsink, const gchar * element_srcpad_name) +{ + GstHarness *h; + h = gst_harness_new_empty (); + gst_harness_add_element_full (h, element, + hsrc, element_sinkpad_name, hsink, element_srcpad_name); return h; } @@ -814,30 +875,27 @@ gst_harness_new (const gchar * element_name) } /** - * gst_harness_new_parse: (skip) + * gst_harness_add_parse: (skip) + * @h: a #GstHarness * @launchline: a #gchar describing a gst-launch type line * - * Creates a new harness, parsing the @launchline and putting that in a #GstBin, - * and then attches the harness to the bin. + * Parses the @launchline and puts that in a #GstBin, + * and then attches the supplied #GstHarness to the bin. * * MT safe. * - * Returns: (transfer full): a #GstHarness, or %NULL if the harness could - * not be created - * * Since: 1.6 */ -GstHarness * -gst_harness_new_parse (const gchar * launchline) +void +gst_harness_add_parse (GstHarness * h, const gchar * launchline) { - GstHarness *h; GstBin *bin; gchar *desc; GstPad *pad; GstIterator *iter; gboolean done = FALSE; - g_return_val_if_fail (launchline != NULL, NULL); + g_return_if_fail (launchline != NULL); desc = g_strdup_printf ("bin.( %s )", launchline); bin = @@ -845,7 +903,7 @@ gst_harness_new_parse (const gchar * launchline) g_free (desc); if (G_UNLIKELY (bin == NULL)) - return NULL; + return; /* find pads and ghost them if necessary */ if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC)) != NULL) { @@ -875,15 +933,37 @@ gst_harness_new_parse (const gchar * launchline) case GST_ITERATOR_ERROR: gst_object_unref (bin); gst_iterator_free (iter); - g_return_val_if_reached (NULL); + g_return_if_reached (); break; } } gst_iterator_free (iter); - h = gst_harness_new_full (GST_ELEMENT_CAST (bin), + gst_harness_add_element_full (h, GST_ELEMENT_CAST (bin), &hsrctemplate, "sink", &hsinktemplate, "src"); gst_object_unref (bin); +} + +/** + * gst_harness_new_parse: (skip) + * @launchline: a #gchar describing a gst-launch type line + * + * Creates a new harness, parsing the @launchline and putting that in a #GstBin, + * and then attches the harness to the bin. + * + * MT safe. + * + * Returns: (transfer full): a #GstHarness, or %NULL if the harness could + * not be created + * + * Since: 1.6 + */ +GstHarness * +gst_harness_new_parse (const gchar * launchline) +{ + GstHarness *h; + h = gst_harness_new_empty (); + gst_harness_add_parse (h, launchline); return h; } @@ -968,6 +1048,9 @@ gst_harness_teardown (GstHarness * h) g_ptr_array_unref (priv->stress); gst_object_unref (h->element); + + gst_object_replace ((GstObject **) & priv->testclock, NULL); + g_free (h->priv); g_free (h); } @@ -1174,10 +1257,7 @@ gst_harness_use_systemclock (GstHarness * h) void gst_harness_use_testclock (GstHarness * h) { - GstClock *clock = gst_test_clock_new (); - g_assert (clock != NULL); - gst_element_set_clock (h->element, clock); - gst_object_unref (clock); + gst_element_set_clock (h->element, GST_CLOCK_CAST (h->priv->testclock)); } /** @@ -1197,17 +1277,7 @@ gst_harness_use_testclock (GstHarness * h) GstTestClock * gst_harness_get_testclock (GstHarness * h) { - GstTestClock *testclock = NULL; - GstClock *clock; - - clock = gst_element_get_clock (h->element); - if (clock) { - if (GST_IS_TEST_CLOCK (clock)) - testclock = GST_TEST_CLOCK (clock); - else - gst_object_unref (clock); - } - return testclock; + return gst_object_ref (h->priv->testclock); } /** @@ -1226,13 +1296,7 @@ gst_harness_get_testclock (GstHarness * h) gboolean gst_harness_set_time (GstHarness * h, GstClockTime time) { - GstTestClock *testclock; - testclock = gst_harness_get_testclock (h); - if (testclock == NULL) - return FALSE; - - gst_test_clock_set_time (testclock, time); - gst_object_unref (testclock); + gst_test_clock_set_time (h->priv->testclock, time); return TRUE; } @@ -1258,13 +1322,10 @@ gst_harness_set_time (GstHarness * h, GstClockTime time) gboolean gst_harness_wait_for_clock_id_waits (GstHarness * h, guint waits, guint timeout) { - GstTestClock *testclock = gst_harness_get_testclock (h); + GstTestClock *testclock = h->priv->testclock; gint64 start_time; gboolean ret; - if (testclock == NULL) - return FALSE; - start_time = g_get_monotonic_time (); while (gst_test_clock_peek_id_count (testclock) < waits) { gint64 time_spent; @@ -1277,7 +1338,6 @@ gst_harness_wait_for_clock_id_waits (GstHarness * h, guint waits, guint timeout) ret = (waits == gst_test_clock_peek_id_count (testclock)); - gst_object_unref (testclock); return ret; } @@ -1303,31 +1363,25 @@ gst_harness_wait_for_clock_id_waits (GstHarness * h, guint waits, guint timeout) gboolean gst_harness_crank_single_clock_wait (GstHarness * h) { - GstTestClock *testclock = gst_harness_get_testclock (h); + GstTestClock *testclock = h->priv->testclock; GstClockID res, pending; gboolean ret = FALSE; - if (G_LIKELY (testclock != NULL)) { - gst_test_clock_wait_for_next_pending_id (testclock, &pending); - - gst_test_clock_set_time (testclock, gst_clock_id_get_time (pending)); - res = gst_test_clock_process_next_clock_id (testclock); - if (res == pending) { - GST_DEBUG ("cranked time %" GST_TIME_FORMAT, - GST_TIME_ARGS (gst_clock_get_time (GST_CLOCK (testclock)))); - ret = TRUE; - } else { - GST_WARNING ("testclock next id != pending (%p != %p)", res, pending); - } - - gst_clock_id_unref (res); - gst_clock_id_unref (pending); - - gst_object_unref (testclock); + gst_test_clock_wait_for_next_pending_id (testclock, &pending); + gst_test_clock_set_time (testclock, gst_clock_id_get_time (pending)); + res = gst_test_clock_process_next_clock_id (testclock); + if (res == pending) { + GST_DEBUG ("cranked time %" GST_TIME_FORMAT, + GST_TIME_ARGS (gst_clock_get_time (GST_CLOCK (testclock)))); + ret = TRUE; } else { - GST_WARNING ("No testclock on element %s", GST_ELEMENT_NAME (h->element)); + GST_WARNING ("testclock next id != pending (%p != %p)", res, pending); } + if (G_LIKELY (res != NULL)) + gst_clock_id_unref (res); + gst_clock_id_unref (pending); + return ret; } @@ -1352,20 +1406,15 @@ gst_harness_crank_single_clock_wait (GstHarness * h) gboolean gst_harness_crank_multiple_clock_waits (GstHarness * h, guint waits) { - GstTestClock *testclock; + GstTestClock *testclock = h->priv->testclock; GList *pending; guint processed; - testclock = gst_harness_get_testclock (h); - if (testclock == NULL) - return FALSE; - gst_test_clock_wait_for_multiple_pending_ids (testclock, waits, &pending); gst_harness_set_time (h, gst_test_clock_id_list_get_latest_time (pending)); processed = gst_test_clock_process_id_list (testclock, pending); g_list_free_full (pending, gst_clock_id_unref); - gst_object_unref (testclock); return processed == waits; } diff --git a/libs/gst/check/gstharness.h b/libs/gst/check/gstharness.h index 7dc7c85..3c39f03 100644 --- a/libs/gst/check/gstharness.h +++ b/libs/gst/check/gstharness.h @@ -63,6 +63,15 @@ struct _GstHarness { /* Harness creation */ +GstHarness * gst_harness_new_empty (void); + +void gst_harness_add_element_full (GstHarness * h, + GstElement * element, + GstStaticPadTemplate * hsrc, + const gchar * element_sinkpad_name, + GstStaticPadTemplate * hsink, + const gchar * element_srcpad_name); + GstHarness * gst_harness_new_full (GstElement * element, GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name, @@ -85,6 +94,8 @@ GstHarness * gst_harness_new (const gchar * element_name); GstHarness * gst_harness_new_parse (const gchar * launchline); +void gst_harness_add_parse (GstHarness * h, const gchar * launchline); + void gst_harness_teardown (GstHarness * h); void gst_harness_add_element_src_pad (GstHarness * h, GstPad * srcpad);