mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 02:45:35 +00:00
parse: Don't hold element's object lock while querying element pads' caps
This can easily deadlock if the element uses the object lock for something internally, like posting an error message. Use an GstIterator for iterating over the pads instead. https://bugzilla.gnome.org/show_bug.cgi?id=777449
This commit is contained in:
parent
b3296183fc
commit
80c5fd50db
1 changed files with 28 additions and 16 deletions
|
@ -587,32 +587,44 @@ static gboolean
|
|||
gst_parse_element_can_do_caps (GstElement * e, GstPadDirection dir,
|
||||
GstCaps * link_caps)
|
||||
{
|
||||
gboolean can_do = FALSE;
|
||||
GList *pads;
|
||||
gboolean can_do = FALSE, done = FALSE;
|
||||
GstIterator *it;
|
||||
|
||||
GST_OBJECT_LOCK (e);
|
||||
it = (dir == GST_PAD_SRC) ? gst_element_iterate_src_pads (e) : gst_element_iterate_sink_pads (e);
|
||||
|
||||
pads = (dir == GST_PAD_SRC) ? e->srcpads : e->sinkpads;
|
||||
|
||||
while (!can_do && pads != NULL) {
|
||||
GstPad *pad = pads->data;
|
||||
while (!done && !can_do) {
|
||||
GValue v = G_VALUE_INIT;
|
||||
GstPad *pad;
|
||||
GstCaps *caps;
|
||||
|
||||
caps = gst_pad_get_current_caps (pad);
|
||||
if (caps == NULL)
|
||||
caps = gst_pad_query_caps (pad, NULL);
|
||||
switch (gst_iterator_next (it, &v)) {
|
||||
case GST_ITERATOR_OK:
|
||||
pad = g_value_get_object (&v);
|
||||
|
||||
can_do = gst_caps_can_intersect (caps, link_caps);
|
||||
caps = gst_pad_get_current_caps (pad);
|
||||
if (caps == NULL)
|
||||
caps = gst_pad_query_caps (pad, NULL);
|
||||
|
||||
GST_TRACE ("can_do: %d for %" GST_PTR_FORMAT " and %" GST_PTR_FORMAT,
|
||||
can_do, caps, link_caps);
|
||||
can_do = gst_caps_can_intersect (caps, link_caps);
|
||||
|
||||
gst_caps_unref (caps);
|
||||
GST_TRACE ("can_do: %d for %" GST_PTR_FORMAT " and %" GST_PTR_FORMAT,
|
||||
can_do, caps, link_caps);
|
||||
|
||||
pads = pads->next;
|
||||
gst_caps_unref (caps);
|
||||
|
||||
g_value_unset (&v);
|
||||
break;
|
||||
case GST_ITERATOR_DONE:
|
||||
case GST_ITERATOR_ERROR:
|
||||
done = TRUE;
|
||||
break;
|
||||
case GST_ITERATOR_RESYNC:
|
||||
gst_iterator_resync (it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GST_OBJECT_UNLOCK (e);
|
||||
gst_iterator_free (it);
|
||||
|
||||
return can_do;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue