mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-20 13:06:23 +00:00
test-appsrc: Test state when blocked in caps Event
In GStreamer 1.12 and older, the GstBaseSrc live lock used to be held while create() virtual function was called. As appsrc pushes serialized event in that virtual function, we ended up with some deadlock while setting the state to NULL. This test simulates this situation. https://bugzilla.gnome.org/show_bug.cgi?id=783301
This commit is contained in:
parent
bfba213437
commit
b39f5067e3
1 changed files with 65 additions and 0 deletions
|
@ -419,6 +419,70 @@ GST_START_TEST (test_appsrc_caps_in_push_modes)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
/* This test simulates a pipeline blocked pushing caps using a blocking pad
|
||||
* probe. This state is seen if the application push buffers and later change
|
||||
* the caps on one stream before the other stream have prerolled. In this
|
||||
* state, GStreamer 1.12 and previous would deadlock inside GstBaseSrc as
|
||||
* it was holding the live lock while calling create(). AppSrc serialize the
|
||||
* caps event into it's queue and then push it downstream when create() is
|
||||
* called. */
|
||||
|
||||
static GstPadProbeReturn
|
||||
caps_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
|
||||
{
|
||||
GMainLoop *loop = user_data;
|
||||
|
||||
if (GST_EVENT_TYPE (info->data) == GST_EVENT_CAPS) {
|
||||
g_main_loop_quit (loop);
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
return GST_PAD_PROBE_PASS;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_appsrc_blocked_on_caps)
|
||||
{
|
||||
GstElement *pipeline = NULL, *app = NULL;
|
||||
GstPad *pad = NULL;
|
||||
GstCaps *caps = NULL;
|
||||
GError *error = NULL;
|
||||
GMainLoop *loop;
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
pipeline = gst_parse_launch ("appsrc is-live=1 name=app ! fakesink", &error);
|
||||
g_assert_no_error (error);
|
||||
|
||||
app = gst_bin_get_by_name (GST_BIN (pipeline), "app");
|
||||
pad = gst_element_get_static_pad (app, "src");
|
||||
|
||||
gst_pad_add_probe (pad,
|
||||
GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
|
||||
caps_event_probe_cb, loop, NULL);
|
||||
gst_object_unref (app);
|
||||
gst_object_unref (pad);
|
||||
|
||||
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
||||
|
||||
caps = gst_caps_from_string ("application/x-test");
|
||||
gst_app_src_set_caps (GST_APP_SRC (app), caps);
|
||||
gst_caps_unref (caps);
|
||||
|
||||
g_main_loop_run (loop);
|
||||
|
||||
#if 0
|
||||
/* This would work around the issue by deblocking the source on older
|
||||
* version of GStreamer */
|
||||
gst_element_send_event (app, gst_event_new_flush_start ());
|
||||
#endif
|
||||
|
||||
/* As appsrc change the caps GstBaseSrc::create() virtual function, the live
|
||||
* lock use to remains held and prevented the state change from happening. */
|
||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
appsrc_suite (void)
|
||||
{
|
||||
|
@ -428,6 +492,7 @@ appsrc_suite (void)
|
|||
tcase_add_test (tc_chain, test_appsrc_non_null_caps);
|
||||
tcase_add_test (tc_chain, test_appsrc_set_caps_twice);
|
||||
tcase_add_test (tc_chain, test_appsrc_caps_in_push_modes);
|
||||
tcase_add_test (tc_chain, test_appsrc_blocked_on_caps);
|
||||
|
||||
if (RUNNING_ON_VALGRIND)
|
||||
tcase_add_loop_test (tc_chain, test_appsrc_block_deadlock, 0, 5);
|
||||
|
|
Loading…
Reference in a new issue