Commit 605175b8 authored by Sebastian Dröge's avatar Sebastian Dröge

deinterleave: Use GstIterator for iterating all pads instead of manually...

deinterleave: Use GstIterator for iterating all pads instead of manually iterating them while holding the object lock all the time

Doing queries while holding the object lock is a bit dangerous, and in this
case causes deadlocks.

https://bugzilla.gnome.org/show_bug.cgi?id=763326
parent 5d8e7598
...@@ -554,9 +554,10 @@ gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter) ...@@ -554,9 +554,10 @@ gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter)
{ {
GstDeinterleave *self = GST_DEINTERLEAVE (parent); GstDeinterleave *self = GST_DEINTERLEAVE (parent);
GstCaps *ret; GstCaps *ret;
GList *l; GstIterator *it;
GstIteratorResult res;
GValue v = G_VALUE_INIT;
GST_OBJECT_LOCK (self);
/* Intersect all of our pad template caps with the peer caps of the pad /* Intersect all of our pad template caps with the peer caps of the pad
* to get all formats that are possible up- and downstream. * to get all formats that are possible up- and downstream.
* *
...@@ -565,52 +566,74 @@ gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter) ...@@ -565,52 +566,74 @@ gst_deinterleave_getcaps (GstPad * pad, GstObject * parent, GstCaps * filter)
* will be detected here already * will be detected here already
*/ */
ret = gst_caps_new_any (); ret = gst_caps_new_any ();
for (l = GST_ELEMENT (self)->pads; l != NULL; l = l->next) { it = gst_element_iterate_pads (GST_ELEMENT_CAST (self));
GstPad *ourpad = GST_PAD (l->data);
GstCaps *peercaps = NULL, *ourcaps; do {
GstCaps *templ_caps = gst_pad_get_pad_template_caps (ourpad); res = gst_iterator_next (it, &v);
switch (res) {
ourcaps = gst_caps_copy (templ_caps); case GST_ITERATOR_OK:{
gst_caps_unref (templ_caps); GstPad *ourpad = GST_PAD (g_value_get_object (&v));
GstCaps *peercaps = NULL, *ourcaps;
if (pad == ourpad) { GstCaps *templ_caps = gst_pad_get_pad_template_caps (ourpad);
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
__set_channels (ourcaps, GST_AUDIO_INFO_CHANNELS (&self->audio_info)); ourcaps = gst_caps_copy (templ_caps);
else gst_caps_unref (templ_caps);
__set_channels (ourcaps, 1);
} else { if (pad == ourpad) {
__remove_channels (ourcaps); if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
/* Only ask for peer caps for other pads than pad __set_channels (ourcaps,
* as otherwise gst_pad_peer_get_caps() might call GST_AUDIO_INFO_CHANNELS (&self->audio_info));
* back into this function and deadlock else
*/ __set_channels (ourcaps, 1);
peercaps = gst_pad_peer_query_caps (ourpad, NULL); } else {
peercaps = gst_caps_make_writable (peercaps); __remove_channels (ourcaps);
} /* Only ask for peer caps for other pads than pad
* as otherwise gst_pad_peer_get_caps() might call
/* If the peer exists and has caps add them to the intersection, * back into this function and deadlock
* otherwise assume that the peer accepts everything */ */
if (peercaps) { peercaps = gst_pad_peer_query_caps (ourpad, NULL);
GstCaps *intersection; peercaps = gst_caps_make_writable (peercaps);
GstCaps *oldret = ret; }
__remove_channels (peercaps); /* If the peer exists and has caps add them to the intersection,
* otherwise assume that the peer accepts everything */
intersection = gst_caps_intersect (peercaps, ourcaps); if (peercaps) {
GstCaps *intersection;
ret = gst_caps_intersect (ret, intersection); GstCaps *oldret = ret;
gst_caps_unref (intersection);
gst_caps_unref (peercaps); __remove_channels (peercaps);
gst_caps_unref (oldret);
} else { intersection = gst_caps_intersect (peercaps, ourcaps);
GstCaps *oldret = ret;
ret = gst_caps_intersect (ret, intersection);
ret = gst_caps_intersect (ret, ourcaps); gst_caps_unref (intersection);
gst_caps_unref (oldret); gst_caps_unref (peercaps);
gst_caps_unref (oldret);
} else {
GstCaps *oldret = ret;
ret = gst_caps_intersect (ret, ourcaps);
gst_caps_unref (oldret);
}
gst_caps_unref (ourcaps);
g_value_reset (&v);
break;
}
case GST_ITERATOR_DONE:
break;
case GST_ITERATOR_ERROR:
gst_caps_unref (ret);
ret = gst_caps_new_empty ();
break;
case GST_ITERATOR_RESYNC:
gst_caps_unref (ret);
ret = gst_caps_new_empty ();
gst_iterator_resync (it);
break;
} }
gst_caps_unref (ourcaps); } while (res != GST_ITERATOR_DONE && res != GST_ITERATOR_ERROR);
} g_value_unset (&v);
GST_OBJECT_UNLOCK (self); gst_iterator_free (it);
if (filter) { if (filter) {
GstCaps *aux; GstCaps *aux;
...@@ -827,7 +850,8 @@ gst_deinterleave_process (GstDeinterleave * self, GstBuffer * buf) ...@@ -827,7 +850,8 @@ gst_deinterleave_process (GstDeinterleave * self, GstBuffer * buf)
* here is an unliked pad */ * here is an unliked pad */
if (!buffers_out[i]) if (!buffers_out[i])
goto alloc_buffer_failed; goto alloc_buffer_failed;
else if (buffers_out[i] && gst_buffer_get_size (buffers_out[i]) != bufsize) else if (buffers_out[i]
&& gst_buffer_get_size (buffers_out[i]) != bufsize)
goto alloc_buffer_bad_size; goto alloc_buffer_bad_size;
if (buffers_out[i]) { if (buffers_out[i]) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment