diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 031e9b9f8e..d163a49d42 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -1232,6 +1232,7 @@ gst_harness_crank_multiple_clock_waits gst_harness_play gst_harness_set_blocking_push_mode +gst_harness_set_forwarding gst_harness_create_buffer gst_harness_push diff --git a/libs/gst/check/Makefile.am b/libs/gst/check/Makefile.am index 7f2564535f..1791c83c20 100644 --- a/libs/gst/check/Makefile.am +++ b/libs/gst/check/Makefile.am @@ -139,6 +139,7 @@ LIBGSTCHECK_EXPORTED_FUNCS = \ gst_harness_set_caps_str \ gst_harness_set_drop_buffers \ gst_harness_set_blocking_push_mode \ + gst_harness_set_forwarding \ gst_harness_set_propose_allocator \ gst_harness_set_sink_caps \ gst_harness_set_src_caps \ diff --git a/libs/gst/check/gstharness.c b/libs/gst/check/gstharness.c index 9fbb16d6e9..7d48526afb 100644 --- a/libs/gst/check/gstharness.c +++ b/libs/gst/check/gstharness.c @@ -156,6 +156,8 @@ struct _GstHarnessPrivate GstCaps *src_caps; GstCaps *sink_caps; + + gboolean forwarding; GstPad *sink_forward_pad; volatile gint recv_buffers; @@ -242,7 +244,7 @@ gst_harness_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) break; } - if (forward && priv->sink_forward_pad) { + if (priv->forwarding && forward && priv->sink_forward_pad) { gst_pad_push_event (priv->sink_forward_pad, event); } else { g_async_queue_push (priv->sink_event_queue, event); @@ -358,7 +360,7 @@ gst_harness_sink_query (GstPad * pad, GstObject * parent, GstQuery * query) break; case GST_QUERY_ALLOCATION: { - if (priv->sink_forward_pad != NULL) { + if (priv->forwarding && priv->sink_forward_pad != NULL) { GstPad *peer = gst_pad_get_peer (priv->sink_forward_pad); g_assert (peer != NULL); res = gst_pad_query (peer, query); @@ -676,6 +678,9 @@ gst_harness_new_full (GstElement * element, 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; } @@ -1400,6 +1405,40 @@ gst_harness_set_blocking_push_mode (GstHarness * h) priv->blocking_push_mode = TRUE; } +/** + * gst_harness_set_forwarding: + * @h: a #GstHarness + * @forwarding: a #gboolean to enable/disable forwarding + * + * As a convenience, a src-harness will forward %GST_EVENT_STREAM_START, + * %GST_EVENT_CAPS and %GST_EVENT_SEGMENT to the main-harness if forwarding + * is enabled, and forward any sticky-events from the main-harness to + * the sink-harness. It will also forward the %GST_QUERY_ALLOCATION. + * + * If forwarding is disabled, the user will have to either manually push + * these events from the src-harness using gst_harness_src_push_event, or + * create and push them manually. While this will allow full control and + * inspection of these events, for the most cases having forwarding enabled + * will be sufficient when writing a test where the src-harness' main function + * is providing data for the main-harness. + * + * Forwarding is enabled by default. + * + * MT safe. + * + * Since: 1.6 + */ +void +gst_harness_set_forwarding (GstHarness * h, gboolean forwarding) +{ + GstHarnessPrivate *priv = h->priv; + priv->forwarding = forwarding; + if (h->src_harness) + gst_harness_set_forwarding (h->src_harness, forwarding); + if (h->sink_harness) + gst_harness_set_forwarding (h->sink_harness, forwarding); +} + /** * gst_harness_create_buffer: * @h: a #GstHarness @@ -1995,6 +2034,7 @@ gst_harness_add_src_harness (GstHarness * h, h->src_harness->priv->sink_forward_pad = gst_object_ref (h->srcpad); gst_harness_use_testclock (h->src_harness); h->src_harness->priv->has_clock_wait = has_clock_wait; + gst_harness_set_forwarding (h->src_harness, h->priv->forwarding); } /** @@ -2186,7 +2226,9 @@ gst_harness_add_sink_harness (GstHarness * h, GstHarness * sink_harness) h->sink_harness = sink_harness; priv->sink_forward_pad = gst_object_ref (h->sink_harness->srcpad); gst_harness_use_testclock (h->sink_harness); - gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h); + if (priv->forwarding) + gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h); + gst_harness_set_forwarding (h->sink_harness, priv->forwarding); } /** diff --git a/libs/gst/check/gstharness.h b/libs/gst/check/gstharness.h index 708248a1fb..7dc7c85cc3 100644 --- a/libs/gst/check/gstharness.h +++ b/libs/gst/check/gstharness.h @@ -126,10 +126,13 @@ gboolean gst_harness_crank_single_clock_wait (GstHarness * h); gboolean gst_harness_crank_multiple_clock_waits (GstHarness * h, guint waits); +/* misc */ void gst_harness_play (GstHarness * h); void gst_harness_set_blocking_push_mode (GstHarness * h); +void gst_harness_set_forwarding (GstHarness * h, gboolean forwarding); + /* buffers */ GstBuffer * gst_harness_create_buffer (GstHarness * h, gsize size); diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 6d122e5e41..07ad657af6 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -158,6 +158,7 @@ check_PROGRAMS = \ libs/flowcombiner \ libs/sparsefile \ libs/collectpads \ + libs/gstharness \ libs/gstnetclientclock \ libs/gstnettimeprovider \ libs/gsttestclock \ diff --git a/tests/check/libs/gstharness.c b/tests/check/libs/gstharness.c new file mode 100644 index 0000000000..67abab2aa2 --- /dev/null +++ b/tests/check/libs/gstharness.c @@ -0,0 +1,97 @@ +/* + * Tests and examples of GstHarness + * + * Copyright (C) 2015 Havard Graff + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +GST_START_TEST(test_src_harness) +{ + GstHarness * h = gst_harness_new ("identity"); + + /* add a fakesrc that syncs to the clock and a + capsfilter that adds some caps to it */ + gst_harness_add_src_parse (h, + "fakesrc sync=1 ! capsfilter caps=\"mycaps\"", TRUE); + + /* this cranks the clock and transfers the resulting buffer + from the src-harness into the identity element */ + gst_harness_push_from_src (h); + + /* verify that identity outputs a buffer by pulling and unreffing */ + gst_buffer_unref (gst_harness_pull (h)); + + gst_harness_teardown (h); +} +GST_END_TEST; + +GST_START_TEST(test_src_harness_no_forwarding) +{ + GstHarness * h = gst_harness_new ("identity"); + + /* turn of forwarding of necessary events */ + gst_harness_set_forwarding (h, FALSE); + + /* add a fakesrc that syncs to the clock and a + capsfilter that adds some caps to it */ + gst_harness_add_src_parse (h, + "fakesrc sync=1 ! capsfilter caps=\"mycaps\"", TRUE); + + /* start the fakesrc to produce the first events */ + gst_harness_play (h->src_harness); + + /* transfer STREAM_START event */ + gst_harness_src_push_event (h); + + /* crank the clock to produce the CAPS and SEGMENT events */ + gst_harness_crank_single_clock_wait (h->src_harness); + + /* transfer CAPS event */ + gst_harness_src_push_event (h); + + /* transfer SEGMENT event */ + gst_harness_src_push_event (h); + + /* now transfer the buffer produced by exploiting + the ability to say 0 cranks but 1 push */ + gst_harness_src_crank_and_push_many (h, 0, 1); + + /* and verify that the identity element outputs it */ + gst_buffer_unref (gst_harness_pull (h)); + + gst_harness_teardown (h); +} +GST_END_TEST; + +static Suite * +gst_harness_suite (void) +{ + Suite *s = suite_create ("GstHarness"); + TCase *tc_chain = tcase_create ("harness"); + + suite_add_tcase (s, tc_chain); + + tcase_add_test (tc_chain, test_src_harness); + tcase_add_test (tc_chain, test_src_harness_no_forwarding); + + return s; +} + +GST_CHECK_MAIN (gst_harness);