basetrans: Remove ref in passthrough

Remove the requirement to have to return a ref to the input buffer when in
passthrough mode. This saves a few ref/unref cycles and fixes another 0.11
FIXME.
This commit is contained in:
Wim Taymans 2011-07-21 17:42:08 +02:00
parent 70d13ae70e
commit 85d2355125
4 changed files with 15 additions and 18 deletions

View file

@ -1364,6 +1364,8 @@ gst_base_transform_query_type (GstPad * pad)
return types;
}
/* this function either returns the input buffer without incrementing the
* refcount or it allocates a new (writable) buffer */
static GstFlowReturn
default_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * inbuf, GstBuffer ** outbuf)
@ -1380,7 +1382,7 @@ default_prepare_output_buffer (GstBaseTransform * trans,
/* passthrough, we will not modify the incomming buffer so we can just
* reuse it */
GST_DEBUG_OBJECT (trans, "passthrough: reusing input buffer");
*outbuf = gst_buffer_ref (inbuf);
*outbuf = inbuf;
} else {
/* we can't reuse the input buffer */
if (priv->pool) {
@ -1830,14 +1832,8 @@ no_qos:
if (ret != GST_FLOW_OK || *outbuf == NULL)
goto no_buffer;
/* FIXME 0.11:
* decrease refcount again if vmethod returned refcounted inbuf. 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 (inbuf == *outbuf) {
GST_DEBUG_OBJECT (trans, "reusing input buffer");
gst_buffer_unref (inbuf);
} else if (trans->passthrough) {
/* we are asked to perform a passthrough transform but the input and
* output buffers are different. We have to discard the output buffer and
@ -1905,7 +1901,9 @@ no_qos:
}
skip:
/* only unref input buffer if we allocated a new outbuf buffer */
/* only unref input buffer if we allocated a new outbuf buffer. If we reused
* the input buffer, no refcount is changed to keep the input buffer writable
* when needed. */
if (*outbuf != inbuf)
gst_buffer_unref (inbuf);

View file

@ -180,10 +180,11 @@ struct _GstBaseTransform {
* Subclasses can override this to do their own
* allocation of output buffers. Elements that only do
* analysis can return a subbuffer or even just
* increment the reference to the input buffer (if in
* return a reference to the input buffer (if in
* passthrough mode). The default implementation will
* use the negotiated allocator or bufferpool and
* transform_size to allocate an output buffer.
* transform_size to allocate an output buffer or it
* will return the input buffer in passthrough mode.
* @copy_metadata: Optional.
* Copy the metadata from the input buffer to the output buffer.
* The default implementation will copy the flags, timestamps and

View file

@ -330,9 +330,8 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
{
GstFlowReturn ret = GST_FLOW_OK;
/* always ref input as output buffer */
/* always return the input as output buffer */
*buf = input;
gst_buffer_ref (input);
if (!gst_pad_has_current_caps (trans->sinkpad)) {
/* Buffer has no caps. See if the output pad only supports fixed caps */

View file

@ -388,15 +388,14 @@ gst_identity_prepare_output_buffer (GstBaseTransform * trans,
/* only bother if we may have to alter metadata */
if (identity->datarate > 0 || identity->single_segment) {
if (gst_buffer_is_writable (in_buf))
*out_buf = gst_buffer_ref (in_buf);
/* reuse */
*out_buf = in_buf;
else {
/* make even less writable */
gst_buffer_ref (in_buf);
/* extra ref is dropped going through the official process */
*out_buf = gst_buffer_make_writable (in_buf);
/* copy */
*out_buf = gst_buffer_copy (in_buf);
}
} else
*out_buf = gst_buffer_ref (in_buf);
*out_buf = in_buf;
return GST_FLOW_OK;
}