Skip to content

Commit c3fb321

Browse files
author
Alexander Matveev
committed
8252107: Media pipeline initialization can crash if audio or video bin state change fails
Reviewed-by: kcr, arapte
1 parent eb9886a commit c3fb321

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

modules/javafx.media/src/main/native/jfxmedia/platform/gstreamer/GstAVPlaybackPipeline.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -434,6 +434,7 @@ void CGstAVPlaybackPipeline::on_pad_added(GstElement *element, GstPad *pad, CGst
434434
const gchar* pstrName = gst_structure_get_name(pStructure);
435435
GstPad *pPad = NULL;
436436
GstPadLinkReturn ret = GST_PAD_LINK_OK;
437+
GstStateChangeReturn stateRet = GST_STATE_CHANGE_FAILURE;
437438

438439
if (g_str_has_prefix(pstrName, "audio"))
439440
{
@@ -453,7 +454,20 @@ void CGstAVPlaybackPipeline::on_pad_added(GstElement *element, GstPad *pad, CGst
453454
{
454455
pPad = gst_element_get_static_pad(pPipeline->m_Elements[AUDIO_BIN], "sink");
455456
gst_bin_add(GST_BIN (pPipeline->m_Elements[PIPELINE]), pPipeline->m_Elements[AUDIO_BIN]);
456-
gst_element_set_state(pPipeline->m_Elements[AUDIO_BIN], GST_STATE_READY);
457+
stateRet = gst_element_set_state(pPipeline->m_Elements[AUDIO_BIN], GST_STATE_READY);
458+
if (stateRet == GST_STATE_CHANGE_FAILURE)
459+
{
460+
gst_object_ref(pPipeline->m_Elements[AUDIO_BIN]);
461+
gst_bin_remove(GST_BIN (pPipeline->m_Elements[PIPELINE]), pPipeline->m_Elements[AUDIO_BIN]);
462+
// Remove handles, so we do not receive any more notifications about pads being added or
463+
// when we done adding new pads. Since we fail to switch bin state we got fatal error and
464+
// bus callback will move pipeline into GST_STATE_NULL while holding dispose lock and
465+
// demux (qtdemux) might deadlock since it will call on_pad_added or no_more_pads
466+
// and these callback will hold dispose lock as well.
467+
g_signal_handlers_disconnect_by_func(element, (void*)G_CALLBACK(on_pad_added), pPipeline);
468+
g_signal_handlers_disconnect_by_func(element, (void*)G_CALLBACK(no_more_pads), pPipeline);
469+
goto Error;
470+
}
457471
if (pPad != NULL)
458472
{
459473
ret = gst_pad_link (pad, pPad);
@@ -462,6 +476,8 @@ void CGstAVPlaybackPipeline::on_pad_added(GstElement *element, GstPad *pad, CGst
462476
gst_element_set_state(pPipeline->m_Elements[AUDIO_BIN], GST_STATE_NULL);
463477
gst_object_ref(pPipeline->m_Elements[AUDIO_BIN]);
464478
gst_bin_remove(GST_BIN (pPipeline->m_Elements[PIPELINE]), pPipeline->m_Elements[AUDIO_BIN]);
479+
// We might need to remove callbacks here as well, but it was not necessary before,
480+
// so to avoid any regression we will not do it here.
465481
goto Error;
466482
}
467483
}
@@ -476,7 +492,15 @@ void CGstAVPlaybackPipeline::on_pad_added(GstElement *element, GstPad *pad, CGst
476492
{
477493
pPad = gst_element_get_static_pad(pPipeline->m_Elements[VIDEO_BIN], "sink");
478494
gst_bin_add (GST_BIN (pPipeline->m_Elements[PIPELINE]), pPipeline->m_Elements[VIDEO_BIN]);
479-
gst_element_set_state(pPipeline->m_Elements[VIDEO_BIN], GST_STATE_READY);
495+
stateRet = gst_element_set_state(pPipeline->m_Elements[VIDEO_BIN], GST_STATE_READY);
496+
if (stateRet == GST_STATE_CHANGE_FAILURE)
497+
{
498+
gst_object_ref(pPipeline->m_Elements[VIDEO_BIN]);
499+
gst_bin_remove(GST_BIN (pPipeline->m_Elements[PIPELINE]), pPipeline->m_Elements[VIDEO_BIN]);
500+
g_signal_handlers_disconnect_by_func(element, (void*)G_CALLBACK(on_pad_added), pPipeline);
501+
g_signal_handlers_disconnect_by_func(element, (void*)G_CALLBACK(no_more_pads), pPipeline);
502+
goto Error;
503+
}
480504
if (pPad != NULL)
481505
{
482506
ret = gst_pad_link (pad, pPad);

0 commit comments

Comments
 (0)