libs/gst/base/gstbasetransform.*: Add support for dropping buffers with custom GstFlowReturn.

Original commit message from CVS:
* libs/gst/base/gstbasetransform.c:
(gst_base_transform_sink_eventfunc),
(gst_base_transform_handle_buffer), (gst_base_transform_chain),
(gst_base_transform_activate):
* libs/gst/base/gstbasetransform.h:
Add support for dropping buffers with custom GstFlowReturn.
Set DISCONT flags on outgoing buffers based on QoS, incomming DISCONT
buffers or dropped buffers.
* docs/libs/gstreamer-libs-sections.txt:
docs for new custom return code.
* plugins/elements/gstidentity.c: (gst_identity_transform_ip):
Use drop support in base class to implement drop-probability.
This commit is contained in:
Wim Taymans 2007-03-08 11:40:18 +00:00
parent a6510349d4
commit ecc37d9389
6 changed files with 65 additions and 11 deletions

View file

@ -1,3 +1,20 @@
2007-03-08 Wim Taymans <wim@fluendo.com>
* libs/gst/base/gstbasetransform.c:
(gst_base_transform_sink_eventfunc),
(gst_base_transform_handle_buffer), (gst_base_transform_chain),
(gst_base_transform_activate):
* libs/gst/base/gstbasetransform.h:
Add support for dropping buffers with custom GstFlowReturn.
Set DISCONT flags on outgoing buffers based on QoS, incomming DISCONT
buffers or dropped buffers.
* docs/libs/gstreamer-libs-sections.txt:
docs for new custom return code.
* plugins/elements/gstidentity.c: (gst_identity_transform_ip):
Use drop support in base class to implement drop-probability.
2007-03-07 Tim-Philipp Müller <tim at centricular dot net> 2007-03-07 Tim-Philipp Müller <tim at centricular dot net>
* gst/gst.c: (load_plugin_func): * gst/gst.c: (load_plugin_func):

2
common

@ -1 +1 @@
Subproject commit c4f56a657d79aee0e3fc25ef2bcf876f9f3c1593 Subproject commit 7c5a0ab68de1fed4e5a1fd473160debc2c4c7b89

View file

@ -222,6 +222,8 @@ GST_BASE_TRANSFORM_SRC_NAME
GST_BASE_TRANSFORM_SINK_PAD GST_BASE_TRANSFORM_SINK_PAD
GST_BASE_TRANSFORM_SRC_PAD GST_BASE_TRANSFORM_SRC_PAD
GST_BASE_TRANSFORM_FLOW_DROPPED
<SUBSECTION Standard> <SUBSECTION Standard>
GST_BASE_TRANSFORM GST_BASE_TRANSFORM
GST_IS_BASE_TRANSFORM GST_IS_BASE_TRANSFORM

View file

@ -230,6 +230,8 @@ struct _GstBaseTransformPrivate
gboolean qos_enabled; gboolean qos_enabled;
gdouble proportion; gdouble proportion;
GstClockTime earliest_time; GstClockTime earliest_time;
/* previous buffer had a discont */
gboolean discont;
GstActivateMode pad_mode; GstActivateMode pad_mode;
}; };
@ -1250,6 +1252,7 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
/* reset QoS parameters */ /* reset QoS parameters */
trans->priv->proportion = 1.0; trans->priv->proportion = 1.0;
trans->priv->earliest_time = -1; trans->priv->earliest_time = -1;
trans->priv->discont = FALSE;
GST_OBJECT_UNLOCK (trans); GST_OBJECT_UNLOCK (trans);
/* we need new segment info after the flush. */ /* we need new segment info after the flush. */
trans->have_newsegment = FALSE; trans->have_newsegment = FALSE;
@ -1372,6 +1375,12 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL)) if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL))
goto not_negotiated; goto not_negotiated;
/* Set discont flag so we can mark the outgoing buffer */
if (GST_BUFFER_IS_DISCONT (inbuf)) {
GST_LOG_OBJECT (trans, "got DISCONT buffer %p", inbuf);
trans->priv->discont = TRUE;
}
/* can only do QoS if the segment is in TIME */ /* can only do QoS if the segment is in TIME */
if (trans->segment.format != GST_FORMAT_TIME) if (trans->segment.format != GST_FORMAT_TIME)
goto no_qos; goto no_qos;
@ -1395,6 +1404,8 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, "skipping transform: qostime %" GST_CAT_DEBUG_OBJECT (GST_CAT_QOS, trans, "skipping transform: qostime %"
GST_TIME_FORMAT " <= %" GST_TIME_FORMAT, GST_TIME_FORMAT " <= %" GST_TIME_FORMAT,
GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time)); GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time));
/* mark discont for next buffer */
trans->priv->discont = TRUE;
goto skip; goto skip;
} }
} }
@ -1411,7 +1422,7 @@ no_qos:
*outbuf = inbuf; *outbuf = inbuf;
return ret; goto done;
} }
want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place; want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place;
@ -1477,6 +1488,7 @@ skip:
if (*outbuf != inbuf) if (*outbuf != inbuf)
gst_buffer_unref (inbuf); gst_buffer_unref (inbuf);
done:
return ret; return ret;
/* ERRORS */ /* ERRORS */
@ -1565,14 +1577,29 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
ret = gst_base_transform_handle_buffer (trans, buffer, &outbuf); ret = gst_base_transform_handle_buffer (trans, buffer, &outbuf);
g_mutex_unlock (trans->transform_lock); g_mutex_unlock (trans->transform_lock);
/* outbuf can be NULL, this means a dropped buffer */ /* outbuf can be NULL, this means a dropped buffer, if we have a buffer but
* GST_BASE_TRANSFORM_FLOW_DROPPED we will not push either. */
if (outbuf != NULL) { if (outbuf != NULL) {
if ((ret == GST_FLOW_OK)) if ((ret == GST_FLOW_OK)) {
/* apply DISCONT flag if the buffer is not yet marked as such */
if (trans->priv->discont) {
if (!GST_BUFFER_IS_DISCONT (outbuf)) {
outbuf = gst_buffer_make_metadata_writable (outbuf);
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
}
trans->priv->discont = FALSE;
}
ret = gst_pad_push (trans->srcpad, outbuf); ret = gst_pad_push (trans->srcpad, outbuf);
else } else
gst_buffer_unref (outbuf); gst_buffer_unref (outbuf);
} }
/* convert internal flow to OK and mark discont for the next buffer. */
if (ret == GST_BASE_TRANSFORM_FLOW_DROPPED) {
trans->priv->discont = TRUE;
ret = GST_FLOW_OK;
}
gst_object_unref (trans); gst_object_unref (trans);
return ret; return ret;
@ -1641,6 +1668,7 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED); gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
trans->priv->proportion = 1.0; trans->priv->proportion = 1.0;
trans->priv->earliest_time = -1; trans->priv->earliest_time = -1;
trans->priv->discont = FALSE;
GST_OBJECT_UNLOCK (trans); GST_OBJECT_UNLOCK (trans);
} else { } else {

View file

@ -67,11 +67,20 @@ G_BEGIN_DECLS
*/ */
#define GST_BASE_TRANSFORM_SINK_PAD(obj) (GST_BASE_TRANSFORM_CAST (obj)->sinkpad) #define GST_BASE_TRANSFORM_SINK_PAD(obj) (GST_BASE_TRANSFORM_CAST (obj)->sinkpad)
/**
* GST_BASE_TRANSFORM_FLOW_DROPPED:
*
* A #GstFlowReturn that can be returned from transform and transform_ip to
* indicate that no output buffer was generated.
*
* Since: 0.10.13
*/
#define GST_BASE_TRANSFORM_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS
typedef struct _GstBaseTransform GstBaseTransform; typedef struct _GstBaseTransform GstBaseTransform;
typedef struct _GstBaseTransformClass GstBaseTransformClass; typedef struct _GstBaseTransformClass GstBaseTransformClass;
typedef struct _GstBaseTransformPrivate GstBaseTransformPrivate; typedef struct _GstBaseTransformPrivate GstBaseTransformPrivate;
/** /**
* GstBaseTransform: * GstBaseTransform:
* @element: the parent element. * @element: the parent element.

View file

@ -183,7 +183,7 @@ gst_identity_class_init (GstIdentityClass * klass)
g_object_class_install_property (gobject_class, g_object_class_install_property (gobject_class,
PROP_DROP_PROBABILITY, g_param_spec_float ("drop_probability", PROP_DROP_PROBABILITY, g_param_spec_float ("drop_probability",
"Drop Probability", "Drop Probability",
"The Probability a buffer is dropped (not implemented)", 0.0, 1.0, "The Probability a buffer is dropped", 0.0, 1.0,
DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE)); DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE));
g_object_class_install_property (gobject_class, PROP_DATARATE, g_object_class_install_property (gobject_class, PROP_DATARATE,
g_param_spec_int ("datarate", "Datarate", g_param_spec_int ("datarate", "Datarate",
@ -434,10 +434,8 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
GST_OBJECT_UNLOCK (identity); GST_OBJECT_UNLOCK (identity);
g_object_notify (G_OBJECT (identity), "last-message"); g_object_notify (G_OBJECT (identity), "last-message");
} }
/* FIXME, this does not drop the buffer in basetransform. Actually /* return DROPPED to basetransform. */
* dropping the buffer in transform_ip is not possible without a new return GST_BASE_TRANSFORM_FLOW_DROPPED;
* custom GstFlowReturn value. */
return GST_FLOW_OK;
} }
} }