Revert "typefind: Store caps on the pad before emitting have-type but send it downstream only in the default signal handler"

This reverts commit 0835c3d656.

It causes deadlocks in decodebin, which currently would deadlock if the caps
are already on the pad in have-type and are forwarded while copying the sticky
events (while holding the decodebin lock)... as that might cause the next
element to expose pads, which then calls back into decodebin and takes the
decodebin lock.

This needs some more thoughts.
This commit is contained in:
Sebastian Dröge 2016-03-12 12:56:28 +02:00
parent 0835c3d656
commit a15fca1934

View file

@ -172,62 +172,18 @@ static void
gst_type_find_element_have_type (GstTypeFindElement * typefind,
guint probability, GstCaps * caps)
{
GstEvent *event;
g_assert (caps != NULL);
GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", probability=%u",
caps, probability);
GST_OBJECT_LOCK (typefind);
/* Now actually send the CAPS event downstream.
*
* Try to directly send the CAPS event downstream that we created in
* gst_type_find_element_emit_have_type() if it is still there, instead
* of creating a new one. No need to create an equivalent one, replacing
* it in the sticky event list and possibly causing renegotiation
*/
event = gst_pad_get_sticky_event (typefind->src, GST_EVENT_CAPS, 0);
if (event) {
GstCaps *event_caps;
gst_event_parse_caps (event, &event_caps);
if (caps == event_caps) {
event = event;
} else {
gst_event_unref (event);
event = gst_event_new_caps (caps);
}
} else {
event = gst_event_new_caps (caps);
}
if (typefind->caps)
gst_caps_unref (typefind->caps);
typefind->caps = gst_caps_ref (caps);
GST_OBJECT_UNLOCK (typefind);
gst_pad_push_event (typefind->src, event);
}
static void
gst_type_find_element_emit_have_type (GstTypeFindElement * typefind,
guint probability, GstCaps * caps)
{
GstEvent *event;
/* Only store the caps event at this point. We give signal handlers
* the chance to look at the caps before they are sent downstream.
* They are only forwarded downstream later in the default signal
* handler after all application signal handlers
*/
event = gst_event_new_caps (caps);
gst_pad_store_sticky_event (typefind->src, event);
gst_event_unref (event);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
probability, caps);
gst_pad_set_caps (typefind->src, caps);
}
static void
@ -773,7 +729,8 @@ gst_type_find_element_setcaps (GstTypeFindElement * typefind, GstCaps * caps)
if (gst_caps_is_any (caps))
return TRUE;
gst_type_find_element_emit_have_type (typefind, GST_TYPE_FIND_MAXIMUM, caps);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
GST_TYPE_FIND_MAXIMUM, caps);
/* Shortcircuit typefinding if we get caps */
GST_DEBUG_OBJECT (typefind, "Skipping typefinding, using caps from "
@ -957,7 +914,8 @@ gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
/* probability is good enough too, so let's make it known ... emiting this
* signal calls our object handler which sets the caps. */
gst_type_find_element_emit_have_type (typefind, probability, caps);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
probability, caps);
/* .. and send out the accumulated data */
stop_typefinding (typefind);
@ -1148,7 +1106,8 @@ gst_type_find_element_loop (GstPad * pad)
}
GST_DEBUG ("Emiting found caps %" GST_PTR_FORMAT, found_caps);
gst_type_find_element_emit_have_type (typefind, probability, found_caps);
g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
0, probability, found_caps);
typefind->mode = MODE_NORMAL;
gst_caps_unref (found_caps);
} else if (typefind->mode == MODE_NORMAL) {