summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2012-03-15 14:12:21 -0400
committerOlivier CrĂȘte <olivier.crete@collabora.com>2013-01-23 21:13:03 -0500
commitd1023646f9ef0437d134ae0ba006855e1b9982d6 (patch)
treed2ab938ecb4d168d65929ca3d76dc347dd29ec78 /tests
parent07a51b16eb92e998a831e65a4a54466da29ea469 (diff)
downloadgstreamer-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.am8
-rw-r--r--tests/check/libs/.gitignore1
-rw-r--r--tests/check/libs/insertbin.c354
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);