mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +00:00
Added GstBin test.
Original commit message from CVS: Added GstBin test. Added GstSystemClock test. Implemented clock distribution code in GstBin. Implemented iterate sinks method for future use. Rearranged gstelement.h Fix GstIterator comparison bug. Moved some code to GstPipeline, mostly clocking related.
This commit is contained in:
parent
c6a7adc9d4
commit
6cacf76cd9
19 changed files with 1159 additions and 155 deletions
40
ChangeLog
40
ChangeLog
|
@ -1,3 +1,43 @@
|
|||
2005-03-09 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* check/Makefile.am:
|
||||
* check/gst/gstbin.c: (START_TEST), (gst_bin_suite), (main):
|
||||
* check/gst/gstsystemclock.c: (START_TEST), (gst_clock_debug),
|
||||
(ok_callback), (error_callback), (gst_systemclock_suite), (main):
|
||||
* gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_index_func),
|
||||
(gst_bin_set_clock_func), (gst_bin_get_clock_func),
|
||||
(gst_bin_add_func), (gst_bin_add), (gst_bin_remove_func),
|
||||
(gst_bin_remove), (gst_bin_iterate_recurse_up),
|
||||
(bin_element_is_sink), (gst_bin_iterate_sinks),
|
||||
(gst_bin_iterate_all_by_interface):
|
||||
* gst/gstbin.h:
|
||||
* gst/gstelement.c: (gst_element_init), (gst_element_error_full),
|
||||
(gst_element_change_state), (gst_element_dispose),
|
||||
(gst_element_finalize), (gst_element_set_loop_function):
|
||||
* gst/gstelement.h:
|
||||
* gst/gstiterator.c: (find_custom_fold_func):
|
||||
* gst/gstpad.c: (_gst_pad_default_fixate_foreach),
|
||||
(gst_pad_collectv), (gst_pad_collect_valist),
|
||||
(gst_pad_template_new):
|
||||
* gst/gstpipeline.c: (gst_pipeline_class_init),
|
||||
(gst_pipeline_dispose), (gst_pipeline_set_property),
|
||||
(gst_pipeline_get_property), (gst_pipeline_get_clock_func),
|
||||
(gst_pipeline_get_clock), (gst_pipeline_use_clock),
|
||||
(gst_pipeline_set_clock), (gst_pipeline_auto_clock):
|
||||
* gst/gstutils.h:
|
||||
* gst/schedulers/entryscheduler.c:
|
||||
* gst/schedulers/gstbasicscheduler.c:
|
||||
(gst_basic_scheduler_cothreaded_chain),
|
||||
(gst_basic_scheduler_chain_add_element):
|
||||
* testsuite/bins/interface.c: (main):
|
||||
Added GstBin test.
|
||||
Added GstSystemClock test.
|
||||
Implemented clock distribution code in GstBin.
|
||||
Implemented iterate sinks method for future use.
|
||||
Rearranged gstelement.h
|
||||
Fix GstIterator comparison bug.
|
||||
Moved some code to GstPipeline, mostly clocking related.
|
||||
|
||||
2005-03-09 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* configure.ac:
|
||||
|
|
|
@ -19,10 +19,12 @@ install-pluginLTLIBRARIES:
|
|||
CLEANFILES = core.*
|
||||
|
||||
TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
|
||||
gst/gstcaps \
|
||||
gst/gstdata \
|
||||
gst/gstiterator \
|
||||
gst/gstobject \
|
||||
gst/gstbin \
|
||||
gst/gstcaps \
|
||||
gst/gstdata \
|
||||
gst/gstiterator \
|
||||
gst/gstobject \
|
||||
gst/gstsystemclock \
|
||||
gst-libs/gdp
|
||||
|
||||
check_PROGRAMS = $(TESTS)
|
||||
|
|
110
check/gst/gstbin.c
Normal file
110
check/gst/gstbin.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* gstbin.c: Unit test for GstBin
|
||||
*
|
||||
* 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 "../gstcheck.h"
|
||||
|
||||
START_TEST (test_interface)
|
||||
{
|
||||
GstBin *bin, *bin2;
|
||||
GstElement *filesrc;
|
||||
GstIterator *it;
|
||||
gpointer item;
|
||||
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
fail_unless (bin != NULL, "Could not create bin");
|
||||
|
||||
filesrc = gst_element_factory_make ("filesrc", NULL);
|
||||
fail_unless (filesrc != NULL, "Could not create filesrc");
|
||||
fail_unless (GST_IS_URI_HANDLER (filesrc), "Filesrc not a URI handler");
|
||||
gst_bin_add (bin, filesrc);
|
||||
|
||||
fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (it != NULL);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (item == (gpointer) filesrc);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add_many (bin,
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL), NULL);
|
||||
fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (it != NULL);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (item == (gpointer) filesrc);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
bin2 = bin;
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
fail_unless (bin != NULL);
|
||||
gst_bin_add_many (bin,
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
|
||||
fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (item == (gpointer) filesrc);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
|
||||
gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
g_object_unref (bin);
|
||||
}
|
||||
END_TEST Suite * gst_bin_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("GstBin");
|
||||
TCase *tc_chain = tcase_create ("bin tests");
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_interface);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int nf;
|
||||
|
||||
Suite *s = gst_bin_suite ();
|
||||
SRunner *sr = srunner_create (s);
|
||||
|
||||
gst_check_init (&argc, &argv);
|
||||
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
nf = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
|
||||
return nf;
|
||||
}
|
221
check/gst/gstsystemclock.c
Normal file
221
check/gst/gstsystemclock.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* gstsystemclock.c: Unit test for GstSystemClock
|
||||
*
|
||||
* 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 "../gstcheck.h"
|
||||
|
||||
START_TEST (test_signedness)
|
||||
{
|
||||
GstClockTime time[] = { 0, 1, G_MAXUINT64 / GST_SECOND };
|
||||
GstClockTimeDiff diff[] =
|
||||
{ 0, 1, -1, G_MAXINT64 / GST_SECOND, G_MININT64 / GST_SECOND };
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (time); i++) {
|
||||
fail_if (time[i] != (time[i] * GST_SECOND / GST_SECOND));
|
||||
}
|
||||
for (i = 0; i < G_N_ELEMENTS (diff); i++) {
|
||||
fail_if (diff[i] != (diff[i] * GST_SECOND / GST_SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
END_TEST
|
||||
#define TIME_UNIT GST_SECOND
|
||||
static void
|
||||
gst_clock_debug (GstClock * clock)
|
||||
{
|
||||
GstClockTime time;
|
||||
|
||||
time = gst_clock_get_time (clock);
|
||||
g_message ("Clock info: time %" G_GUINT64_FORMAT "\n", time);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ok_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, gpointer user_data)
|
||||
{
|
||||
g_message ("unlocked async id %p\n", id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
error_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, gpointer user_data)
|
||||
{
|
||||
g_message ("unlocked unscheduled async id %p, this is wrong\n", id);
|
||||
fail_if (TRUE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
START_TEST (test_single_shot)
|
||||
{
|
||||
GstClock *clock;
|
||||
GstClockID id, id2;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
fail_unless (clock != NULL, "Could not create instance of GstSystemClock");
|
||||
|
||||
gst_clock_debug (clock);
|
||||
base = gst_clock_get_time (clock);
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + TIME_UNIT);
|
||||
fail_unless (id != NULL, "Could not create single shot id");
|
||||
|
||||
g_message ("waiting one second\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
|
||||
g_message ("waiting in the past\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_EARLY, "Waiting did not return EARLY");
|
||||
gst_clock_id_unref (id);
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + 2 * TIME_UNIT);
|
||||
g_message ("waiting one second async id %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
gst_clock_id_unref (id);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + 5 * TIME_UNIT);
|
||||
g_message ("waiting one second async, with cancel on id %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, error_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (G_USEC_PER_SEC / 2);
|
||||
g_message ("cancel id %p after 0.5 seconds\n", id);
|
||||
gst_clock_id_unschedule (id);
|
||||
gst_clock_id_unref (id);
|
||||
g_message ("canceled id %p\n", id);
|
||||
|
||||
g_message ("waiting multiple one second async, with cancel\n");
|
||||
id = gst_clock_new_single_shot_id (clock, base + 5 * TIME_UNIT);
|
||||
id2 = gst_clock_new_single_shot_id (clock, base + 6 * TIME_UNIT);
|
||||
g_message ("waiting id %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
gst_clock_id_unref (id);
|
||||
g_message ("waiting id %p\n", id2);
|
||||
result = gst_clock_id_wait_async (id2, error_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (G_USEC_PER_SEC / 2);
|
||||
g_message ("cancel id %p after 0.5 seconds\n", id2);
|
||||
gst_clock_id_unschedule (id2);
|
||||
g_message ("canceled id %p\n", id2);
|
||||
gst_clock_id_unref (id2);
|
||||
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
}
|
||||
|
||||
END_TEST
|
||||
START_TEST (test_periodic_shot)
|
||||
{
|
||||
GstClock *clock;
|
||||
GstClockID id, id2;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
fail_unless (clock != NULL, "Could not create instance of GstSystemClock");
|
||||
|
||||
gst_clock_debug (clock);
|
||||
base = gst_clock_get_time (clock);
|
||||
|
||||
/* signal every half a second */
|
||||
id = gst_clock_new_periodic_id (clock, base + TIME_UNIT, TIME_UNIT / 2);
|
||||
fail_unless (id != NULL, "Could not create periodic id");
|
||||
|
||||
g_message ("waiting one second\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
|
||||
g_message ("waiting for the next\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
|
||||
g_message ("waiting for the next async %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
g_message ("waiting some more for the next async %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
id2 = gst_clock_new_periodic_id (clock, base + TIME_UNIT, TIME_UNIT / 2);
|
||||
fail_unless (id2 != NULL, "Could not create second periodic id");
|
||||
|
||||
g_message ("waiting some more for another async %p\n", id2);
|
||||
result = gst_clock_id_wait_async (id2, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
g_message ("unschedule %p\n", id);
|
||||
gst_clock_id_unschedule (id);
|
||||
|
||||
/* entry cannot be used again */
|
||||
result = gst_clock_id_wait_async (id, error_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_UNSCHEDULED,
|
||||
"Waiting did not return UNSCHEDULED");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
fail_unless (result == GST_CLOCK_UNSCHEDULED,
|
||||
"Waiting did not return UNSCHEDULED");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
}
|
||||
|
||||
END_TEST Suite * gst_systemclock_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("GstSystemClock");
|
||||
TCase *tc_chain = tcase_create ("waiting");
|
||||
|
||||
/* increase timeout */
|
||||
tcase_set_timeout (tc_chain, 20);
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_signedness);
|
||||
tcase_add_test (tc_chain, test_single_shot);
|
||||
tcase_add_test (tc_chain, test_periodic_shot);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int nf;
|
||||
|
||||
Suite *s = gst_systemclock_suite ();
|
||||
SRunner *sr = srunner_create (s);
|
||||
|
||||
gst_check_init (&argc, &argv);
|
||||
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
nf = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
|
||||
return nf;
|
||||
}
|
241
gst/gstbin.c
241
gst/gstbin.c
|
@ -60,20 +60,20 @@ static void gst_bin_dispose (GObject * object);
|
|||
static GstElementStateReturn gst_bin_change_state (GstElement * element);
|
||||
static GstElementStateReturn gst_bin_change_state_norecurse (GstBin * bin);
|
||||
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
static void gst_bin_set_index (GstElement * element, GstIndex * index);
|
||||
#endif
|
||||
|
||||
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
|
||||
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
|
||||
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
|
||||
#endif
|
||||
static GstClock *gst_bin_get_clock_func (GstElement * element);
|
||||
static void gst_bin_set_clock_func (GstElement * element, GstClock * clock);
|
||||
|
||||
static void gst_bin_child_state_change_func (GstBin * bin,
|
||||
GstElementState oldstate, GstElementState newstate, GstElement * child);
|
||||
GstElementStateReturn gst_bin_set_state (GstElement * element,
|
||||
GstElementState state);
|
||||
|
||||
static GstClock *gst_bin_get_clock_func (GstElement * element);
|
||||
static void gst_bin_set_clock_func (GstElement * element, GstClock * clock);
|
||||
|
||||
static gboolean gst_bin_iterate_func (GstBin * bin);
|
||||
|
||||
#ifndef GST_DISABLE_LOADSAVE
|
||||
|
@ -180,11 +180,14 @@ gst_bin_class_init (GstBinClass * klass)
|
|||
gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
|
||||
gstelement_class->set_state = GST_DEBUG_FUNCPTR (gst_bin_set_state);
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index);
|
||||
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
|
||||
#endif
|
||||
gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_bin_get_clock_func);
|
||||
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
|
||||
|
||||
klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
|
||||
klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
|
||||
|
||||
klass->child_state_change =
|
||||
GST_DEBUG_FUNCPTR (gst_bin_child_state_change_func);
|
||||
klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func);
|
||||
|
@ -227,73 +230,13 @@ gst_bin_new (const gchar * name)
|
|||
return gst_element_factory_make ("bin", name);
|
||||
}
|
||||
|
||||
static GstClock *
|
||||
gst_bin_get_clock_func (GstElement * element)
|
||||
{
|
||||
if (GST_ELEMENT_SCHEDULER (element))
|
||||
return gst_scheduler_get_clock (GST_ELEMENT_SCHEDULER (element));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_bin_set_clock_func (GstElement * element, GstClock * clock)
|
||||
{
|
||||
if (GST_ELEMENT_SCHEDULER (element))
|
||||
gst_scheduler_use_clock (GST_ELEMENT_SCHEDULER (element), clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bin_get_clock:
|
||||
* @bin: a #GstBin to get the clock of
|
||||
/* set the index on all elements in this bin
|
||||
*
|
||||
* Gets the current clock of the (scheduler of the) bin.
|
||||
*
|
||||
* Returns: the #GstClock of the bin
|
||||
* MT safe
|
||||
*/
|
||||
GstClock *
|
||||
gst_bin_get_clock (GstBin * bin)
|
||||
{
|
||||
g_return_val_if_fail (bin != NULL, NULL);
|
||||
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||
|
||||
return gst_bin_get_clock_func (GST_ELEMENT (bin));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bin_use_clock:
|
||||
* @bin: the bin to set the clock for
|
||||
* @clock: the clock to use.
|
||||
*
|
||||
* Force the bin to use the given clock. Use NULL to
|
||||
* force it to use no clock at all.
|
||||
*/
|
||||
void
|
||||
gst_bin_use_clock (GstBin * bin, GstClock * clock)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BIN (bin));
|
||||
|
||||
gst_bin_set_clock_func (GST_ELEMENT (bin), clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bin_auto_clock:
|
||||
* @bin: the bin to autoclock
|
||||
*
|
||||
* Let the bin select a clock automatically.
|
||||
*/
|
||||
void
|
||||
gst_bin_auto_clock (GstBin * bin)
|
||||
{
|
||||
g_return_if_fail (GST_IS_BIN (bin));
|
||||
|
||||
if (GST_ELEMENT_SCHEDULER (bin))
|
||||
gst_scheduler_auto_clock (GST_ELEMENT_SCHEDULER (bin));
|
||||
}
|
||||
|
||||
#ifndef GST_DISABLE_INDEX
|
||||
static void
|
||||
gst_bin_set_index (GstElement * element, GstIndex * index)
|
||||
gst_bin_set_index_func (GstElement * element, GstIndex * index)
|
||||
{
|
||||
GstBin *bin;
|
||||
GList *children;
|
||||
|
@ -310,6 +253,53 @@ gst_bin_set_index (GstElement * element, GstIndex * index)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* set the clock on all elements in this bin
|
||||
*
|
||||
* MT safe
|
||||
*/
|
||||
static void
|
||||
gst_bin_set_clock_func (GstElement * element, GstClock * clock)
|
||||
{
|
||||
GList *children;
|
||||
GstBin *bin;
|
||||
|
||||
bin = GST_BIN (element);
|
||||
|
||||
GST_LOCK (bin);
|
||||
for (children = bin->children; children; children = g_list_next (children)) {
|
||||
GstElement *child = GST_ELEMENT (children->data);
|
||||
|
||||
gst_element_set_clock (child, clock);
|
||||
}
|
||||
GST_UNLOCK (bin);
|
||||
}
|
||||
|
||||
/* get the clock for this bin by asking all of the children in this bin
|
||||
*
|
||||
* MT safe
|
||||
*/
|
||||
static GstClock *
|
||||
gst_bin_get_clock_func (GstElement * element)
|
||||
{
|
||||
GstClock *result = NULL;
|
||||
GstBin *bin;
|
||||
GList *children;
|
||||
|
||||
bin = GST_BIN (element);
|
||||
|
||||
GST_LOCK (bin);
|
||||
for (children = bin->children; children; children = g_list_next (children)) {
|
||||
GstElement *child = GST_ELEMENT (children->data);
|
||||
|
||||
result = gst_element_get_clock (child);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
GST_UNLOCK (bin);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_bin_set_element_sched (GstElement * element, GstScheduler * sched)
|
||||
{
|
||||
|
@ -741,6 +731,114 @@ gst_bin_iterate_recurse (GstBin * bin)
|
|||
return result;
|
||||
}
|
||||
|
||||
GstIterator *
|
||||
gst_bin_iterate_recurse_up (GstBin * bin)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* returns 0 if the element is a sink, this is made so that
|
||||
* we can use this function as a filter
|
||||
*
|
||||
* MT safe
|
||||
*/
|
||||
static gint
|
||||
bin_element_is_sink (GstElement * child, GstBin * bin)
|
||||
{
|
||||
gint ret = 1;
|
||||
|
||||
/* we lock the child here for the remainder of the function to
|
||||
* get its pads and name safely. */
|
||||
GST_LOCK (child);
|
||||
|
||||
/* check if this is a sink element, these are the elements
|
||||
* without (linked) source pads. */
|
||||
if (child->numsrcpads == 0) {
|
||||
/* shortcut */
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
|
||||
"adding child %s as sink", GST_OBJECT_NAME (child));
|
||||
ret = 0;
|
||||
} else {
|
||||
/* loop over all pads, try to figure out if this element
|
||||
* is a sink because it has no linked source pads */
|
||||
GList *pads;
|
||||
gboolean connected_src = FALSE;
|
||||
|
||||
for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
|
||||
GstPad *peer;
|
||||
|
||||
peer = gst_pad_get_peer (GST_PAD_CAST (pads->data));
|
||||
if (peer) {
|
||||
GstElement *parent;
|
||||
|
||||
parent = gst_pad_get_parent (peer);
|
||||
if (parent) {
|
||||
GstObject *grandparent;
|
||||
|
||||
grandparent = gst_object_get_parent (GST_OBJECT_CAST (parent));
|
||||
if (grandparent == GST_OBJECT_CAST (bin)) {
|
||||
connected_src = TRUE;
|
||||
}
|
||||
if (grandparent) {
|
||||
gst_object_unref (GST_OBJECT_CAST (grandparent));
|
||||
}
|
||||
gst_object_unref (GST_OBJECT_CAST (parent));
|
||||
}
|
||||
gst_object_unref (GST_OBJECT_CAST (peer));
|
||||
if (connected_src) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (connected_src) {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
|
||||
"not adding child %s as sink: linked source pads",
|
||||
GST_OBJECT_NAME (child));
|
||||
} else {
|
||||
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
|
||||
"adding child %s as sink since it has unlinked source pads in this bin",
|
||||
GST_OBJECT_NAME (child));
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
GST_UNLOCK (child);
|
||||
|
||||
/* we did not find the element, need to release the ref
|
||||
* added by the iterator */
|
||||
if (ret == 1)
|
||||
gst_object_unref (GST_OBJECT (child));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bin_iterate_sinks:
|
||||
* @bin: #Gstbin to iterate on
|
||||
*
|
||||
* Get an iterator for the sink elements in this bin.
|
||||
* Each element will have its refcount increased, so unref
|
||||
* after usage.
|
||||
*
|
||||
* Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
GstIterator *
|
||||
gst_bin_iterate_sinks (GstBin * bin)
|
||||
{
|
||||
GstIterator *children;
|
||||
GstIterator *result;
|
||||
|
||||
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
|
||||
|
||||
children = gst_bin_iterate_elements (bin);
|
||||
result = gst_iterator_filter (children,
|
||||
(GCompareFunc) bin_element_is_sink, bin);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_bin_child_state_change:
|
||||
* @bin: #GstBin with the child
|
||||
|
@ -1197,7 +1295,6 @@ gst_bin_iterate_all_by_interface (GstBin * bin, GType interface)
|
|||
children = gst_bin_iterate_recurse (bin);
|
||||
result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
|
||||
GINT_TO_POINTER (interface));
|
||||
gst_iterator_free (children);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -60,8 +60,7 @@ GST_EXPORT GType _gst_bin_type;
|
|||
* and (un)set using GST_FLAG_SET () and GST_FLAG_UNSET ().
|
||||
*/
|
||||
typedef enum {
|
||||
GST_BIN_FLAG_FIXED_CLOCK = GST_ELEMENT_FLAG_LAST,
|
||||
GST_BIN_FLAG_MANAGER,
|
||||
GST_BIN_FLAG_MANAGER = GST_ELEMENT_FLAG_LAST,
|
||||
GST_BIN_SELF_SCHEDULABLE,
|
||||
GST_BIN_STATE_LOCKED,
|
||||
/* padding */
|
||||
|
|
|
@ -252,7 +252,7 @@ gst_element_init (GstElement * element)
|
|||
element->srcpads = NULL;
|
||||
element->sinkpads = NULL;
|
||||
element->loopfunc = NULL;
|
||||
element->sched = NULL;
|
||||
element->scheduler = NULL;
|
||||
element->clock = NULL;
|
||||
element->sched_private = NULL;
|
||||
element->state_lock = g_mutex_new ();
|
||||
|
@ -1766,8 +1766,8 @@ void gst_element_error_full
|
|||
GST_ELEMENT_NAME (element), sent_message);
|
||||
|
||||
/* tell the scheduler */
|
||||
if (element->sched) {
|
||||
gst_scheduler_error (element->sched, element);
|
||||
if (GST_ELEMENT_SCHEDULER (element)) {
|
||||
gst_scheduler_error (GST_ELEMENT_SCHEDULER (element), element);
|
||||
}
|
||||
|
||||
if (GST_STATE (element) == GST_STATE_PLAYING) {
|
||||
|
@ -2200,9 +2200,9 @@ gst_element_change_state (GstElement * element)
|
|||
gst_element_state_get_name (GST_STATE (element)));
|
||||
|
||||
/* tell the scheduler if we have one */
|
||||
if (element->sched) {
|
||||
if (gst_scheduler_state_transition (element->sched, element,
|
||||
old_transition) != GST_STATE_SUCCESS) {
|
||||
if (GST_ELEMENT_SCHEDULER (element)) {
|
||||
if (gst_scheduler_state_transition (GST_ELEMENT_SCHEDULER (element),
|
||||
element, old_transition) != GST_STATE_SUCCESS) {
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
|
||||
"scheduler could not change state");
|
||||
goto failure;
|
||||
|
@ -2263,13 +2263,17 @@ gst_element_dispose (GObject * object)
|
|||
while (element->pads) {
|
||||
gst_element_remove_pad (element, GST_PAD (element->pads->data));
|
||||
}
|
||||
if (G_UNLIKELY (element->pads != 0)) {
|
||||
g_critical ("could not remove pads from element %s",
|
||||
GST_STR_NULL (GST_OBJECT_NAME (object)));
|
||||
}
|
||||
|
||||
element->numsrcpads = 0;
|
||||
element->numsinkpads = 0;
|
||||
element->numpads = 0;
|
||||
|
||||
gst_object_replace ((GstObject **) & element->sched, NULL);
|
||||
GST_LOCK (element);
|
||||
gst_object_replace ((GstObject **) & element->scheduler, NULL);
|
||||
gst_object_replace ((GstObject **) & element->clock, NULL);
|
||||
GST_UNLOCK (element);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose parent");
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
@ -2279,8 +2283,16 @@ gst_element_finalize (GObject * object)
|
|||
{
|
||||
GstElement *element = GST_ELEMENT (object);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
|
||||
|
||||
GST_STATE_LOCK (element);
|
||||
if (element->state_cond)
|
||||
g_cond_free (element->state_cond);
|
||||
element->state_cond = NULL;
|
||||
GST_STATE_UNLOCK (element);
|
||||
g_mutex_free (element->state_lock);
|
||||
g_cond_free (element->state_cond);
|
||||
|
||||
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ typedef enum
|
|||
|
||||
#define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj))
|
||||
#define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj))
|
||||
#define GST_ELEMENT_SCHEDULER(obj) (GST_ELEMENT_CAST(obj)->sched)
|
||||
#define GST_ELEMENT_SCHEDULER(obj) (GST_ELEMENT_CAST(obj)->scheduler)
|
||||
#define GST_ELEMENT_CLOCK(obj) (GST_ELEMENT_CAST(obj)->clock)
|
||||
#define GST_ELEMENT_PADS(obj) (GST_ELEMENT_CAST(obj)->pads)
|
||||
|
||||
|
@ -183,7 +183,7 @@ typedef void (*GstElementLoopFunction) (GstElement *element);
|
|||
#define GST_STATE_SIGNAL(elem) g_cond_signal (GST_STATE_GET_COND (elem));
|
||||
#define GST_STATE_BROADCAST(elem) g_cond_broadcast (GST_STATE_GET_COND (elem));
|
||||
|
||||
struct _GstElement
|
||||
struct _GstElement
|
||||
{
|
||||
GstObject object;
|
||||
|
||||
|
@ -198,7 +198,7 @@ struct _GstElement
|
|||
/*< public >*/ /* with LOCK */
|
||||
/* scheduling */
|
||||
GstElementLoopFunction loopfunc;
|
||||
GstScheduler *sched;
|
||||
GstScheduler *scheduler;
|
||||
/* private pointer for the scheduler */
|
||||
gpointer sched_private;
|
||||
|
||||
|
@ -246,7 +246,7 @@ struct _GstElementClass
|
|||
void (*found_tag) (GstElement *element, GstElement *source, const GstTagList *tag_list);
|
||||
|
||||
/*< protected >*/
|
||||
/* vtable*/
|
||||
/* vtable */
|
||||
|
||||
/* request/release pads */
|
||||
GstPad* (*request_new_pad) (GstElement *element, GstPadTemplate *templ, const gchar* name);
|
||||
|
@ -278,6 +278,7 @@ struct _GstElementClass
|
|||
const GstQueryType* (*get_query_types) (GstElement *element);
|
||||
gboolean (*query) (GstElement *element, GstQueryType type,
|
||||
GstFormat *format, gint64 *value);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
@ -317,7 +318,6 @@ gboolean gst_element_is_indexable (GstElement *element);
|
|||
void gst_element_set_index (GstElement *element, GstIndex *index);
|
||||
GstIndex* gst_element_get_index (GstElement *element);
|
||||
|
||||
|
||||
/* scheduling */
|
||||
void gst_element_set_loop_function (GstElement *element,
|
||||
GstElementLoopFunction loop);
|
||||
|
@ -366,8 +366,6 @@ void gst_element_default_error (GObject *object, GstObject *orig, GError *err
|
|||
#define gst_element_default_deep_notify gst_object_default_deep_notify
|
||||
|
||||
/* state management */
|
||||
void gst_element_set_eos (GstElement *element);
|
||||
|
||||
gboolean gst_element_is_locked_state (GstElement *element);
|
||||
gboolean gst_element_set_locked_state (GstElement *element, gboolean locked_state);
|
||||
gboolean gst_element_sync_state_with_parent (GstElement *element);
|
||||
|
@ -377,6 +375,8 @@ GstElementStateReturn gst_element_set_state (GstElement *element, GstElementSta
|
|||
|
||||
void gst_element_wait_state_change (GstElement *element);
|
||||
|
||||
void gst_element_set_eos (GstElement *element);
|
||||
|
||||
/* factory management */
|
||||
GstElementFactory* gst_element_get_factory (GstElement *element);
|
||||
|
||||
|
@ -459,4 +459,3 @@ void __gst_element_factory_add_interface (GstElementFactory *elementfactory,
|
|||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_ELEMENT_H__ */
|
||||
|
||||
|
|
|
@ -506,7 +506,7 @@ typedef struct
|
|||
static gboolean
|
||||
find_custom_fold_func (gpointer item, GValue * ret, FindCustomFoldData * data)
|
||||
{
|
||||
if (data->func (item, data->user_data)) {
|
||||
if (data->func (item, data->user_data) == 0) {
|
||||
g_value_set_pointer (ret, item);
|
||||
return FALSE;
|
||||
} else {
|
||||
|
|
10
gst/gstpad.c
10
gst/gstpad.c
|
@ -3587,16 +3587,6 @@ gst_pad_template_new (const gchar * name_template,
|
|||
if (!name_is_valid (name_template, presence))
|
||||
return NULL;
|
||||
|
||||
#if 0
|
||||
#ifdef USE_POISONING
|
||||
if (caps) {
|
||||
GstCaps *newcaps = gst_caps_copy (caps);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
caps = newcaps;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
new = g_object_new (gst_pad_template_get_type (),
|
||||
"name", name_template, NULL);
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "gstpipeline.h"
|
||||
#include "gstinfo.h"
|
||||
#include "gstscheduler.h"
|
||||
#include "gstsystemclock.h"
|
||||
|
||||
static GstElementDetails gst_pipeline_details =
|
||||
GST_ELEMENT_DETAILS ("Pipeline object",
|
||||
|
@ -43,8 +44,10 @@ enum
|
|||
#define DEFAULT_PLAY_TIMEOUT (2*GST_SECOND)
|
||||
enum
|
||||
{
|
||||
ARG_0
|
||||
/* FILL ME */
|
||||
ARG_0,
|
||||
ARG_DELAY,
|
||||
ARG_PLAY_TIMEOUT,
|
||||
/* FILL ME */
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,7 +56,12 @@ static void gst_pipeline_class_init (gpointer g_class, gpointer class_data);
|
|||
static void gst_pipeline_init (GTypeInstance * instance, gpointer g_class);
|
||||
|
||||
static void gst_pipeline_dispose (GObject * object);
|
||||
static void gst_pipeline_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec);
|
||||
static void gst_pipeline_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static GstClock *gst_pipeline_get_clock_func (GstElement * element);
|
||||
static GstElementStateReturn gst_pipeline_change_state (GstElement * element);
|
||||
|
||||
static GstBinClass *parent_class = NULL;
|
||||
|
@ -102,10 +110,24 @@ gst_pipeline_class_init (gpointer g_class, gpointer class_data)
|
|||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pipeline_set_property);
|
||||
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pipeline_get_property);
|
||||
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DELAY,
|
||||
g_param_spec_uint64 ("delay", "Delay",
|
||||
"Expected delay needed for elements "
|
||||
"to spin up to PLAYING in nanoseconds", 0, G_MAXUINT64, DEFAULT_DELAY,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PLAY_TIMEOUT,
|
||||
g_param_spec_uint64 ("play-timeout", "Play Timeout",
|
||||
"Max timeout for going " "to PLAYING in nanoseconds", 0, G_MAXUINT64,
|
||||
DEFAULT_PLAY_TIMEOUT, G_PARAM_READWRITE));
|
||||
|
||||
gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pipeline_dispose);
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
|
||||
gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_pipeline_get_clock_func);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -134,15 +156,55 @@ static void
|
|||
gst_pipeline_dispose (GObject * object)
|
||||
{
|
||||
GstPipeline *pipeline = GST_PIPELINE (object);
|
||||
GstScheduler *sched;
|
||||
|
||||
g_assert (GST_IS_SCHEDULER (GST_ELEMENT_SCHEDULER (pipeline)));
|
||||
sched = GST_ELEMENT_SCHEDULER (pipeline);
|
||||
gst_scheduler_reset (GST_ELEMENT_SCHEDULER (object));
|
||||
gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
|
||||
|
||||
gst_scheduler_reset (sched);
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pipeline_set_property (GObject * object, guint prop_id,
|
||||
const GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPipeline *pipeline = GST_PIPELINE (object);
|
||||
|
||||
GST_LOCK (pipeline);
|
||||
switch (prop_id) {
|
||||
case ARG_DELAY:
|
||||
pipeline->delay = g_value_get_uint64 (value);
|
||||
break;
|
||||
case ARG_PLAY_TIMEOUT:
|
||||
pipeline->play_timeout = g_value_get_uint64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
GST_UNLOCK (pipeline);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_pipeline_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
{
|
||||
GstPipeline *pipeline = GST_PIPELINE (object);
|
||||
|
||||
GST_LOCK (pipeline);
|
||||
switch (prop_id) {
|
||||
case ARG_DELAY:
|
||||
g_value_set_uint64 (value, pipeline->delay);
|
||||
break;
|
||||
case ARG_PLAY_TIMEOUT:
|
||||
g_value_set_uint64 (value, pipeline->play_timeout);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
GST_UNLOCK (pipeline);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pipeline_new:
|
||||
* @name: name of new pipeline
|
||||
|
@ -179,3 +241,125 @@ gst_pipeline_change_state (GstElement * element)
|
|||
|
||||
return GST_STATE_SUCCESS;
|
||||
}
|
||||
|
||||
static GstClock *
|
||||
gst_pipeline_get_clock_func (GstElement * element)
|
||||
{
|
||||
GstClock *clock = NULL;
|
||||
GstPipeline *pipeline = GST_PIPELINE (element);
|
||||
|
||||
/* if we have a fixed clock, use that one */
|
||||
GST_LOCK (pipeline);
|
||||
if (GST_FLAG_IS_SET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK)) {
|
||||
clock = pipeline->fixed_clock;
|
||||
gst_object_ref (GST_OBJECT (clock));
|
||||
GST_UNLOCK (pipeline);
|
||||
|
||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using fixed clock %p (%s)",
|
||||
clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
|
||||
} else {
|
||||
GST_UNLOCK (pipeline);
|
||||
clock =
|
||||
GST_ELEMENT_CLASS (parent_class)->get_clock (GST_ELEMENT (pipeline));
|
||||
/* no clock, use a system clock */
|
||||
if (!clock) {
|
||||
clock = gst_system_clock_obtain ();
|
||||
/* we unref since this function is not supposed to increase refcount
|
||||
* of clock object returned; this is ok since the systemclock always
|
||||
* has a refcount of at least one in the current code. */
|
||||
gst_object_unref (GST_OBJECT (clock));
|
||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline obtained system clock: %p (%s)",
|
||||
clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
|
||||
} else {
|
||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline obtained clock: %p (%s)",
|
||||
clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
|
||||
}
|
||||
}
|
||||
return clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pipeline_get_clock:
|
||||
* @pipeline: the pipeline
|
||||
*
|
||||
* Gets the current clock used by the pipeline.
|
||||
*
|
||||
* Returns: a GstClock
|
||||
*/
|
||||
GstClock *
|
||||
gst_pipeline_get_clock (GstPipeline * pipeline)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
|
||||
|
||||
return gst_pipeline_get_clock_func (GST_ELEMENT (pipeline));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_pipeline_use_clock:
|
||||
* @pipeline: the pipeline
|
||||
* @clock: the clock to use
|
||||
*
|
||||
* Force the pipeline to use the given clock. The pipeline will
|
||||
* always use the given clock even if new clock providers are added
|
||||
* to this pipeline.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
void
|
||||
gst_pipeline_use_clock (GstPipeline * pipeline, GstClock * clock)
|
||||
{
|
||||
g_return_if_fail (GST_IS_PIPELINE (pipeline));
|
||||
|
||||
GST_LOCK (pipeline);
|
||||
GST_FLAG_SET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK);
|
||||
|
||||
gst_object_replace ((GstObject **) & pipeline->fixed_clock,
|
||||
(GstObject *) clock);
|
||||
GST_LOCK (pipeline);
|
||||
|
||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using fixed clock %p (%s)", clock,
|
||||
(clock ? GST_OBJECT_NAME (clock) : "nil"));
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pipeline_set_clock:
|
||||
* @pipeline: the pipeline
|
||||
* @clock: the clock to set
|
||||
*
|
||||
* Set the clock for the pipeline. The clock will be distributed
|
||||
* to all the elements managed by the pipeline.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
void
|
||||
gst_pipeline_set_clock (GstPipeline * pipeline, GstClock * clock)
|
||||
{
|
||||
g_return_if_fail (pipeline != NULL);
|
||||
g_return_if_fail (GST_IS_PIPELINE (pipeline));
|
||||
|
||||
GST_ELEMENT_CLASS (parent_class)->set_clock (GST_ELEMENT (pipeline), clock);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_pipeline_auto_clock:
|
||||
* @pipeline: the pipeline
|
||||
*
|
||||
* Let the pipeline select a clock automatically.
|
||||
*
|
||||
* MT safe.
|
||||
*/
|
||||
void
|
||||
gst_pipeline_auto_clock (GstPipeline * pipeline)
|
||||
{
|
||||
g_return_if_fail (pipeline != NULL);
|
||||
g_return_if_fail (GST_IS_PIPELINE (pipeline));
|
||||
|
||||
GST_LOCK (pipeline);
|
||||
GST_FLAG_UNSET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK);
|
||||
|
||||
gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
|
||||
GST_UNLOCK (pipeline);
|
||||
|
||||
GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using automatic clock");
|
||||
}
|
||||
|
|
|
@ -277,7 +277,6 @@ void gst_bin_remove_many (GstBin *bin, GstElement *eleme
|
|||
/* buffer functions */
|
||||
GstBuffer * gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2);
|
||||
void gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src);
|
||||
void gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -100,7 +100,7 @@ typedef struct
|
|||
CothreadPrivate;
|
||||
|
||||
#define ELEMENT_PRIVATE(element) ((CothreadPrivate *) GST_ELEMENT (element)->sched_private)
|
||||
#define SCHED(element) (GST_ENTRY_SCHEDULER ((element)->sched))
|
||||
#define SCHED(element) (GST_ENTRY_SCHEDULER ((element)->scheduler))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -647,7 +647,7 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain)
|
|||
if (peerpad) {
|
||||
GstElement *peerelement = GST_ELEMENT (GST_PAD_PARENT (peerpad));
|
||||
gboolean different_sched =
|
||||
(peerelement->sched != GST_SCHEDULER (chain->sched));
|
||||
(peerelement->scheduler != GST_SCHEDULER (chain->sched));
|
||||
gboolean peer_decoupled =
|
||||
GST_FLAG_IS_SET (peerelement, GST_ELEMENT_DECOUPLED);
|
||||
|
||||
|
@ -804,7 +804,7 @@ gst_basic_scheduler_chain_add_element (GstSchedulerChain * chain,
|
|||
GstElement * element)
|
||||
{
|
||||
/* set the sched pointer for the element */
|
||||
element->sched = GST_SCHEDULER (chain->sched);
|
||||
element->scheduler = GST_SCHEDULER (chain->sched);
|
||||
|
||||
/* add the element to either the main list or the disabled list */
|
||||
if (GST_STATE (element) == GST_STATE_PLAYING) {
|
||||
|
|
|
@ -19,10 +19,12 @@ install-pluginLTLIBRARIES:
|
|||
CLEANFILES = core.*
|
||||
|
||||
TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@ \
|
||||
gst/gstcaps \
|
||||
gst/gstdata \
|
||||
gst/gstiterator \
|
||||
gst/gstobject \
|
||||
gst/gstbin \
|
||||
gst/gstcaps \
|
||||
gst/gstdata \
|
||||
gst/gstiterator \
|
||||
gst/gstobject \
|
||||
gst/gstsystemclock \
|
||||
gst-libs/gdp
|
||||
|
||||
check_PROGRAMS = $(TESTS)
|
||||
|
|
110
tests/check/gst/gstbin.c
Normal file
110
tests/check/gst/gstbin.c
Normal file
|
@ -0,0 +1,110 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* gstbin.c: Unit test for GstBin
|
||||
*
|
||||
* 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 "../gstcheck.h"
|
||||
|
||||
START_TEST (test_interface)
|
||||
{
|
||||
GstBin *bin, *bin2;
|
||||
GstElement *filesrc;
|
||||
GstIterator *it;
|
||||
gpointer item;
|
||||
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
fail_unless (bin != NULL, "Could not create bin");
|
||||
|
||||
filesrc = gst_element_factory_make ("filesrc", NULL);
|
||||
fail_unless (filesrc != NULL, "Could not create filesrc");
|
||||
fail_unless (GST_IS_URI_HANDLER (filesrc), "Filesrc not a URI handler");
|
||||
gst_bin_add (bin, filesrc);
|
||||
|
||||
fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (it != NULL);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (item == (gpointer) filesrc);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add_many (bin,
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL), NULL);
|
||||
fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (it != NULL);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (item == (gpointer) filesrc);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
bin2 = bin;
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
fail_unless (bin != NULL);
|
||||
gst_bin_add_many (bin,
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
|
||||
fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (item == (gpointer) filesrc);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
|
||||
gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
g_object_unref (bin);
|
||||
}
|
||||
END_TEST Suite * gst_bin_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("GstBin");
|
||||
TCase *tc_chain = tcase_create ("bin tests");
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_interface);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int nf;
|
||||
|
||||
Suite *s = gst_bin_suite ();
|
||||
SRunner *sr = srunner_create (s);
|
||||
|
||||
gst_check_init (&argc, &argv);
|
||||
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
nf = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
|
||||
return nf;
|
||||
}
|
221
tests/check/gst/gstsystemclock.c
Normal file
221
tests/check/gst/gstsystemclock.c
Normal file
|
@ -0,0 +1,221 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* gstsystemclock.c: Unit test for GstSystemClock
|
||||
*
|
||||
* 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 "../gstcheck.h"
|
||||
|
||||
START_TEST (test_signedness)
|
||||
{
|
||||
GstClockTime time[] = { 0, 1, G_MAXUINT64 / GST_SECOND };
|
||||
GstClockTimeDiff diff[] =
|
||||
{ 0, 1, -1, G_MAXINT64 / GST_SECOND, G_MININT64 / GST_SECOND };
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (time); i++) {
|
||||
fail_if (time[i] != (time[i] * GST_SECOND / GST_SECOND));
|
||||
}
|
||||
for (i = 0; i < G_N_ELEMENTS (diff); i++) {
|
||||
fail_if (diff[i] != (diff[i] * GST_SECOND / GST_SECOND));
|
||||
}
|
||||
}
|
||||
|
||||
END_TEST
|
||||
#define TIME_UNIT GST_SECOND
|
||||
static void
|
||||
gst_clock_debug (GstClock * clock)
|
||||
{
|
||||
GstClockTime time;
|
||||
|
||||
time = gst_clock_get_time (clock);
|
||||
g_message ("Clock info: time %" G_GUINT64_FORMAT "\n", time);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ok_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, gpointer user_data)
|
||||
{
|
||||
g_message ("unlocked async id %p\n", id);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
error_callback (GstClock * clock, GstClockTime time,
|
||||
GstClockID id, gpointer user_data)
|
||||
{
|
||||
g_message ("unlocked unscheduled async id %p, this is wrong\n", id);
|
||||
fail_if (TRUE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
START_TEST (test_single_shot)
|
||||
{
|
||||
GstClock *clock;
|
||||
GstClockID id, id2;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
fail_unless (clock != NULL, "Could not create instance of GstSystemClock");
|
||||
|
||||
gst_clock_debug (clock);
|
||||
base = gst_clock_get_time (clock);
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + TIME_UNIT);
|
||||
fail_unless (id != NULL, "Could not create single shot id");
|
||||
|
||||
g_message ("waiting one second\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
|
||||
g_message ("waiting in the past\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_EARLY, "Waiting did not return EARLY");
|
||||
gst_clock_id_unref (id);
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + 2 * TIME_UNIT);
|
||||
g_message ("waiting one second async id %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
gst_clock_id_unref (id);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
id = gst_clock_new_single_shot_id (clock, base + 5 * TIME_UNIT);
|
||||
g_message ("waiting one second async, with cancel on id %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, error_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (G_USEC_PER_SEC / 2);
|
||||
g_message ("cancel id %p after 0.5 seconds\n", id);
|
||||
gst_clock_id_unschedule (id);
|
||||
gst_clock_id_unref (id);
|
||||
g_message ("canceled id %p\n", id);
|
||||
|
||||
g_message ("waiting multiple one second async, with cancel\n");
|
||||
id = gst_clock_new_single_shot_id (clock, base + 5 * TIME_UNIT);
|
||||
id2 = gst_clock_new_single_shot_id (clock, base + 6 * TIME_UNIT);
|
||||
g_message ("waiting id %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
gst_clock_id_unref (id);
|
||||
g_message ("waiting id %p\n", id2);
|
||||
result = gst_clock_id_wait_async (id2, error_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (G_USEC_PER_SEC / 2);
|
||||
g_message ("cancel id %p after 0.5 seconds\n", id2);
|
||||
gst_clock_id_unschedule (id2);
|
||||
g_message ("canceled id %p\n", id2);
|
||||
gst_clock_id_unref (id2);
|
||||
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
}
|
||||
|
||||
END_TEST
|
||||
START_TEST (test_periodic_shot)
|
||||
{
|
||||
GstClock *clock;
|
||||
GstClockID id, id2;
|
||||
GstClockTime base;
|
||||
GstClockReturn result;
|
||||
|
||||
clock = gst_system_clock_obtain ();
|
||||
fail_unless (clock != NULL, "Could not create instance of GstSystemClock");
|
||||
|
||||
gst_clock_debug (clock);
|
||||
base = gst_clock_get_time (clock);
|
||||
|
||||
/* signal every half a second */
|
||||
id = gst_clock_new_periodic_id (clock, base + TIME_UNIT, TIME_UNIT / 2);
|
||||
fail_unless (id != NULL, "Could not create periodic id");
|
||||
|
||||
g_message ("waiting one second\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
|
||||
g_message ("waiting for the next\n");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
gst_clock_debug (clock);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
|
||||
g_message ("waiting for the next async %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
g_message ("waiting some more for the next async %p\n", id);
|
||||
result = gst_clock_id_wait_async (id, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
id2 = gst_clock_new_periodic_id (clock, base + TIME_UNIT, TIME_UNIT / 2);
|
||||
fail_unless (id2 != NULL, "Could not create second periodic id");
|
||||
|
||||
g_message ("waiting some more for another async %p\n", id2);
|
||||
result = gst_clock_id_wait_async (id2, ok_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_OK, "Waiting did not return OK");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
|
||||
g_message ("unschedule %p\n", id);
|
||||
gst_clock_id_unschedule (id);
|
||||
|
||||
/* entry cannot be used again */
|
||||
result = gst_clock_id_wait_async (id, error_callback, NULL);
|
||||
fail_unless (result == GST_CLOCK_UNSCHEDULED,
|
||||
"Waiting did not return UNSCHEDULED");
|
||||
result = gst_clock_id_wait (id, NULL);
|
||||
fail_unless (result == GST_CLOCK_UNSCHEDULED,
|
||||
"Waiting did not return UNSCHEDULED");
|
||||
g_usleep (2 * G_USEC_PER_SEC);
|
||||
}
|
||||
|
||||
END_TEST Suite * gst_systemclock_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("GstSystemClock");
|
||||
TCase *tc_chain = tcase_create ("waiting");
|
||||
|
||||
/* increase timeout */
|
||||
tcase_set_timeout (tc_chain, 20);
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_signedness);
|
||||
tcase_add_test (tc_chain, test_single_shot);
|
||||
tcase_add_test (tc_chain, test_periodic_shot);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int nf;
|
||||
|
||||
Suite *s = gst_systemclock_suite ();
|
||||
SRunner *sr = srunner_create (s);
|
||||
|
||||
gst_check_init (&argc, &argv);
|
||||
|
||||
srunner_run_all (sr, CK_NORMAL);
|
||||
nf = srunner_ntests_failed (sr);
|
||||
srunner_free (sr);
|
||||
|
||||
return nf;
|
||||
}
|
|
@ -25,8 +25,9 @@ gint
|
|||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstBin *bin, *bin2;
|
||||
GList *list;
|
||||
GstElement *filesrc;
|
||||
GstIterator *it;
|
||||
gpointer item;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
|
@ -39,20 +40,24 @@ main (gint argc, gchar * argv[])
|
|||
gst_bin_add (bin, filesrc);
|
||||
|
||||
g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
g_assert (list->data == (gpointer) filesrc);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (it != NULL);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (item == (gpointer) filesrc);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add_many (bin,
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL), NULL);
|
||||
g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
g_assert (list->data == (gpointer) filesrc);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (it != NULL);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (item == (gpointer) filesrc);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
bin2 = bin;
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
|
@ -62,16 +67,20 @@ main (gint argc, gchar * argv[])
|
|||
gst_element_factory_make ("identity", NULL),
|
||||
GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
|
||||
g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
g_assert (list->data == (gpointer) filesrc);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (item == (gpointer) filesrc);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
|
||||
gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 3);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
g_object_unref (bin);
|
||||
return 0;
|
||||
|
|
|
@ -25,8 +25,9 @@ gint
|
|||
main (gint argc, gchar * argv[])
|
||||
{
|
||||
GstBin *bin, *bin2;
|
||||
GList *list;
|
||||
GstElement *filesrc;
|
||||
GstIterator *it;
|
||||
gpointer item;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
|
@ -39,20 +40,24 @@ main (gint argc, gchar * argv[])
|
|||
gst_bin_add (bin, filesrc);
|
||||
|
||||
g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
g_assert (list->data == (gpointer) filesrc);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (it != NULL);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (item == (gpointer) filesrc);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add_many (bin,
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL),
|
||||
gst_element_factory_make ("identity", NULL), NULL);
|
||||
g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
g_assert (list->data == (gpointer) filesrc);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (it != NULL);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (item == (gpointer) filesrc);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
bin2 = bin;
|
||||
bin = GST_BIN (gst_bin_new (NULL));
|
||||
|
@ -62,16 +67,20 @@ main (gint argc, gchar * argv[])
|
|||
gst_element_factory_make ("identity", NULL),
|
||||
GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
|
||||
g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 1);
|
||||
g_assert (list->data == (gpointer) filesrc);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (item == (gpointer) filesrc);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
|
||||
gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
|
||||
list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (g_list_length (list) == 3);
|
||||
g_list_free (list);
|
||||
it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
|
||||
g_assert (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
|
||||
gst_iterator_free (it);
|
||||
|
||||
g_object_unref (bin);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue