diff options
author | Jan Schmidt <jan@centricular.com> | 2021-07-07 17:12:52 +0300 |
---|---|---|
committer | Jan Schmidt <jan@centricular.com> | 2021-07-26 09:22:23 +0300 |
commit | b50d3b9c9fa93af1dcf5162b3b2424209659c2bf (patch) | |
tree | a90f103c9986d2e7474bdaa068899924ed6baf1f /tests | |
parent | 2c85fd1be94c1f3f03294beaf750d45bc9418f6c (diff) |
splitmuxsink: Prevent hang going back to NULL after failures
Prevent a condition where splitmuxsink won't go back to NULL state
after a child element fails to change state by making sure that
a READY->READY state change doesn't fail, and by returning
GST_FLOW_ERROR or GST_FLOW_FLUSHING upstream to shut down streaming
as quickly as possible.
This can happen after (for example) setting an invalid filename
on the sink element. In that case, the READY->PAUSED transition
fails, but with internal elements still in the NULL state. Trying
to set splitmuxsink back to NULL then ends up trying to bring
those NULL elements up to READY with a READY->READY transition,
(which fails, prevent splitmuxsink from getting to NULL)
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/1023>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/check/elements/splitmuxsink.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/tests/check/elements/splitmuxsink.c b/tests/check/elements/splitmuxsink.c index 9db9b91cf..93c86e748 100644 --- a/tests/check/elements/splitmuxsink.c +++ b/tests/check/elements/splitmuxsink.c @@ -433,6 +433,43 @@ GST_START_TEST (test_splitmuxsink) GST_END_TEST; +GST_START_TEST (test_splitmuxsink_clean_failure) +{ + GstMessage *msg; + GstElement *pipeline; + GstElement *sink, *fakesink; + + /* This pipeline has a small time cutoff - it should start a new file + * every GOP, ie 1 second */ + pipeline = + gst_parse_launch + ("videotestsrc horizontal-speed=2 is-live=true ! video/x-raw,width=80,height=64,framerate=5/1 ! videoconvert !" + " queue ! theoraenc keyframe-force=5 ! splitmuxsink name=splitsink " + " max-size-time=1000000 max-size-bytes=1000000 muxer=oggmux", NULL); + fail_if (pipeline == NULL); + sink = gst_bin_get_by_name (GST_BIN (pipeline), "splitsink"); + fail_if (sink == NULL); + + fakesink = gst_element_factory_make ("fakesink", "fakesink-fail"); + fail_if (fakesink == NULL); + + /* Trigger an error on READY->PAUSED */ + g_object_set (fakesink, "state-error", 2, NULL); + g_object_set (sink, "sink", fakesink, NULL); + gst_object_unref (sink); + + msg = run_pipeline (pipeline); + + fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR); + gst_message_unref (msg); + + fail_unless (gst_element_set_state (pipeline, + GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS); + gst_object_unref (pipeline); +} + +GST_END_TEST; + GST_START_TEST (test_splitmuxsink_multivid) { GstMessage *msg; @@ -807,6 +844,7 @@ splitmuxsink_suite (void) tcase_add_checked_fixture (tc_chain, tempdir_setup, tempdir_cleanup); tcase_add_test (tc_chain, test_splitmuxsink); + tcase_add_test (tc_chain, test_splitmuxsink_clean_failure); if (have_matroska && have_vorbis) { tcase_add_checked_fixture (tc_chain_complex, tempdir_setup, |