libs/gst/base/gstbasetransform.*: Add support for dropping buffers with custom GstFlo...
authorWim Taymans <wim.taymans@gmail.com>
Thu, 8 Mar 2007 11:40:18 +0000 (11:40 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Thu, 8 Mar 2007 11:40:18 +0000 (11:40 +0000)
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.

ChangeLog
common
docs/libs/gstreamer-libs-sections.txt
libs/gst/base/gstbasetransform.c
libs/gst/base/gstbasetransform.h
plugins/elements/gstidentity.c

index 33ed592..4581cfa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * gst/gst.c: (load_plugin_func):
diff --git a/common b/common
index c4f56a6..7c5a0ab 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit c4f56a657d79aee0e3fc25ef2bcf876f9f3c1593
+Subproject commit 7c5a0ab68de1fed4e5a1fd473160debc2c4c7b89
index 692d4a3..4f75333 100644 (file)
@@ -222,6 +222,8 @@ GST_BASE_TRANSFORM_SRC_NAME
 GST_BASE_TRANSFORM_SINK_PAD
 GST_BASE_TRANSFORM_SRC_PAD
 
+GST_BASE_TRANSFORM_FLOW_DROPPED
+
 <SUBSECTION Standard>
 GST_BASE_TRANSFORM
 GST_IS_BASE_TRANSFORM
index fbd3e8f..dc91b49 100644 (file)
@@ -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 {
index 8a846d3..ad8344f 100644 (file)
@@ -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.
index 0af5920..1f31d66 100644 (file)
@@ -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;
     }
   }