diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2012-03-15 14:12:21 -0400 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2013-01-23 21:13:03 -0500 |
commit | d1023646f9ef0437d134ae0ba006855e1b9982d6 (patch) | |
tree | d2ab938ecb4d168d65929ca3d76dc347dd29ec78 /tests | |
parent | 07a51b16eb92e998a831e65a4a54466da29ea469 (diff) | |
download | gstreamer-plugins-bad-d1023646f9ef0437d134ae0ba006855e1b9982d6.tar.gz |
insertbin: Add bin to dynamically insert elements in a running pipeline
This element automatically links in any element added using it's
action signals. These elements must have a single source pad and a single
sink pad.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/check/Makefile.am | 8 | ||||
-rw-r--r-- | tests/check/libs/.gitignore | 1 | ||||
-rw-r--r-- | tests/check/libs/insertbin.c | 354 |
3 files changed, 363 insertions, 0 deletions
diff --git a/tests/check/Makefile.am b/tests/check/Makefile.am index 51d560eca..66a72dac5 100644 --- a/tests/check/Makefile.am +++ b/tests/check/Makefile.am @@ -232,6 +232,7 @@ check_PROGRAMS = \ elements/viewfinderbin \ $(check_zbar) \ $(check_orc) \ + libs/insertbin \ $(EXPERIMENTAL_CHECKS) noinst_HEADERS = elements/mxfdemux.h @@ -365,6 +366,13 @@ elements_uvch264demux_CFLAGS = -DUVCH264DEMUX_DATADIR="$(srcdir)/elements/uvch26 pipelines_streamheader_CFLAGS = $(GIO_CFLAGS) $(AM_CFLAGS) pipelines_streamheader_LDADD = $(GIO_LIBS) $(LDADD) +libs_insertbin_LDADD = \ + $(GST_PLUGINS_BAD_LIBS) $(GST_BASE_LIBS) $(GST_LIBS) $(LDADD) \ + $(top_builddir)/gst-libs/gst/insertbin/libgstinsertbin-@GST_API_VERSION@.la +libs_insertbin_CFLAGS = \ + $(GST_PLUGINS_BAD_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS) + + EXTRA_DIST = gst-plugins-bad.supp $(uvch264_dist_data) orc_bayer_CFLAGS = $(ORC_CFLAGS) diff --git a/tests/check/libs/.gitignore b/tests/check/libs/.gitignore index 238cb3d11..728f9e9c2 100644 --- a/tests/check/libs/.gitignore +++ b/tests/check/libs/.gitignore @@ -2,3 +2,4 @@ h264parser mpegvideoparser vc1parser +insertbin diff --git a/tests/check/libs/insertbin.c b/tests/check/libs/insertbin.c new file mode 100644 index 000000000..b98c94a54 --- /dev/null +++ b/tests/check/libs/insertbin.c @@ -0,0 +1,354 @@ +/* GStreamer + * + * unit test for autoconvert element + * Copyright (C) 2009 Jan Schmidt <thaytan@noraisin.net> + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gst/gst.h> +#include <gst/check/gstcheck.h> +#include <gst/insertbin/gstinsertbin.h> + +GstStaticPadTemplate sinkpad_template = GST_STATIC_PAD_TEMPLATE ("sink", // the name of the pad + GST_PAD_SINK, // the direction of the pad + GST_PAD_ALWAYS, // when this pad will be present + GST_STATIC_CAPS ( // the capabilities of the padtemplate + "video/test") + ); + +GstStaticPadTemplate srcpad_template = GST_STATIC_PAD_TEMPLATE ("src", // the name of the pad + GST_PAD_SRC, // the direction of the pad + GST_PAD_ALWAYS, // when this pad will be present + GST_STATIC_CAPS ( // the capabilities of the padtemplate + "video/test") + ); + +gint cb_count = 0; + +GMutex mutex; +GCond cond; + +GThread *push_thread = NULL; +gulong block_probe_id = 0; +gboolean is_blocked = FALSE; + +static void +success_cb (GstInsertBin * insertbin, GstElement * element, gboolean success, + gpointer user_data) +{ + fail_unless (g_thread_self () != push_thread); + fail_unless (success == TRUE); + fail_unless (GST_IS_ELEMENT (insertbin)); + fail_unless (GST_IS_ELEMENT (element)); + cb_count++; +} + +static void +fail_cb (GstInsertBin * insertbin, GstElement * element, gboolean success, + gpointer user_data) +{ + fail_unless (GST_IS_ELEMENT (insertbin)); + fail_unless (GST_IS_ELEMENT (element)); + fail_unless (success == FALSE); + cb_count++; +} + +/* + * This is a macro so the line number of any error is more useful + */ +#define push_buffer(srcpad, count) \ + { \ + fail_unless (cb_count == 0); \ + gst_pad_push (srcpad, gst_buffer_new ()); \ + fail_unless (g_list_length (buffers) == 1); \ + gst_check_drop_buffers (); \ + fail_unless (cb_count == (count)); \ + cb_count = 0; \ + } + +#define check_reset_cb_count(count) \ + { \ + fail_unless (cb_count == (count)); \ + cb_count = 0; \ + } + +static gpointer +thread_push_buffer (gpointer data) +{ + GstPad *pad = data; + + gst_pad_push (pad, gst_buffer_new ()); + return NULL; +} + +static GstPadProbeReturn +got_buffer_block (GstPad * pad, GstPadProbeInfo * info, gpointer data) +{ + g_mutex_lock (&mutex); + is_blocked = TRUE; + g_cond_broadcast (&cond); + g_mutex_unlock (&mutex); + + return GST_PAD_PROBE_OK; +} + +#define block_thread() \ +{ \ + fail_unless (cb_count == 0); \ + fail_unless (block_probe_id == 0); \ + fail_unless (is_blocked == FALSE); \ + fail_unless (push_thread == NULL); \ + block_probe_id = gst_pad_add_probe (sinkpad, \ + GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER, \ + got_buffer_block, NULL, NULL); \ + push_thread = g_thread_new ("push block", thread_push_buffer, srcpad); \ + fail_unless (push_thread != NULL); \ + g_mutex_lock (&mutex); \ + while (is_blocked == FALSE) \ + g_cond_wait (&cond, &mutex); \ + g_mutex_unlock (&mutex); \ +} + +#define unblock_thread() \ +{ \ + fail_unless (cb_count == 0); \ + fail_unless (push_thread != NULL); \ + fail_unless (is_blocked == TRUE); \ + fail_unless (block_probe_id != 0); \ + gst_pad_remove_probe (sinkpad, block_probe_id); \ + g_thread_join (push_thread); \ + fail_unless (g_list_length (buffers) == 1); \ + gst_check_drop_buffers (); \ + block_probe_id = 0; \ + push_thread = NULL; \ + is_blocked = FALSE; \ +} + +GST_START_TEST (test_insertbin_simple) +{ + GstElement *insertbin; + GstElement *elem; + GstElement *elem2; + GstElement *elem3; + GstElement *elem4; + GstPad *srcpad; + GstPad *sinkpad; + + g_mutex_init (&mutex); + g_cond_init (&cond); + + insertbin = gst_insert_bin_new (NULL); + fail_unless (insertbin != NULL); + ASSERT_OBJECT_REFCOUNT (insertbin, insertbin, 1); + srcpad = gst_check_setup_src_pad (insertbin, &srcpad_template); + sinkpad = gst_check_setup_sink_pad (insertbin, &sinkpad_template); + + g_assert (srcpad && sinkpad); + + ASSERT_CRITICAL (gst_insert_bin_append (GST_INSERT_BIN (insertbin), NULL, + NULL, NULL)); + ASSERT_CRITICAL (gst_insert_bin_append (GST_INSERT_BIN (insertbin), NULL, + fail_cb, NULL)); + fail_unless (cb_count == 0); + + + elem = gst_element_factory_make ("identity", NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + check_reset_cb_count (1); + + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + check_reset_cb_count (1); + + fail_unless (gst_pad_set_active (srcpad, TRUE)); + fail_unless (gst_pad_set_active (sinkpad, TRUE)); + fail_unless (gst_element_set_state (insertbin, + GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS); + + fail_unless (cb_count == 0); + fail_unless (buffers == NULL); + + push_buffer (srcpad, 0); + + block_thread (); + elem = gst_element_factory_make ("identity", NULL); + gst_insert_bin_prepend (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem, fail_cb, NULL); + check_reset_cb_count (1); + unblock_thread (); + push_buffer (srcpad, 0); + + block_thread (); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + elem = gst_element_factory_make ("identity", NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + elem2 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem2, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + elem3 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem3, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + elem4 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_prepend (GST_INSERT_BIN (insertbin), elem4, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem3, success_cb, NULL); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem2, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + elem2 = gst_element_factory_make ("identity", NULL); + elem3 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_insert_after (GST_INSERT_BIN (insertbin), elem2, elem, + success_cb, NULL); + gst_insert_bin_insert_before (GST_INSERT_BIN (insertbin), elem3, elem4, + success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem3, success_cb, NULL); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem2, success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 2); + push_buffer (srcpad, 0); + + block_thread (); + elem2 = gst_element_factory_make ("identity", NULL); + elem3 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_insert_before (GST_INSERT_BIN (insertbin), elem3, elem4, + success_cb, NULL); + gst_insert_bin_insert_after (GST_INSERT_BIN (insertbin), elem2, elem, + success_cb, NULL); + unblock_thread (); + push_buffer (srcpad, 2); + push_buffer (srcpad, 0); + + block_thread (); + elem = gst_bin_new (NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem, fail_cb, NULL); + check_reset_cb_count (1); + unblock_thread (); + + block_thread (); + elem = gst_bin_new (NULL); + elem2 = gst_element_factory_make ("identity", NULL); + gst_bin_add (GST_BIN (elem), elem2); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem2, fail_cb, NULL); + check_reset_cb_count (1); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem2, fail_cb, NULL); + check_reset_cb_count (1); + unblock_thread (); + gst_object_unref (elem); + + push_buffer (srcpad, 0); + + block_thread (); + elem = gst_element_factory_make ("identity", NULL); + elem2 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem2, success_cb, NULL); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem2, success_cb, NULL); + check_reset_cb_count (2); + unblock_thread (); + push_buffer (srcpad, 1); + push_buffer (srcpad, 0); + + block_thread (); + elem = gst_element_factory_make ("identity", NULL); + elem2 = gst_element_factory_make ("identity", NULL); + gst_insert_bin_insert_before (GST_INSERT_BIN (insertbin), elem, elem2, + fail_cb, NULL); + check_reset_cb_count (1); + unblock_thread (); + push_buffer (srcpad, 0); + gst_object_unref (elem2); + + fail_unless (gst_element_set_state (insertbin, + GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS); + gst_pad_set_active (srcpad, FALSE); + gst_pad_set_active (sinkpad, FALSE); + + + elem = gst_element_factory_make ("identity", NULL); + gst_insert_bin_remove (GST_INSERT_BIN (insertbin), elem, fail_cb, NULL); + check_reset_cb_count (1); + + gst_insert_bin_append (GST_INSERT_BIN (insertbin), elem, success_cb, NULL); + check_reset_cb_count (1); + + gst_check_teardown_sink_pad (insertbin); + gst_check_teardown_src_pad (insertbin); + gst_check_teardown_element (insertbin); + + fail_unless (cb_count == 0); + + g_mutex_clear (&mutex); + g_cond_clear (&cond); +} + +GST_END_TEST; + + +static Suite * +insert_bin_suite (void) +{ + Suite *s = suite_create ("insertbin"); + TCase *tc_basic = tcase_create ("general"); + + suite_add_tcase (s, tc_basic); + tcase_add_test (tc_basic, test_insertbin_simple); + + return s; +} + + +GST_CHECK_MAIN (insert_bin); |