mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-03 15:06:34 +00:00
base: Fix pad callbacks so they handle when parent goes away
1) We need to lock and get a strong ref to the parent, if still there. 2) If it has gone away, we need to handle that gracefully. This is necessary in order to safely modify a running pipeline. Has been observed when a streaming thread is doing a buffer_alloc() while an application thread sends an event on a pad further downstream, and from within a pad probe (holding STREAM_LOCK) carries out the pipeline plumbing while the streaming thread has its buffer_alloc() in progress.
This commit is contained in:
parent
7dd38cdcf4
commit
e7bf5484c7
2 changed files with 19 additions and 2 deletions
|
@ -653,6 +653,8 @@ gst_base_sink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
|
||||||
bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
||||||
|
if (G_UNLIKELY (bsink == NULL))
|
||||||
|
return GST_FLOW_WRONG_STATE;
|
||||||
bclass = GST_BASE_SINK_GET_CLASS (bsink);
|
bclass = GST_BASE_SINK_GET_CLASS (bsink);
|
||||||
|
|
||||||
if (bclass->buffer_alloc)
|
if (bclass->buffer_alloc)
|
||||||
|
@ -3414,6 +3416,10 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
|
||||||
GstBaseSinkClass *bclass;
|
GstBaseSinkClass *bclass;
|
||||||
|
|
||||||
basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
|
||||||
|
if (G_UNLIKELY (basesink == NULL)) {
|
||||||
|
gst_event_unref (event);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
bclass = GST_BASE_SINK_GET_CLASS (basesink);
|
||||||
|
|
||||||
|
|
|
@ -1225,8 +1225,13 @@ static gboolean
|
||||||
gst_base_transform_query (GstPad * pad, GstQuery * query)
|
gst_base_transform_query (GstPad * pad, GstQuery * query)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GstBaseTransform *trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
GstBaseTransform *trans;
|
||||||
GstPad *otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
|
GstPad *otherpad;
|
||||||
|
|
||||||
|
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
||||||
|
if (G_UNLIKELY (trans == NULL))
|
||||||
|
return FALSE;
|
||||||
|
otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
|
||||||
|
|
||||||
switch (GST_QUERY_TYPE (query)) {
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
case GST_QUERY_POSITION:{
|
case GST_QUERY_POSITION:{
|
||||||
|
@ -1715,6 +1720,8 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
||||||
guint size_suggest;
|
guint size_suggest;
|
||||||
|
|
||||||
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
||||||
|
if (G_UNLIKELY (trans == NULL))
|
||||||
|
return GST_FLOW_WRONG_STATE;
|
||||||
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
||||||
priv = trans->priv;
|
priv = trans->priv;
|
||||||
|
|
||||||
|
@ -1997,6 +2004,10 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
|
||||||
gboolean forward = TRUE;
|
gboolean forward = TRUE;
|
||||||
|
|
||||||
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
||||||
|
if (G_UNLIKELY (trans == NULL)) {
|
||||||
|
gst_event_unref (event);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
||||||
|
|
||||||
if (bclass->event)
|
if (bclass->event)
|
||||||
|
|
Loading…
Reference in a new issue