mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
libs/gst/base/gstbasetransform.c: Make sure the buffer we pass to transform_ip has a refcount of 1 and thus is writab...
Original commit message from CVS: * libs/gst/base/gstbasetransform.c: (gst_base_transform_prepare_output_buffer), (gst_base_transform_buffer_alloc), (gst_base_transform_handle_buffer): Make sure the buffer we pass to transform_ip has a refcount of 1 and thus is writable. Fixes #343196
This commit is contained in:
parent
16ac778f31
commit
d7c7dcc686
2 changed files with 36 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2006-07-05 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
* libs/gst/base/gstbasetransform.c:
|
||||||
|
(gst_base_transform_prepare_output_buffer),
|
||||||
|
(gst_base_transform_buffer_alloc),
|
||||||
|
(gst_base_transform_handle_buffer):
|
||||||
|
Make sure the buffer we pass to transform_ip has a refcount of
|
||||||
|
1 and thus is writable. Fixes #343196
|
||||||
|
|
||||||
2006-07-04 Jan Schmidt <thaytan@mad.scientist.com>
|
2006-07-04 Jan Schmidt <thaytan@mad.scientist.com>
|
||||||
|
|
||||||
* plugins/elements/gstfilesrc.c: (gst_file_src_class_init),
|
* plugins/elements/gstfilesrc.c: (gst_file_src_class_init),
|
||||||
|
|
|
@ -858,6 +858,10 @@ failed_configure:
|
||||||
/* Allocate a buffer using gst_pad_alloc_buffer
|
/* Allocate a buffer using gst_pad_alloc_buffer
|
||||||
*
|
*
|
||||||
* This function does not do renegotiation on the source pad
|
* This function does not 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
|
static GstFlowReturn
|
||||||
gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
||||||
|
@ -873,6 +877,7 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
||||||
* the old buffer. We will therefore delay the reconfiguration of the
|
* the old buffer. We will therefore delay the reconfiguration of the
|
||||||
* element until we have processed this last buffer. */
|
* element until we have processed this last buffer. */
|
||||||
trans->delay_configure = TRUE;
|
trans->delay_configure = TRUE;
|
||||||
|
|
||||||
/* out_caps is the caps of the src pad gathered through the GST_PAD_CAPS
|
/* out_caps is the caps of the src pad gathered through the GST_PAD_CAPS
|
||||||
macro. If a set_caps occurs during this function this caps will become
|
macro. If a set_caps occurs during this function this caps will become
|
||||||
invalid. We want to keep them during preparation of the output buffer. */
|
invalid. We want to keep them during preparation of the output buffer. */
|
||||||
|
@ -886,6 +891,13 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
||||||
out_buf);
|
out_buf);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
/* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if we want to prepare the buffer for in place output */
|
/* See if we want to prepare the buffer for in place output */
|
||||||
|
@ -893,18 +905,24 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
||||||
&& bclass->transform_ip) {
|
&& bclass->transform_ip) {
|
||||||
if (gst_buffer_is_writable (in_buf)) {
|
if (gst_buffer_is_writable (in_buf)) {
|
||||||
if (trans->have_same_caps) {
|
if (trans->have_same_caps) {
|
||||||
/* Input buffer is already writable and caps are the same, just ref and return it */
|
/* Input buffer is already writable and caps are the same, return input as
|
||||||
|
* output buffer. We don't take an additional ref since that would make the
|
||||||
|
* output buffer not writable anymore. Caller should be prepared to deal
|
||||||
|
* with proper refcounting of input/output buffers. */
|
||||||
*out_buf = in_buf;
|
*out_buf = in_buf;
|
||||||
gst_buffer_ref (in_buf);
|
GST_LOG_OBJECT (trans, "reuse input buffer");
|
||||||
} else {
|
} else {
|
||||||
/* Writable buffer, but need to change caps => subbuffer */
|
/* Writable buffer, but need to change caps => subbuffer */
|
||||||
*out_buf = gst_buffer_create_sub (in_buf, 0, GST_BUFFER_SIZE (in_buf));
|
*out_buf = gst_buffer_create_sub (in_buf, 0, GST_BUFFER_SIZE (in_buf));
|
||||||
gst_caps_replace (&GST_BUFFER_CAPS (*out_buf), out_caps);
|
gst_caps_replace (&GST_BUFFER_CAPS (*out_buf), out_caps);
|
||||||
|
GST_LOG_OBJECT (trans, "created sub-buffer of input buffer");
|
||||||
}
|
}
|
||||||
|
/* we are done now */
|
||||||
goto done;
|
goto done;
|
||||||
} else {
|
} else {
|
||||||
/* Make a writable buffer below and copy the data */
|
/* Make a writable buffer below and copy the data */
|
||||||
copy_inbuf = TRUE;
|
copy_inbuf = TRUE;
|
||||||
|
GST_LOG_OBJECT (trans, "need to copy input buffer to new output buffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,6 +959,7 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
|
||||||
done:
|
done:
|
||||||
if (out_caps)
|
if (out_caps)
|
||||||
gst_caps_unref (out_caps);
|
gst_caps_unref (out_caps);
|
||||||
|
|
||||||
trans->delay_configure = FALSE;
|
trans->delay_configure = FALSE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1369,8 +1388,11 @@ no_qos:
|
||||||
if (!success)
|
if (!success)
|
||||||
goto configure_failed;
|
goto configure_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
skip:
|
skip:
|
||||||
gst_buffer_unref (inbuf);
|
/* only unref input buffer if we allocated a new outbuf buffer */
|
||||||
|
if (*outbuf != inbuf)
|
||||||
|
gst_buffer_unref (inbuf);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -1399,7 +1421,8 @@ no_buffer:
|
||||||
}
|
}
|
||||||
configure_failed:
|
configure_failed:
|
||||||
{
|
{
|
||||||
gst_buffer_unref (inbuf);
|
if (*outbuf != inbuf)
|
||||||
|
gst_buffer_unref (inbuf);
|
||||||
GST_DEBUG_OBJECT (trans, "could not negotiate");
|
GST_DEBUG_OBJECT (trans, "could not negotiate");
|
||||||
return GST_FLOW_NOT_NEGOTIATED;
|
return GST_FLOW_NOT_NEGOTIATED;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue