gst/gstbin.c: Always change the state of a NO_PREROLL element even if it has ASYNC elements inside (in case of a bin).

Original commit message from CVS:
* gst/gstbin.c: (gst_bin_element_set_state):
Always change the state of a NO_PREROLL element even if it has ASYNC
elements inside (in case of a bin).
* tests/check/generic/sinks.c: (GST_START_TEST), (gst_sinks_suite):
Unit test for this case.
This commit is contained in:
Wim Taymans 2007-08-14 13:37:16 +00:00
parent 7c2e8138b6
commit 9b24336ce5
3 changed files with 71 additions and 2 deletions

View file

@ -1,3 +1,12 @@
2007-08-14 Wim Taymans <wim.taymans@gmail.com>
* gst/gstbin.c: (gst_bin_element_set_state):
Always change the state of a NO_PREROLL element even if it has ASYNC
elements inside (in case of a bin).
* tests/check/generic/sinks.c: (GST_START_TEST), (gst_sinks_suite):
Unit test for this case.
2007-08-13 Stefan Kost <ensonic@users.sf.net>
* libs/gst/check/gstbufferstraw.c:

View file

@ -1834,6 +1834,14 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element,
if (G_UNLIKELY (locked))
goto locked;
/* if the element was no preroll, just start changing the state regardless
* if it had async elements (in the case of a bin) because they won't preroll
* anyway. */
if (G_UNLIKELY (ret == GST_STATE_CHANGE_NO_PREROLL)) {
GST_DEBUG_OBJECT (element, "element is NO_PREROLL, ignore async elements");
goto no_preroll;
}
GST_OBJECT_LOCK (bin);
/* the element was busy with an upwards async state change, we must wait for
* an ASYNC_DONE message before we attemp to change the state. */
@ -1864,6 +1872,7 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element,
no_latency:
GST_OBJECT_UNLOCK (bin);
no_preroll:
GST_DEBUG_OBJECT (bin,
"setting element %s to %s, base_time %" GST_TIME_FORMAT,
GST_ELEMENT_NAME (element), gst_element_state_get_name (next),

View file

@ -846,9 +846,59 @@ GST_START_TEST (test_add_live2)
GST_END_TEST;
GST_START_TEST (test_bin_live)
{
GstElement *sink, *src, *pipeline, *bin;
GstStateChangeReturn ret;
GstState current, pending;
GstPad *srcpad, *sinkpad;
pipeline = gst_pipeline_new ("pipeline");
bin = gst_bin_new ("bin");
src = gst_element_factory_make ("fakesrc", "src");
g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
sink = gst_element_factory_make ("fakesink", "sink");
gst_bin_add (GST_BIN (bin), src);
gst_bin_add (GST_BIN (bin), sink);
gst_bin_add (GST_BIN (pipeline), bin);
srcpad = gst_element_get_pad (src, "src");
sinkpad = gst_element_get_pad (sink, "sink");
gst_pad_link (srcpad, sinkpad);
gst_object_unref (srcpad);
gst_object_unref (sinkpad);
/* PAUSED returns NO_PREROLL because of the live source */
ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
"no NO_PREROLL state return");
ret =
gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
fail_unless (current == GST_STATE_PAUSED, "not paused");
fail_unless (pending == GST_STATE_VOID_PENDING, "not void pending");
/* when going to PLAYING, the sink should go to PLAYING ASYNC */
ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not ASYNC");
/* now wait for PLAYING to complete */
ret =
gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
fail_unless (current == GST_STATE_PLAYING, "not playing");
fail_unless (pending == GST_STATE_VOID_PENDING, "not void pending");
ret = gst_element_set_state (pipeline, GST_STATE_NULL);
fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot null pipeline");
gst_object_unref (pipeline);
}
GST_END_TEST
/* test: try changing state of sinks */
Suite *
gst_sinks_suite (void)
Suite * gst_sinks_suite (void)
{
Suite *s = suite_create ("Sinks");
TCase *tc_chain = tcase_create ("general");
@ -868,6 +918,7 @@ gst_sinks_suite (void)
tcase_add_test (tc_chain, test_added_async2);
tcase_add_test (tc_chain, test_add_live);
tcase_add_test (tc_chain, test_add_live2);
tcase_add_test (tc_chain, test_bin_live);
return s;
}