mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
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
This commit is contained in:
parent
5d8e7598ac
commit
605175b8c4
1 changed files with 70 additions and 46 deletions
|
@ -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)
|
||||||
* 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;
|
|
||||||
GstCaps *templ_caps = gst_pad_get_pad_template_caps (ourpad);
|
|
||||||
|
|
||||||
ourcaps = gst_caps_copy (templ_caps);
|
do {
|
||||||
gst_caps_unref (templ_caps);
|
res = gst_iterator_next (it, &v);
|
||||||
|
switch (res) {
|
||||||
|
case GST_ITERATOR_OK:{
|
||||||
|
GstPad *ourpad = GST_PAD (g_value_get_object (&v));
|
||||||
|
GstCaps *peercaps = NULL, *ourcaps;
|
||||||
|
GstCaps *templ_caps = gst_pad_get_pad_template_caps (ourpad);
|
||||||
|
|
||||||
if (pad == ourpad) {
|
ourcaps = gst_caps_copy (templ_caps);
|
||||||
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
|
gst_caps_unref (templ_caps);
|
||||||
__set_channels (ourcaps, GST_AUDIO_INFO_CHANNELS (&self->audio_info));
|
|
||||||
else
|
if (pad == ourpad) {
|
||||||
__set_channels (ourcaps, 1);
|
if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK)
|
||||||
} else {
|
__set_channels (ourcaps,
|
||||||
__remove_channels (ourcaps);
|
GST_AUDIO_INFO_CHANNELS (&self->audio_info));
|
||||||
/* Only ask for peer caps for other pads than pad
|
else
|
||||||
* as otherwise gst_pad_peer_get_caps() might call
|
__set_channels (ourcaps, 1);
|
||||||
* back into this function and deadlock
|
} else {
|
||||||
*/
|
__remove_channels (ourcaps);
|
||||||
peercaps = gst_pad_peer_query_caps (ourpad, NULL);
|
/* Only ask for peer caps for other pads than pad
|
||||||
peercaps = gst_caps_make_writable (peercaps);
|
* as otherwise gst_pad_peer_get_caps() might call
|
||||||
|
* back into this function and deadlock
|
||||||
|
*/
|
||||||
|
peercaps = gst_pad_peer_query_caps (ourpad, NULL);
|
||||||
|
peercaps = gst_caps_make_writable (peercaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the peer exists and has caps add them to the intersection,
|
||||||
|
* otherwise assume that the peer accepts everything */
|
||||||
|
if (peercaps) {
|
||||||
|
GstCaps *intersection;
|
||||||
|
GstCaps *oldret = ret;
|
||||||
|
|
||||||
|
__remove_channels (peercaps);
|
||||||
|
|
||||||
|
intersection = gst_caps_intersect (peercaps, ourcaps);
|
||||||
|
|
||||||
|
ret = gst_caps_intersect (ret, intersection);
|
||||||
|
gst_caps_unref (intersection);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
} while (res != GST_ITERATOR_DONE && res != GST_ITERATOR_ERROR);
|
||||||
/* If the peer exists and has caps add them to the intersection,
|
g_value_unset (&v);
|
||||||
* otherwise assume that the peer accepts everything */
|
gst_iterator_free (it);
|
||||||
if (peercaps) {
|
|
||||||
GstCaps *intersection;
|
|
||||||
GstCaps *oldret = ret;
|
|
||||||
|
|
||||||
__remove_channels (peercaps);
|
|
||||||
|
|
||||||
intersection = gst_caps_intersect (peercaps, ourcaps);
|
|
||||||
|
|
||||||
ret = gst_caps_intersect (ret, intersection);
|
|
||||||
gst_caps_unref (intersection);
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
GST_OBJECT_UNLOCK (self);
|
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
GstCaps *aux;
|
GstCaps *aux;
|
||||||
|
@ -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]) {
|
||||||
|
|
Loading…
Reference in a new issue