/* 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;
GstCaps * caps, GstBuffer ** buf)
{
GstBaseTransform *trans;
+ GstBaseTransformClass *klass;
GstBaseTransformPrivate *priv;
GstFlowReturn res;
gboolean proxy, suggest, same_caps;
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",
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))
- goto not_supported;
+ 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;
+ }
+ }
}
}
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) {
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);
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);
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);
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);
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);
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);