plugins/elements/gstidentity.c: Identity is not always a passthrough element, it can modify the buffer timestamps whe...

Original commit message from CVS:
Patch by: Mark Nauwelaerts <manauw at skynet be>
* plugins/elements/gstidentity.c: (gst_identity_class_init),
(gst_identity_init), (gst_identity_prepare_output_buffer):
Identity is not always a passthrough element, it can modify the buffer
timestamps when it has a datarate and operates in single-segment mode.
We therefore make it an in_place filter with a custom buffer prepare
function that conditionally makes the input buffer metadata writable
when needed.  Fixes #523985.
This commit is contained in:
Mark Nauwelaerts 2008-03-24 16:56:36 +00:00 committed by Wim Taymans
parent 7850967084
commit d82688054e
2 changed files with 39 additions and 2 deletions

View file

@ -1,3 +1,15 @@
2008-03-24 Wim Taymans <wim.taymans@collabora.co.uk>
Patch by: Mark Nauwelaerts <manauw at skynet be>
* plugins/elements/gstidentity.c: (gst_identity_class_init),
(gst_identity_init), (gst_identity_prepare_output_buffer):
Identity is not always a passthrough element, it can modify the buffer
timestamps when it has a datarate and operates in single-segment mode.
We therefore make it an in_place filter with a custom buffer prepare
function that conditionally makes the input buffer metadata writable
when needed. Fixes #523985.
2008-03-24 Wim Taymans <wim.taymans@collabora.co.uk>
Patch by: Mark Nauwelaerts <manauw at skynet be>

View file

@ -107,6 +107,9 @@ static void gst_identity_get_property (GObject * object, guint prop_id,
static gboolean gst_identity_event (GstBaseTransform * trans, GstEvent * event);
static GstFlowReturn gst_identity_transform_ip (GstBaseTransform * trans,
GstBuffer * buf);
static GstFlowReturn gst_identity_prepare_output_buffer (GstBaseTransform
* trans, GstBuffer * in_buf, gint out_size, GstCaps * out_caps,
GstBuffer ** out_buf);
static gboolean gst_identity_start (GstBaseTransform * trans);
static gboolean gst_identity_stop (GstBaseTransform * trans);
@ -267,6 +270,8 @@ gst_identity_class_init (GstIdentityClass * klass)
gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_identity_event);
gstbasetrans_class->transform_ip =
GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
gstbasetrans_class->prepare_output_buffer =
GST_DEBUG_FUNCPTR (gst_identity_prepare_output_buffer);
gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_identity_start);
gstbasetrans_class->stop = GST_DEBUG_FUNCPTR (gst_identity_stop);
}
@ -274,8 +279,6 @@ gst_identity_class_init (GstIdentityClass * klass)
static void
gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
{
gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (identity), TRUE);
identity->sleep_time = DEFAULT_SLEEP_TIME;
identity->error_after = DEFAULT_ERROR_AFTER;
identity->drop_probability = DEFAULT_DROP_PROBABILITY;
@ -349,6 +352,28 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
return ret;
}
static GstFlowReturn
gst_identity_prepare_output_buffer (GstBaseTransform * trans,
GstBuffer * in_buf, gint out_size, GstCaps * out_caps, GstBuffer ** out_buf)
{
GstIdentity *identity = GST_IDENTITY (trans);
/* only bother if we may have to alter metadata */
if (identity->datarate > 0 || identity->single_segment) {
if (gst_buffer_is_metadata_writable (in_buf))
*out_buf = gst_buffer_ref (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_metadata_writable (in_buf);
}
} else
*out_buf = gst_buffer_ref (in_buf);
return GST_FLOW_OK;
}
static void
gst_identity_check_perfect (GstIdentity * identity, GstBuffer * buf)
{