From f126094dce3539c94b3a50dfc9622143a1ba2649 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Fri, 19 Jun 2015 00:05:44 -0400 Subject: [PATCH] pad: Enforce NEED_PARENT flag also for chain The check for the presence of the parent in the presence of the NEED_PARENT flag was missing for the chain function. Also keep a ref on the parent in case the pad is removed mid-chain. --- gst/gstpad.c | 13 ++++++++++++- tests/check/gst/gstbin.c | 6 +++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/gst/gstpad.c b/gst/gstpad.c index c4e8ff25f6..34735a0bba 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -4017,7 +4017,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data) PROBE_PUSH (pad, type, data, probe_stopped); - parent = GST_OBJECT_PARENT (pad); + ACQUIRE_PARENT (pad, parent, no_parent); GST_OBJECT_UNLOCK (pad); /* NOTE: we read the chainfunc unlocked. @@ -4057,6 +4057,8 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data) GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret)); } + RELEASE_PARENT (parent); + GST_PAD_STREAM_UNLOCK (pad); return ret; @@ -4105,8 +4107,17 @@ probe_stopped: } return ret; } +no_parent: + { + GST_DEBUG_OBJECT (pad, "No parent when chaining %" GST_PTR_FORMAT, data); + gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); + GST_OBJECT_UNLOCK (pad); + GST_PAD_STREAM_UNLOCK (pad); + return GST_FLOW_FLUSHING; + } no_function: { + RELEASE_PARENT (parent); gst_mini_object_unref (GST_MINI_OBJECT_CAST (data)); g_critical ("chain on pad %s:%s but it has no chainfunction", GST_DEBUG_PAD_NAME (pad)); diff --git a/tests/check/gst/gstbin.c b/tests/check/gst/gstbin.c index 409e273ff3..171884fcb9 100644 --- a/tests/check/gst/gstbin.c +++ b/tests/check/gst/gstbin.c @@ -462,7 +462,7 @@ GST_START_TEST (test_message_state_changed_children) ASSERT_OBJECT_REFCOUNT (bus, "bus", 2); ASSERT_OBJECT_REFCOUNT (src, "src", 1); - ASSERT_OBJECT_REFCOUNT (sink, "sink", 1); + ASSERT_OBJECT_REFCOUNT (sink, "sink", 2); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); /* change state to PLAYING, spawning three messages */ @@ -481,7 +481,7 @@ GST_START_TEST (test_message_state_changed_children) * sink might have an extra reference if it's still blocked on preroll * pipeline posted a new-clock message too. */ ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 2, 3); - ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3); + ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 4); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3); pop_messages (bus, 3); @@ -491,7 +491,7 @@ GST_START_TEST (test_message_state_changed_children) /* src might have an extra reference if it's still pushing */ ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 1, 2); /* sink might have an extra reference if it's still blocked on preroll */ - ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2); + ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 3); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); /* go back to READY, spawning six messages */