diff --git a/ChangeLog b/ChangeLog index 33ed59219f..4581cfad60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-03-08 Wim Taymans + + * 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 * gst/gst.c: (load_plugin_func): diff --git a/common b/common index c4f56a657d..7c5a0ab68d 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit c4f56a657d79aee0e3fc25ef2bcf876f9f3c1593 +Subproject commit 7c5a0ab68de1fed4e5a1fd473160debc2c4c7b89 diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 692d4a3977..4f75333e50 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -222,6 +222,8 @@ GST_BASE_TRANSFORM_SRC_NAME GST_BASE_TRANSFORM_SINK_PAD GST_BASE_TRANSFORM_SRC_PAD +GST_BASE_TRANSFORM_FLOW_DROPPED + GST_BASE_TRANSFORM GST_IS_BASE_TRANSFORM diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index fbd3e8f5ee..dc91b49605 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -230,6 +230,8 @@ struct _GstBaseTransformPrivate gboolean qos_enabled; gdouble proportion; GstClockTime earliest_time; + /* previous buffer had a discont */ + gboolean discont; GstActivateMode pad_mode; }; @@ -1250,6 +1252,7 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event) /* reset QoS parameters */ trans->priv->proportion = 1.0; trans->priv->earliest_time = -1; + trans->priv->discont = FALSE; GST_OBJECT_UNLOCK (trans); /* we need new segment info after the flush. */ 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)) 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 */ if (trans->segment.format != GST_FORMAT_TIME) 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_TIME_FORMAT " <= %" GST_TIME_FORMAT, GST_TIME_ARGS (qostime), GST_TIME_ARGS (earliest_time)); + /* mark discont for next buffer */ + trans->priv->discont = TRUE; goto skip; } } @@ -1411,7 +1422,7 @@ no_qos: *outbuf = inbuf; - return ret; + goto done; } want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place; @@ -1477,6 +1488,7 @@ skip: if (*outbuf != inbuf) gst_buffer_unref (inbuf); +done: return ret; /* ERRORS */ @@ -1565,14 +1577,29 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer) ret = gst_base_transform_handle_buffer (trans, buffer, &outbuf); 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 ((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); - else + } else 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); return ret; @@ -1641,6 +1668,7 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active) gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED); trans->priv->proportion = 1.0; trans->priv->earliest_time = -1; + trans->priv->discont = FALSE; GST_OBJECT_UNLOCK (trans); } else { diff --git a/libs/gst/base/gstbasetransform.h b/libs/gst/base/gstbasetransform.h index 8a846d3488..ad8344fbef 100644 --- a/libs/gst/base/gstbasetransform.h +++ b/libs/gst/base/gstbasetransform.h @@ -67,11 +67,20 @@ G_BEGIN_DECLS */ #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 _GstBaseTransformClass GstBaseTransformClass; typedef struct _GstBaseTransformPrivate GstBaseTransformPrivate; - /** * GstBaseTransform: * @element: the parent element. diff --git a/plugins/elements/gstidentity.c b/plugins/elements/gstidentity.c index 0af5920c6b..1f31d668c2 100644 --- a/plugins/elements/gstidentity.c +++ b/plugins/elements/gstidentity.c @@ -183,7 +183,7 @@ gst_identity_class_init (GstIdentityClass * klass) g_object_class_install_property (gobject_class, PROP_DROP_PROBABILITY, g_param_spec_float ("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)); g_object_class_install_property (gobject_class, PROP_DATARATE, g_param_spec_int ("datarate", "Datarate", @@ -434,10 +434,8 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf) GST_OBJECT_UNLOCK (identity); g_object_notify (G_OBJECT (identity), "last-message"); } - /* FIXME, this does not drop the buffer in basetransform. Actually - * dropping the buffer in transform_ip is not possible without a new - * custom GstFlowReturn value. */ - return GST_FLOW_OK; + /* return DROPPED to basetransform. */ + return GST_BASE_TRANSFORM_FLOW_DROPPED; } }