gst/base/gstbasetransform.c: Small cleanups.

Original commit message from CVS:
* gst/base/gstbasetransform.c:
(gst_base_transform_prepare_output_buf),
(gst_base_transform_handle_buffer):
Small cleanups.
If we're processing a buffer and need to allocate an output
buffer, we cannot accept a format change. If we did get a
format change, we have to alloc a buffer ourselves of the
right size.
This commit is contained in:
Wim Taymans 2005-11-11 16:37:11 +00:00
parent e39c2beaae
commit 1a87f97de7
3 changed files with 113 additions and 68 deletions

View file

@ -1,3 +1,14 @@
2005-11-11 Wim Taymans <wim@fluendo.com>
* gst/base/gstbasetransform.c:
(gst_base_transform_prepare_output_buf),
(gst_base_transform_handle_buffer):
Small cleanups.
If we're processing a buffer and need to allocate an output
buffer, we cannot accept a format change. If we did get a
format change, we have to alloc a buffer ourselves of the
right size.
2005-11-11 Wim Taymans <wim@fluendo.com>
* gst/gstpad.c: (gst_pad_get_caps), (gst_pad_peer_get_caps):

View file

@ -785,10 +785,19 @@ failed_configure:
}
}
/* Allocate a buffer using gst_pad_alloc_buffer */
/* Allocate a buffer using gst_pad_alloc_buffer.
*
* This function can trigger a renegotiation on the source pad when the
* peer alloc_buffer function sets new caps. Since we currently are
* processing a buffer on the sinkpad when this function is called, we cannot
* reconfigure the transform with sinkcaps different from those of the current
* buffer. FIXME, we currently don't check if the pluging can transform to the
* new srcpad caps using the same sinkcaps, we alloc a proper outbuf buffer
* ourselves instead.
*/
static GstFlowReturn
gst_base_transform_prepare_output_buf (GstBaseTransform * trans,
GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf)
{
GstBaseTransformClass *bclass;
GstFlowReturn ret = GST_FLOW_OK;
@ -796,53 +805,72 @@ gst_base_transform_prepare_output_buf (GstBaseTransform * trans,
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
/* we cannot reconfigure the element yet as we are still processing
* the old buffer. We will therefore delay the reconfiguration of the
* element until we have processed this last buffer. */
trans->delay_configure = TRUE;
/* see if the subclass wants to alloc a buffer */
if (bclass->prepare_output_buffer) {
ret = bclass->prepare_output_buffer (trans, input, size, caps, buf);
ret =
bclass->prepare_output_buffer (trans, in_buf, out_size, out_caps,
out_buf);
if (ret != GST_FLOW_OK)
return ret;
goto done;
}
/* See if we want to prepare the buffer for in place output */
if (*buf == NULL && GST_BUFFER_SIZE (input) == size && bclass->transform_ip) {
if (gst_buffer_is_writable (input)) {
if (*out_buf == NULL && GST_BUFFER_SIZE (in_buf) == out_size
&& bclass->transform_ip) {
if (gst_buffer_is_writable (in_buf)) {
if (trans->have_same_caps) {
/* Input buffer is already writable and caps are the same, just ref and return it */
*buf = input;
gst_buffer_ref (input);
*out_buf = in_buf;
gst_buffer_ref (in_buf);
} else {
/* Writable buffer, but need to change caps => subbuffer */
*buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
gst_caps_replace (&GST_BUFFER_CAPS (*buf), caps);
*out_buf = gst_buffer_create_sub (in_buf, 0, GST_BUFFER_SIZE (in_buf));
gst_caps_replace (&GST_BUFFER_CAPS (*out_buf), out_caps);
}
return GST_FLOW_OK;
goto done;
} else {
/* Make a writable buffer below and copy the data */
copy_inbuf = TRUE;
}
}
if (*buf == NULL) {
/* Sub-class didn't already implement a buffer for us. Make one */
ret = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET (input),
size, caps, buf);
if (ret != GST_FLOW_OK || *buf == NULL)
return ret;
if (*out_buf == NULL) {
/* Sub-class didn't already provide a buffer for us. Make one */
ret = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET (in_buf),
out_size, out_caps, out_buf);
if (ret != GST_FLOW_OK || *out_buf == NULL)
goto done;
/* allocated buffer could be of different caps than what we requested */
if (G_UNLIKELY (!gst_caps_is_equal (out_caps, GST_BUFFER_CAPS (*out_buf)))) {
/* FIXME, it is possible we can reconfigure the transform with new caps at this
* point but for now we just create a buffer ourselves */
*out_buf = gst_buffer_new_and_alloc (out_size);
gst_buffer_set_caps (*out_buf, out_caps);
}
}
/* If the output buffer metadata is modifiable, copy timestamps and
* buffer flags */
if (*buf != input && GST_MINI_OBJECT_REFCOUNT_VALUE (*buf) == 1) {
if (*out_buf != in_buf && GST_MINI_OBJECT_REFCOUNT_VALUE (*out_buf) == 1) {
if (copy_inbuf && gst_buffer_is_writable (*buf))
memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size);
if (copy_inbuf && gst_buffer_is_writable (*out_buf))
memcpy (GST_BUFFER_DATA (*out_buf), GST_BUFFER_DATA (in_buf), out_size);
gst_buffer_stamp (*buf, input);
GST_BUFFER_FLAGS (*buf) |= GST_BUFFER_FLAGS (input) &
gst_buffer_stamp (*out_buf, in_buf);
GST_BUFFER_FLAGS (*out_buf) |= GST_BUFFER_FLAGS (in_buf) &
(GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
GST_BUFFER_FLAG_DELTA_UNIT);
}
done:
trans->delay_configure = FALSE;
return ret;
}
@ -1117,13 +1145,8 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
* wish. */
GST_LOG_OBJECT (trans, "doing inplace transform");
/* we cannot reconfigure the element yet as we are still processing
* the old buffer. We will therefore delay the reconfiguration of the
* element until we have processed this last buffer. */
trans->delay_configure = TRUE;
ret = gst_base_transform_prepare_output_buf (trans, inbuf,
GST_BUFFER_SIZE (inbuf), GST_PAD_CAPS (trans->srcpad), outbuf);
trans->delay_configure = FALSE;
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto no_buffer;
@ -1145,15 +1168,9 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
}
}
/* we cannot reconfigure the element yet as we are still processing
* the old buffer. We will therefore delay the reconfiguration of the
* element until we have processed this last buffer. */
trans->delay_configure = TRUE;
/* no in place transform, get buffer, this might renegotiate. */
ret = gst_base_transform_prepare_output_buf (trans, inbuf, out_size,
GST_PAD_CAPS (trans->srcpad), outbuf);
trans->delay_configure = FALSE;
if (ret != GST_FLOW_OK)
goto no_buffer;

View file

@ -785,10 +785,19 @@ failed_configure:
}
}
/* Allocate a buffer using gst_pad_alloc_buffer */
/* Allocate a buffer using gst_pad_alloc_buffer.
*
* This function can trigger a renegotiation on the source pad when the
* peer alloc_buffer function sets new caps. Since we currently are
* processing a buffer on the sinkpad when this function is called, we cannot
* reconfigure the transform with sinkcaps different from those of the current
* buffer. FIXME, we currently don't check if the pluging can transform to the
* new srcpad caps using the same sinkcaps, we alloc a proper outbuf buffer
* ourselves instead.
*/
static GstFlowReturn
gst_base_transform_prepare_output_buf (GstBaseTransform * trans,
GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf)
{
GstBaseTransformClass *bclass;
GstFlowReturn ret = GST_FLOW_OK;
@ -796,53 +805,72 @@ gst_base_transform_prepare_output_buf (GstBaseTransform * trans,
bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
/* we cannot reconfigure the element yet as we are still processing
* the old buffer. We will therefore delay the reconfiguration of the
* element until we have processed this last buffer. */
trans->delay_configure = TRUE;
/* see if the subclass wants to alloc a buffer */
if (bclass->prepare_output_buffer) {
ret = bclass->prepare_output_buffer (trans, input, size, caps, buf);
ret =
bclass->prepare_output_buffer (trans, in_buf, out_size, out_caps,
out_buf);
if (ret != GST_FLOW_OK)
return ret;
goto done;
}
/* See if we want to prepare the buffer for in place output */
if (*buf == NULL && GST_BUFFER_SIZE (input) == size && bclass->transform_ip) {
if (gst_buffer_is_writable (input)) {
if (*out_buf == NULL && GST_BUFFER_SIZE (in_buf) == out_size
&& bclass->transform_ip) {
if (gst_buffer_is_writable (in_buf)) {
if (trans->have_same_caps) {
/* Input buffer is already writable and caps are the same, just ref and return it */
*buf = input;
gst_buffer_ref (input);
*out_buf = in_buf;
gst_buffer_ref (in_buf);
} else {
/* Writable buffer, but need to change caps => subbuffer */
*buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
gst_caps_replace (&GST_BUFFER_CAPS (*buf), caps);
*out_buf = gst_buffer_create_sub (in_buf, 0, GST_BUFFER_SIZE (in_buf));
gst_caps_replace (&GST_BUFFER_CAPS (*out_buf), out_caps);
}
return GST_FLOW_OK;
goto done;
} else {
/* Make a writable buffer below and copy the data */
copy_inbuf = TRUE;
}
}
if (*buf == NULL) {
/* Sub-class didn't already implement a buffer for us. Make one */
ret = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET (input),
size, caps, buf);
if (ret != GST_FLOW_OK || *buf == NULL)
return ret;
if (*out_buf == NULL) {
/* Sub-class didn't already provide a buffer for us. Make one */
ret = gst_pad_alloc_buffer (trans->srcpad, GST_BUFFER_OFFSET (in_buf),
out_size, out_caps, out_buf);
if (ret != GST_FLOW_OK || *out_buf == NULL)
goto done;
/* allocated buffer could be of different caps than what we requested */
if (G_UNLIKELY (!gst_caps_is_equal (out_caps, GST_BUFFER_CAPS (*out_buf)))) {
/* FIXME, it is possible we can reconfigure the transform with new caps at this
* point but for now we just create a buffer ourselves */
*out_buf = gst_buffer_new_and_alloc (out_size);
gst_buffer_set_caps (*out_buf, out_caps);
}
}
/* If the output buffer metadata is modifiable, copy timestamps and
* buffer flags */
if (*buf != input && GST_MINI_OBJECT_REFCOUNT_VALUE (*buf) == 1) {
if (*out_buf != in_buf && GST_MINI_OBJECT_REFCOUNT_VALUE (*out_buf) == 1) {
if (copy_inbuf && gst_buffer_is_writable (*buf))
memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size);
if (copy_inbuf && gst_buffer_is_writable (*out_buf))
memcpy (GST_BUFFER_DATA (*out_buf), GST_BUFFER_DATA (in_buf), out_size);
gst_buffer_stamp (*buf, input);
GST_BUFFER_FLAGS (*buf) |= GST_BUFFER_FLAGS (input) &
gst_buffer_stamp (*out_buf, in_buf);
GST_BUFFER_FLAGS (*out_buf) |= GST_BUFFER_FLAGS (in_buf) &
(GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
GST_BUFFER_FLAG_DELTA_UNIT);
}
done:
trans->delay_configure = FALSE;
return ret;
}
@ -1117,13 +1145,8 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
* wish. */
GST_LOG_OBJECT (trans, "doing inplace transform");
/* we cannot reconfigure the element yet as we are still processing
* the old buffer. We will therefore delay the reconfiguration of the
* element until we have processed this last buffer. */
trans->delay_configure = TRUE;
ret = gst_base_transform_prepare_output_buf (trans, inbuf,
GST_BUFFER_SIZE (inbuf), GST_PAD_CAPS (trans->srcpad), outbuf);
trans->delay_configure = FALSE;
if (G_UNLIKELY (ret != GST_FLOW_OK))
goto no_buffer;
@ -1145,15 +1168,9 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
}
}
/* we cannot reconfigure the element yet as we are still processing
* the old buffer. We will therefore delay the reconfiguration of the
* element until we have processed this last buffer. */
trans->delay_configure = TRUE;
/* no in place transform, get buffer, this might renegotiate. */
ret = gst_base_transform_prepare_output_buf (trans, inbuf, out_size,
GST_PAD_CAPS (trans->srcpad), outbuf);
trans->delay_configure = FALSE;
if (ret != GST_FLOW_OK)
goto no_buffer;