summaryrefslogtreecommitdiffstats
path: root/gst/interleave/deinterleave.c
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-05-17 14:05:03 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-05-17 14:05:03 +0000
commit838e10c219faf33022c241d09acc74bd674e35e1 (patch)
tree626bef9bb5979bbc0eff296ab7d33f0b4ef481fd /gst/interleave/deinterleave.c
parent67515f39fc7b1bba1e15d065e21ae3ca2ebeba1e (diff)
downloadgst-plugins-bad-838e10c219faf33022c241d09acc74bd674e35e1.tar.gz
gst-plugins-bad-838e10c219faf33022c241d09acc74bd674e35e1.tar.bz2
gst-plugins-bad-838e10c219faf33022c241d09acc74bd674e35e1.zip
gst/interleave/deinterleave.c: Always set the channel positions when gst_audio_get_channel_positions() returns someth...
Original commit message from CVS: * gst/interleave/deinterleave.c: (gst_deinterleave_sink_setcaps), (gst_deinterleave_getcaps): Always set the channel positions when gst_audio_get_channel_positions() returns something, even if they're not set in the caps. This makes sure that the output channels can be interleaved again correctly in the mono/stereo cases too. Don't ask for the peercaps of the current pad in getcaps() as this might call getcaps() again and deadlock.
Diffstat (limited to 'gst/interleave/deinterleave.c')
-rw-r--r--gst/interleave/deinterleave.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/gst/interleave/deinterleave.c b/gst/interleave/deinterleave.c
index c1039693..ef4e013f 100644
--- a/gst/interleave/deinterleave.c
+++ b/gst/interleave/deinterleave.c
@@ -300,8 +300,9 @@ gst_deinterleave_sink_setcaps (GstPad * pad, GstCaps * caps)
GST_DEBUG_OBJECT (self, "got caps: %" GST_PTR_FORMAT, caps);
if (self->sinkcaps && !gst_caps_is_equal (caps, self->sinkcaps)) {
- gint new_channels;
+ gint new_channels, i;
GstAudioChannelPosition *pos;
+ gboolean same_layout = TRUE;
s = gst_caps_get_structure (caps, 0);
@@ -314,25 +315,27 @@ gst_deinterleave_sink_setcaps (GstPad * pad, GstCaps * caps)
!gst_deinterleave_set_process_function (self, caps))
goto cannot_change_caps;
- if (gst_structure_has_field (s, "channel-positions")) {
- gint i;
- gboolean same = TRUE;
-
- if (!self->pos)
- goto cannot_change_caps;
+ /* Now check the channel positions. If we had no channel positions
+ * and get them or the other way around things have changed.
+ * If we had channel positions and get different ones things have
+ * changed too of course
+ */
+ pos = gst_audio_get_channel_positions (s);
+ if ((pos && !self->pos) || (!pos && self->pos))
+ goto cannot_change_caps;
- pos = gst_audio_get_channel_positions (s);
+ if (pos) {
for (i = 0; i < self->channels; i++) {
if (self->pos[i] != pos[i]) {
- same = FALSE;
+ same_layout = FALSE;
break;
}
}
-
g_free (pos);
- if (!same)
+ if (!same_layout)
goto cannot_change_caps;
}
+
} else {
s = gst_caps_get_structure (caps, 0);
@@ -342,8 +345,7 @@ gst_deinterleave_sink_setcaps (GstPad * pad, GstCaps * caps)
if (!gst_deinterleave_set_process_function (self, caps))
goto unsupported_caps;
- if (gst_structure_has_field (s, "channel-positions"))
- self->pos = gst_audio_get_channel_positions (s);
+ self->pos = gst_audio_get_channel_positions (s);
}
gst_caps_replace (&self->sinkcaps, caps);
@@ -425,7 +427,6 @@ gst_deinterleave_getcaps (GstPad * pad)
GList *l;
GST_OBJECT_LOCK (self);
-
/* Intersect all of our pad template caps with the peer caps of the pad
* to get all formats that are possible up- and downstream.
*
@@ -436,7 +437,7 @@ gst_deinterleave_getcaps (GstPad * pad)
ret = gst_caps_new_any ();
for (l = GST_ELEMENT (self)->pads; l != NULL; l = l->next) {
GstPad *ourpad = GST_PAD (l->data);
- GstCaps *peercaps, *ourcaps;
+ GstCaps *peercaps = NULL, *ourcaps;
ourcaps = gst_caps_copy (gst_pad_get_pad_template_caps (ourpad));
@@ -447,18 +448,21 @@ gst_deinterleave_getcaps (GstPad * pad)
__set_channels (ourcaps, 1);
} else {
__remove_channels (ourcaps);
+ /* Only ask for peer caps for other pads than pad
+ * as otherwise gst_pad_peer_get_caps() might call
+ * back into this function and deadlock
+ */
+ peercaps = gst_pad_peer_get_caps (ourpad);
}
- peercaps = gst_pad_peer_get_caps (ourpad);
- if (pad != ourpad && peercaps)
- __remove_channels (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);
@@ -473,7 +477,6 @@ gst_deinterleave_getcaps (GstPad * pad)
}
gst_caps_unref (ourcaps);
}
-
GST_OBJECT_UNLOCK (self);
gst_object_unref (self);