return ret;
}
+#if 0
/* check if caps @in on @pad can be transformed to @out on the other pad.
* We don't have a vmethod to test this yet so we have to do a somewhat less
* efficient check for this.
return FALSE;
}
}
+#endif
/* given a fixed @caps on @pad, create the best possible caps for the
* other pad.
return types;
}
+#if 0
static void
compute_upstream_suggestion (GstBaseTransform * trans, gsize expsize,
GstCaps * caps)
gst_caps_unref (othercaps);
}
}
+#endif
/* Allocate a buffer using gst_pad_alloc_buffer
*
GstBaseTransformClass *bclass;
GstBaseTransformPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK;
- gsize insize, outsize, newsize, expsize;
- gboolean discard, setcaps, copymeta;
- GstCaps *incaps, *oldcaps, *newcaps, *outcaps;
+ gboolean discard, copymeta;
+ gsize insize, outsize;
+ GstCaps *incaps, *outcaps;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
*out_buf = NULL;
+ incaps = gst_pad_get_current_caps (trans->sinkpad);
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
+
insize = gst_buffer_get_size (in_buf);
/* figure out how to allocate a buffer based on the current configuration */
GST_DEBUG_OBJECT (trans, "getting output size for copy transform");
/* copy transform, figure out the output size */
if (!gst_base_transform_transform_size (trans,
- GST_PAD_SINK, GST_PAD_CAPS (trans->sinkpad),
- insize, GST_PAD_CAPS (trans->srcpad), &outsize)) {
+ GST_PAD_SINK, incaps, insize, outcaps, &outsize)) {
goto unknown_size;
}
/* never discard this buffer, we need it for storing the output */
}
}
- oldcaps = GST_PAD_CAPS (trans->srcpad);
-
if (bclass->prepare_output_buffer) {
GST_DEBUG_OBJECT (trans,
- "calling prepare buffer with caps %p %" GST_PTR_FORMAT, oldcaps,
- oldcaps);
+ "calling prepare buffer with caps %p %" GST_PTR_FORMAT, outcaps,
+ outcaps);
ret =
- bclass->prepare_output_buffer (trans, in_buf, outsize, oldcaps,
+ bclass->prepare_output_buffer (trans, in_buf, outsize, outcaps,
out_buf);
/* get a new ref to the srcpad caps, the prepare_output_buffer function can
* update the pad caps if it wants */
- oldcaps = GST_PAD_CAPS (trans->srcpad);
+ if (outcaps)
+ gst_caps_unref (outcaps);
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
/* FIXME 0.11:
* decrease refcount again if vmethod returned refcounted in_buf. This
*out_buf = gst_buffer_ref (in_buf);
} else {
GST_DEBUG_OBJECT (trans, "doing alloc with caps %" GST_PTR_FORMAT,
- oldcaps);
+ outcaps);
*out_buf = gst_buffer_new_and_alloc (outsize);
- gst_buffer_set_caps (*out_buf, oldcaps);
-#if 0
- ret = gst_pad_alloc_buffer (trans->srcpad,
- GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
- if (ret != GST_FLOW_OK)
- goto alloc_failed;
-#endif
}
}
if (*out_buf == NULL)
goto no_buffer;
- /* check if we got different caps on this new output buffer */
- newcaps = GST_BUFFER_CAPS (*out_buf);
- newsize = gst_buffer_get_size (*out_buf);
-
- if (newcaps && !gst_caps_is_equal (newcaps, oldcaps)) {
- GstCaps *othercaps;
- gboolean can_convert;
-
- GST_DEBUG_OBJECT (trans, "received new caps %" GST_PTR_FORMAT, newcaps);
-
- incaps = GST_PAD_CAPS (trans->sinkpad);
-
- /* check if we can convert the current incaps to the new target caps */
- can_convert =
- gst_base_transform_can_transform (trans, trans->sinkpad, incaps,
- newcaps);
-
- if (!can_convert) {
- GST_DEBUG_OBJECT (trans, "cannot perform transform on current buffer");
-
- gst_base_transform_transform_size (trans,
- GST_PAD_SINK, incaps, insize, newcaps, &expsize);
-
- compute_upstream_suggestion (trans, expsize, newcaps);
-
- /* we got a suggested caps but we can't transform to it. See if there is
- * another downstream format that we can transform to */
- othercaps =
- gst_base_transform_find_transform (trans, trans->sinkpad, incaps,
- TRUE);
-
- if (othercaps && !gst_caps_is_empty (othercaps)) {
- GST_DEBUG_OBJECT (trans, "we found target caps %" GST_PTR_FORMAT,
- othercaps);
- *out_buf = gst_buffer_make_writable (*out_buf);
- gst_buffer_set_caps (*out_buf, othercaps);
- gst_caps_unref (othercaps);
- newcaps = GST_BUFFER_CAPS (*out_buf);
- can_convert = TRUE;
- } else if (othercaps)
- gst_caps_unref (othercaps);
- }
-
- /* it's possible that the buffer we got is of the wrong size, get the
- * expected size here, we will check the size if we are going to use the
- * buffer later on. */
- gst_base_transform_transform_size (trans,
- GST_PAD_SINK, incaps, insize, newcaps, &expsize);
-
- if (can_convert) {
- GST_DEBUG_OBJECT (trans, "reconfigure transform for current buffer");
-
- /* subclass might want to add fields to the caps */
- if (bclass->fixate_caps != NULL) {
- newcaps = gst_caps_copy (newcaps);
-
- GST_DEBUG_OBJECT (trans, "doing fixate %" GST_PTR_FORMAT
- " using caps %" GST_PTR_FORMAT
- " on pad %s:%s using fixate_caps vmethod", newcaps, incaps,
- GST_DEBUG_PAD_NAME (trans->srcpad));
- bclass->fixate_caps (trans, GST_PAD_SINK, incaps, newcaps);
-
- *out_buf = gst_buffer_make_writable (*out_buf);
- gst_buffer_set_caps (*out_buf, newcaps);
- gst_caps_unref (newcaps);
- newcaps = GST_BUFFER_CAPS (*out_buf);
- }
-
- /* caps not empty, try to renegotiate to the new format */
- if (!gst_base_transform_configure_caps (trans, incaps, newcaps)) {
- /* not sure we need to fail hard here, we can simply continue our
- * conversion with what we negotiated before */
- goto failed_configure;
- }
- /* new format configure, and use the new output buffer */
- gst_pad_set_caps (trans->srcpad, newcaps);
- discard = FALSE;
- /* clear previous cached sink-pad caps, so buffer_alloc knows that
- * it needs to revisit the decision about whether to proxy or not: */
- gst_caps_replace (&priv->sink_alloc, NULL);
- /* if we got a buffer of the wrong size, discard it now and make sure we
- * allocate a propertly sized buffer later. */
- if (newsize != expsize) {
- if (in_buf != *out_buf)
- gst_buffer_unref (*out_buf);
- *out_buf = NULL;
- }
- outsize = expsize;
- } else {
- compute_upstream_suggestion (trans, expsize, newcaps);
-
- if (in_buf != *out_buf)
- gst_buffer_unref (*out_buf);
- *out_buf = NULL;
- }
- } else if (outsize != newsize) {
- GST_WARNING_OBJECT (trans, "Caps did not change but allocated size does "
- "not match expected size (%d != %d)", newsize, outsize);
- if (in_buf != *out_buf)
- gst_buffer_unref (*out_buf);
- *out_buf = NULL;
- }
-
- /* these are the final output caps */
- outcaps = GST_PAD_CAPS (trans->srcpad);
-
copymeta = FALSE;
if (*out_buf == NULL) {
if (!discard) {
}
}
- /* check if we need to make things writable. We need this when we need to
- * update the caps or the metadata on the output buffer. */
- newcaps = GST_BUFFER_CAPS (*out_buf);
- /* we check the pointers as a quick check and then go to the more involved
- * check. This is needed when we receive different pointers on the sinkpad
- * that mean the same caps. What we then want to do is prefer those caps over
- * the ones on the srcpad and set the srcpad caps to the buffer caps */
- setcaps = !newcaps || ((newcaps != outcaps)
- && (!gst_caps_is_equal (newcaps, outcaps)));
/* we need to modify the metadata when the element is not gap aware,
* passthrough is not used and the gap flag is set */
copymeta |= !trans->priv->gap_aware && !trans->passthrough
&& (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP);
- if (setcaps || copymeta) {
- GST_DEBUG_OBJECT (trans, "setcaps %d, copymeta %d", setcaps, copymeta);
+ if (copymeta) {
+ GST_DEBUG_OBJECT (trans, "copymeta %d", copymeta);
if (!gst_buffer_is_writable (*out_buf)) {
GST_DEBUG_OBJECT (trans, "buffer %p not writable", *out_buf);
if (in_buf == *out_buf)
*out_buf = gst_buffer_make_writable (*out_buf);
}
/* when we get here, the metadata should be writable */
- if (setcaps)
- gst_buffer_set_caps (*out_buf, outcaps);
if (copymeta)
gst_buffer_copy_into (*out_buf, in_buf,
GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
GST_BUFFER_FLAG_UNSET (*out_buf, GST_BUFFER_FLAG_GAP);
}
+done:
+ if (incaps)
+ gst_caps_unref (incaps);
+ if (outcaps)
+ gst_caps_unref (outcaps);
+
return ret;
/* ERRORS */
alloc_failed:
{
GST_WARNING_OBJECT (trans, "pad-alloc failed: %s", gst_flow_get_name (ret));
- return ret;
+ goto done;
}
no_buffer:
{
GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED,
("Sub-class failed to provide an output buffer"), (NULL));
- return GST_FLOW_ERROR;
+ ret = GST_FLOW_ERROR;
+ goto done;
}
unknown_size:
{
GST_ERROR_OBJECT (trans, "unknown output size");
- return GST_FLOW_ERROR;
- }
-failed_configure:
- {
- GST_WARNING_OBJECT (trans, "failed to configure caps");
- return GST_FLOW_NOT_NEGOTIATED;
+ ret = GST_FLOW_ERROR;
+ goto done;
}
}
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
if (active) {
+ GstCaps *incaps, *outcaps;
+
if (trans->priv->pad_mode == GST_ACTIVATE_NONE && bclass->start)
result &= bclass->start (trans);
- GST_OBJECT_LOCK (trans);
+ incaps = gst_pad_get_current_caps (trans->sinkpad);
+ outcaps = gst_pad_get_current_caps (trans->srcpad);
- if (GST_PAD_CAPS (trans->sinkpad) && GST_PAD_CAPS (trans->srcpad))
+ GST_OBJECT_LOCK (trans);
+ if (incaps && outcaps)
trans->have_same_caps =
- gst_caps_is_equal (GST_PAD_CAPS (trans->sinkpad),
- GST_PAD_CAPS (trans->srcpad)) || trans->passthrough;
+ gst_caps_is_equal (incaps, outcaps) || trans->passthrough;
else
trans->have_same_caps = trans->passthrough;
GST_DEBUG_OBJECT (trans, "have_same_caps %d", trans->have_same_caps);
trans->priv->processed = 0;
trans->priv->dropped = 0;
trans->priv->force_alloc = TRUE;
-
GST_OBJECT_UNLOCK (trans);
+
+ if (incaps)
+ gst_caps_unref (incaps);
+ if (outcaps)
+ gst_caps_unref (outcaps);
} else {
/* We must make sure streaming has finished before resetting things
* and calling the ::stop vfunc */