streamsplitter: handle ACCEPT_CAPS query correctly

We can accept a caps when one of the downstream peers can accept the
caps. This is not the same as checking a subset of the getcaps
result because parsers might accept broader caps than what their getcaps
function returns (See https://bugzilla.gnome.org/show_bug.cgi?id=677401).

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=722330
This commit is contained in:
Wim Taymans 2014-01-16 16:32:34 +01:00
parent 36efe20679
commit 5df274f824

View file

@ -297,6 +297,53 @@ beach:
return res;
}
static gboolean
gst_stream_splitter_sink_acceptcaps (GstPad * pad, GstCaps * caps)
{
GstStreamSplitter *stream_splitter =
(GstStreamSplitter *) GST_PAD_PARENT (pad);
guint32 cookie;
GList *tmp;
gboolean res = FALSE;
/* check if one of the downstream elements accepts the caps */
STREAMS_LOCK (stream_splitter);
resync:
res = FALSE;
if (G_UNLIKELY (stream_splitter->srcpads == NULL))
goto beach;
cookie = stream_splitter->cookie;
tmp = stream_splitter->srcpads;
while (tmp) {
GstPad *srcpad = (GstPad *) tmp->data;
/* Ensure srcpad doesn't get destroyed while we query peer */
gst_object_ref (srcpad);
STREAMS_UNLOCK (stream_splitter);
res = gst_pad_peer_query_accept_caps (srcpad, caps);
STREAMS_LOCK (stream_splitter);
gst_object_unref (srcpad);
if (G_UNLIKELY (cookie != stream_splitter->cookie))
goto resync;
if (res)
break;
tmp = tmp->next;
}
beach:
STREAMS_UNLOCK (stream_splitter);
return res;
}
static gboolean
gst_stream_splitter_sink_query (GstPad * pad, GstObject * parent,
GstQuery * query)
@ -315,6 +362,17 @@ gst_stream_splitter_sink_query (GstPad * pad, GstObject * parent,
res = TRUE;
break;
}
case GST_QUERY_ACCEPT_CAPS:
{
GstCaps *caps;
gboolean result;
gst_query_parse_accept_caps (query, &caps);
result = gst_stream_splitter_sink_acceptcaps (pad, caps);
gst_query_set_accept_caps_result (query, result);
res = TRUE;
break;
}
default:
res = gst_pad_query_default (pad, parent, query);
break;