+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>
* gst/gst.c: (load_plugin_func):
gboolean qos_enabled;
gdouble proportion;
GstClockTime earliest_time;
+ /* previous buffer had a discont */
+ gboolean discont;
GstActivateMode pad_mode;
};
/* 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;
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;
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;
}
}
*outbuf = inbuf;
- return ret;
+ goto done;
}
want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place;
if (*outbuf != inbuf)
gst_buffer_unref (inbuf);
+done:
return ret;
/* ERRORS */
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;
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 {
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",
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;
}
}