basetransform: move prepare_output_buffer code

Move the code for prepare_output_buffer to a default implementation. this allows
us to simplify some things and have subclasses call into the default
implementation when needed.
This commit is contained in:
Wim Taymans 2011-07-21 15:49:00 +02:00
parent 560c3d7fbc
commit 5253a52cb2

View file

@ -1355,48 +1355,19 @@ gst_base_transform_query_type (GstPad * pad)
return types;
}
/* Allocate a buffer using gst_pad_alloc_buffer
*
* This function can do renegotiation on the source pad
*
* The output buffer is always writable. outbuf can be equal to
* inbuf, the caller should be prepared for this and perform
* appropriate refcounting.
*/
static GstFlowReturn
gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
default_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * in_buf, GstBuffer ** out_buf)
{
GstBaseTransformClass *bclass;
GstBaseTransformPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK;
gboolean copymeta;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
GstBaseTransformClass *bclass;
priv = trans->priv;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
*out_buf = NULL;
if (bclass->prepare_output_buffer) {
GST_DEBUG_OBJECT (trans, "calling prepare buffer");
ret = bclass->prepare_output_buffer (trans, in_buf, out_buf);
/* FIXME 0.11:
* decrease refcount again if vmethod returned refcounted in_buf. This
* is because we need to make sure that the buffer is writable for the
* in_place transform. The docs of the vmethod say that you should return
* a reffed inbuf, which is exactly what we don't want :), oh well.. */
if (in_buf == *out_buf)
gst_buffer_unref (in_buf);
}
if (ret != GST_FLOW_OK)
goto alloc_failed;
if (*out_buf == NULL) {
if (trans->passthrough) {
GST_DEBUG_OBJECT (trans, "Reusing input buffer");
GST_DEBUG_OBJECT (trans, "passthrough: reusing input buffer");
*out_buf = in_buf;
} else if (priv->pool) {
GST_DEBUG_OBJECT (trans, "using pool alloc");
@ -1443,14 +1414,56 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
*out_buf =
gst_buffer_new_allocate (priv->allocator, outsize, priv->alignment);
}
return ret;
/* ERRORS */
unknown_size:
{
GST_ERROR_OBJECT (trans, "unknown output size");
return GST_FLOW_ERROR;
}
}
if (ret != GST_FLOW_OK)
/* Allocate a buffer using gst_pad_alloc_buffer
*
* This function can do renegotiation on the source pad
*
* The output buffer is always writable. outbuf can be equal to
* inbuf, the caller should be prepared for this and perform
* appropriate refcounting.
*/
static GstFlowReturn
gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * in_buf, GstBuffer ** out_buf)
{
GstBaseTransformClass *bclass;
GstBaseTransformPrivate *priv;
GstFlowReturn ret = GST_FLOW_OK;
gboolean copymeta;
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
priv = trans->priv;
*out_buf = NULL;
if (bclass->prepare_output_buffer == NULL)
goto no_prepare;
GST_DEBUG_OBJECT (trans, "calling prepare buffer");
ret = bclass->prepare_output_buffer (trans, in_buf, out_buf);
if (ret != GST_FLOW_OK || *out_buf == NULL)
goto alloc_failed;
/* must always have a buffer by now */
if (*out_buf == NULL)
goto no_buffer;
/* FIXME 0.11:
* decrease refcount again if vmethod returned refcounted in_buf. This
* is because we need to make sure that the buffer is writable for the
* in_place transform. The docs of the vmethod say that you should return
* a reffed inbuf, which is exactly what we don't want :), oh well.. */
if (in_buf == *out_buf)
gst_buffer_unref (in_buf);
if (trans->passthrough && in_buf != *out_buf) {
/* we are asked to perform a passthrough transform but the input and
@ -1508,28 +1521,21 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
GST_BUFFER_FLAG_UNSET (*out_buf, GST_BUFFER_FLAG_GAP);
}
done:
return ret;
/* ERRORS */
alloc_failed:
{
GST_WARNING_OBJECT (trans, "pad-alloc failed: %s", gst_flow_get_name (ret));
goto done;
}
no_buffer:
no_prepare:
{
GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED,
("Sub-class failed to provide an output buffer"), (NULL));
ret = GST_FLOW_ERROR;
goto done;
("Sub-class has no prepare_output_buffer implementation"), (NULL));
return GST_FLOW_ERROR;
}
unknown_size:
alloc_failed:
{
GST_ERROR_OBJECT (trans, "unknown output size");
ret = GST_FLOW_ERROR;
goto done;
GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED,
("Sub-class failed to provide an output buffer (%s)",
gst_flow_get_name (ret)), (NULL));
return ret;
}
}