mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 23:36:38 +00:00
basetransform: Try suggesting caps on bad caps pad_alloc
When basetransform received an unsupported caps on pad_alloc it just returned not-negotiated. This patch makes it query the allowed caps between his sinkpad and upstream's srcpad to find a caps to suggest. This happens when dinamically switching pipeline elements and upstream pad_allocs with the previous caps that was being used. Fixes #614296
This commit is contained in:
parent
4cecd73c93
commit
574e6ab423
2 changed files with 68 additions and 10 deletions
|
@ -1341,6 +1341,7 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
|||
/* check if we got different caps on this new output buffer */
|
||||
newcaps = GST_BUFFER_CAPS (*out_buf);
|
||||
newsize = GST_BUFFER_SIZE (*out_buf);
|
||||
|
||||
if (newcaps && !gst_caps_is_equal (newcaps, oldcaps)) {
|
||||
GstCaps *othercaps;
|
||||
gboolean can_convert;
|
||||
|
@ -1619,6 +1620,7 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
|||
GstCaps * caps, GstBuffer ** buf)
|
||||
{
|
||||
GstBaseTransform *trans;
|
||||
GstBaseTransformClass *klass;
|
||||
GstBaseTransformPrivate *priv;
|
||||
GstFlowReturn res;
|
||||
gboolean proxy, suggest, same_caps;
|
||||
|
@ -1626,6 +1628,7 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
|||
guint size_suggest;
|
||||
|
||||
trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
|
||||
klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
|
||||
priv = trans->priv;
|
||||
|
||||
GST_DEBUG_OBJECT (pad, "alloc with caps %p %" GST_PTR_FORMAT ", size %u",
|
||||
|
@ -1707,17 +1710,53 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
|||
sink_suggest = NULL;
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (trans, "Caps fixated to now: %" GST_PTR_FORMAT,
|
||||
GST_DEBUG_OBJECT (trans, "Caps fixed to: %" GST_PTR_FORMAT,
|
||||
sink_suggest);
|
||||
}
|
||||
|
||||
if (sink_suggest) {
|
||||
templ = gst_pad_get_pad_template_caps (pad);
|
||||
|
||||
if (!gst_caps_can_intersect (sink_suggest, templ))
|
||||
if (!gst_caps_can_intersect (sink_suggest, templ)) {
|
||||
GstCaps *allowed;
|
||||
GstCaps *peercaps;
|
||||
|
||||
/* the requested pad alloc caps are not supported, so let's try
|
||||
* picking something allowed between the pads (they are linked,
|
||||
* there must be something) */
|
||||
|
||||
allowed = gst_pad_get_allowed_caps (pad);
|
||||
if (allowed && !gst_caps_is_empty (allowed)) {
|
||||
GST_DEBUG_OBJECT (trans, "Requested pad alloc caps is not "
|
||||
"supported, but pads could agree on one of the following caps: "
|
||||
"%" GST_PTR_FORMAT, allowed);
|
||||
allowed = gst_caps_make_writable (allowed);
|
||||
|
||||
if (klass->fixate_caps) {
|
||||
peercaps =
|
||||
gst_pad_get_allowed_caps (GST_BASE_TRANSFORM_SRC_PAD (trans));
|
||||
klass->fixate_caps (trans, GST_PAD_SRC, peercaps, allowed);
|
||||
gst_caps_unref (peercaps);
|
||||
}
|
||||
|
||||
/* Fixate them to be safe if the subclass didn't do it */
|
||||
gst_caps_truncate (allowed);
|
||||
gst_pad_fixate_caps (pad, allowed);
|
||||
gst_caps_replace (&sink_suggest, allowed);
|
||||
gst_caps_unref (allowed);
|
||||
|
||||
suggest = TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (trans, "Fixated suggestion caps to %"
|
||||
GST_PTR_FORMAT, sink_suggest);
|
||||
} else {
|
||||
if (allowed)
|
||||
gst_caps_unref (allowed);
|
||||
goto not_supported;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* find the best format for the other side here we decide if we will proxy
|
||||
* the caps or not. */
|
||||
|
@ -1757,7 +1796,8 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
|
|||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
proxy = priv->proxy_alloc;
|
||||
GST_DEBUG_OBJECT (trans, "doing default alloc, proxy %d", proxy);
|
||||
GST_DEBUG_OBJECT (trans, "doing default alloc, proxy %d, suggest %d", proxy,
|
||||
suggest);
|
||||
|
||||
/* we only want to proxy if we have no suggestion pending, FIXME */
|
||||
if (proxy && !suggest) {
|
||||
|
|
|
@ -642,7 +642,10 @@ GST_START_TEST (basetransform_chain_ct1)
|
|||
|
||||
buffer_alloc_ct1_called = FALSE;
|
||||
res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, outcaps, &buffer);
|
||||
fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
|
||||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
gst_buffer_unref (buffer);
|
||||
/* FIXME, why would this call the alloc function? we try to alloc something
|
||||
* with caps that are not supported on the sinkpad */
|
||||
fail_unless (buffer_alloc_ct1_called == FALSE);
|
||||
|
@ -743,7 +746,10 @@ GST_START_TEST (basetransform_chain_ct1)
|
|||
|
||||
buffer_alloc_ct1_called = FALSE;
|
||||
res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, outcaps, &buffer);
|
||||
fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
|
||||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
gst_buffer_unref (buffer);
|
||||
/* should not call the pad-alloc function */
|
||||
fail_unless (buffer_alloc_ct1_called == FALSE);
|
||||
|
||||
|
@ -933,7 +939,10 @@ GST_START_TEST (basetransform_chain_ct2)
|
|||
buffer_alloc_ct2_case = 2;
|
||||
buffer_alloc_ct2_called = FALSE;
|
||||
res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, outcaps, &buffer);
|
||||
fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
|
||||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
gst_buffer_unref (buffer);
|
||||
/* should not call pad-alloc because the caps and sizes are different */
|
||||
fail_unless (buffer_alloc_ct2_called == FALSE);
|
||||
|
||||
|
@ -1024,7 +1033,10 @@ GST_START_TEST (basetransform_chain_ct2)
|
|||
buffer_alloc_ct2_case = 2;
|
||||
buffer_alloc_ct2_called = FALSE;
|
||||
res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, outcaps, &buffer);
|
||||
fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
|
||||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
gst_buffer_unref (buffer);
|
||||
/* should not call the pad-alloc function */
|
||||
fail_unless (buffer_alloc_ct2_called == FALSE);
|
||||
|
||||
|
@ -1086,7 +1098,10 @@ GST_START_TEST (basetransform_chain_ct3)
|
|||
buffer_alloc_ct2_case = 2;
|
||||
buffer_alloc_ct2_called = FALSE;
|
||||
res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, outcaps, &buffer);
|
||||
fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
|
||||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
gst_buffer_unref (buffer);
|
||||
/* should not call pad-alloc because the caps and sizes are different */
|
||||
fail_unless (buffer_alloc_ct2_called == FALSE);
|
||||
|
||||
|
@ -1173,7 +1188,10 @@ GST_START_TEST (basetransform_chain_ct3)
|
|||
buffer_alloc_ct2_case = 2;
|
||||
buffer_alloc_ct2_called = FALSE;
|
||||
res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, outcaps, &buffer);
|
||||
fail_unless (res == GST_FLOW_NOT_NEGOTIATED);
|
||||
fail_unless (res == GST_FLOW_OK);
|
||||
fail_if (buffer == NULL);
|
||||
fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
|
||||
gst_buffer_unref (buffer);
|
||||
/* FIXME should not call the pad-alloc function but it currently does */
|
||||
fail_unless (buffer_alloc_ct2_called == FALSE);
|
||||
|
||||
|
|
Loading…
Reference in a new issue