check/gst-libs/controller.c: Header include fix.
authorJan Schmidt <thaytan@mad.scientist.com>
Fri, 9 Sep 2005 23:45:15 +0000 (23:45 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Fri, 9 Sep 2005 23:45:15 +0000 (23:45 +0000)
Original commit message from CVS:
* check/gst-libs/controller.c:
Header include fix.
* gst/base/gstbasetransform.c:
(gst_base_transform_default_prepare_buf),
(gst_base_transform_handle_buffer):
* gst/base/gstbasetransform.h:
Some more basetransform changes and fixes to enable sub-classes
that modify buffer metadata only.
* gst/elements/gstcapsfilter.c: (gst_capsfilter_class_init),
(gst_capsfilter_init), (gst_capsfilter_transform_ip),
(gst_capsfilter_prepare_buf):
If the output pad has fixed allowed caps and input buffers
don't have any, set the fixed caps on outgoing buffers.

ChangeLog
check/gst-libs/controller.c
gst/base/gstbasetransform.c
gst/base/gstbasetransform.h
gst/elements/gstcapsfilter.c
libs/gst/base/gstbasetransform.c
libs/gst/base/gstbasetransform.h
plugins/elements/gstcapsfilter.c
tests/check/libs/controller.c

index 772b029..9c91472 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2005-09-10  Jan Schmidt  <thaytan@mad.scientist.com>
+
+       * check/gst-libs/controller.c:
+         Header include fix.
+       * gst/base/gstbasetransform.c:
+       (gst_base_transform_default_prepare_buf),
+       (gst_base_transform_handle_buffer):
+       * gst/base/gstbasetransform.h:
+         Some more basetransform changes and fixes to enable sub-classes
+         that modify buffer metadata only.
+       * gst/elements/gstcapsfilter.c: (gst_capsfilter_class_init),
+       (gst_capsfilter_init), (gst_capsfilter_transform_ip),
+       (gst_capsfilter_prepare_buf):
+         If the output pad has fixed allowed caps and input buffers 
+         don't have any, set the fixed caps on outgoing buffers.
+
 2005-09-09  Jan Schmidt  <thaytan@mad.scientist.com>
        * check/elements/identity.c: (GST_START_TEST):
          Make the error a little clearer when the test fails because
index c20fce9..83974a9 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "config.h"
 #include <gst/check/gstcheck.h>
-#include <gst/controller/gst-controller.h>
+#include <gst/controller/gstcontroller.h>
 
 /* LOCAL TEST ELEMENT */
 
index 2651d9d..819948b 100644 (file)
@@ -797,8 +797,8 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans,
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   /* See if we want to prepare the buffer for in place output */
-  if (GST_BUFFER_SIZE (input) == size && bclass->transform_ip) {
-    if (gst_buffer_is_writable (input) && (*buf == NULL)) {
+  if (*buf == NULL && GST_BUFFER_SIZE (input) == size && bclass->transform_ip) {
+    if (gst_buffer_is_writable (input)) {
       /* Input buffer is already writable, just ref and return it */
       *buf = input;
       gst_buffer_ref (input);
@@ -823,15 +823,15 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans,
    * buffer flags */
   if (*buf != input && GST_MINI_OBJECT_REFCOUNT_VALUE (*buf) == 1) {
 
+    if (copy_inbuf && gst_buffer_is_writable (*buf))
+      memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size);
+
     gst_buffer_stamp (*buf, input);
     GST_BUFFER_FLAGS (*buf) |= GST_BUFFER_FLAGS (input) &
         (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
         GST_BUFFER_FLAG_DELTA_UNIT);
   }
 
-  if (copy_inbuf && gst_buffer_is_writable (*buf))
-    memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size);
-
   return ret;
 }
 
@@ -1070,7 +1070,11 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
     GST_LOG_OBJECT (trans, "handling buffer %p of size %d and offset NONE",
         inbuf, GST_BUFFER_SIZE (inbuf));
 
-  if (!trans->negotiated && !trans->passthrough)
+  /* Don't allow buffer handling before negotiation, except in passthrough mode
+   * or if the class doesn't implement a set_caps function (in which case it doesn't
+   * care about caps)
+   */
+  if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL))
     goto not_negotiated;
 
   if (trans->passthrough) {
@@ -1088,6 +1092,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
   }
 
   want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place;
+  *outbuf = NULL;
 
   if (want_in_place) {
     /* If want_in_place is TRUE, we may need to prepare a new output buffer 
index ae8bba8..2f42a81 100644 (file)
@@ -51,9 +51,6 @@ struct _GstBaseTransform {
   gboolean      passthrough;
   gboolean      always_in_place;
 
-  /* Set if caps on each pad are equal */
-  gboolean      have_same_caps;
-
   GstCaps      *cache_caps1;
   guint                 cache_caps1_size;
   GstCaps      *cache_caps2;
@@ -70,8 +67,12 @@ struct _GstBaseTransform {
   gint64         segment_stop;
   gint64         segment_base;
 
+  /* FIXME: When adjusting the padding, move this to a nice place in the structure */
+  /* Set if caps on each pad are equal */
+  gboolean      have_same_caps;
+
   /*< private >*/
-  gpointer       _gst_reserved[GST_PADDING];
+  gpointer       _gst_reserved[GST_PADDING - 1];
 };
 
 /**
index b113007..9a6b168 100644 (file)
@@ -102,7 +102,8 @@ static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps);
 static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base,
     GstBuffer * buf);
-
+static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans,
+    GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
 
 static void
 gst_capsfilter_base_init (gpointer g_class)
@@ -135,12 +136,12 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
   trans_class = (GstBaseTransformClass *) klass;
   trans_class->transform_caps = gst_capsfilter_transform_caps;
   trans_class->transform_ip = gst_capsfilter_transform_ip;
+  trans_class->prepare_output_buffer = gst_capsfilter_prepare_buf;
 }
 
 static void
 gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class)
 {
-  gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE);
   filter->filter_caps = gst_caps_new_any ();
 }
 
@@ -216,15 +217,61 @@ gst_capsfilter_transform_caps (GstBaseTransform * base,
 static GstFlowReturn
 gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf)
 {
-  /* Ensure that outgoing buffers have caps if we can, so that pipelines
-   * like:
-   *   gst-launch filesrc location=rawsamples.raw ! 
-   *       audio/x-raw-int,width=16,depth=16,rate=48000,channels=2,
-   *       endianness=4321,signed='(boolean)'true ! alsasink
-   * will work.
-   */
-  if (GST_BUFFER_CAPS (buf) == NULL) {
+  /* No actual work here. It's all done in the prepare output buffer
+   * func. */
+  return GST_FLOW_OK;
+}
+
+/* Output buffer preparation... if the buffer has no caps, and
+ * our allowed output caps is fixed, then give the caps to the
+ * buffer.
+ * This ensures that outgoing buffers have caps if we can, so 
+ * that pipelines like:
+ *   gst-launch filesrc location=rawsamples.raw ! 
+ *       audio/x-raw-int,width=16,depth=16,rate=48000,channels=2,
+ *       endianness=4321,signed='(boolean)'true ! alsasink
+ * will work.
+ */
+static GstFlowReturn
+gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
+    gint size, GstCaps * caps, GstBuffer ** buf)
+{
+  if (GST_BUFFER_CAPS (input) != NULL) {
+    /* Output buffer already has caps */
+    GST_DEBUG_OBJECT (trans, "Input buffer already has caps");
+    gst_buffer_ref (input);
+    *buf = input;
+  } else {
+    /* Buffer has no caps. See if the output pad only supports fixed caps */
+    GstCaps *out_caps;
+
+    if (GST_PAD_CAPS (trans->srcpad) != NULL) {
+      gst_caps_ref (GST_PAD_CAPS (trans->srcpad));
+      out_caps = GST_PAD_CAPS (trans->srcpad);
+    } else {
+      out_caps = gst_pad_get_allowed_caps (trans->srcpad);
+      g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
+    }
+
+    if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) {
+      GST_DEBUG_OBJECT (trans, "Have fixed output caps %"
+          GST_PTR_FORMAT " to apply to buffer with no caps", out_caps);
+      if (gst_buffer_is_writable (input)) {
+        gst_buffer_ref (input);
+        *buf = input;
+      } else {
+        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
+        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
+      }
+      GST_BUFFER_CAPS (input) = out_caps;
+
+      if (GST_PAD_CAPS (trans->srcpad) == NULL)
+        gst_pad_set_caps (trans->srcpad, out_caps);
+    } else {
+      gst_caps_unref (out_caps);
+    }
   }
 
-  return GST_FLOW_OK;
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->
+      prepare_output_buffer (trans, input, size, caps, buf);
 }
index 2651d9d..819948b 100644 (file)
@@ -797,8 +797,8 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans,
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   /* See if we want to prepare the buffer for in place output */
-  if (GST_BUFFER_SIZE (input) == size && bclass->transform_ip) {
-    if (gst_buffer_is_writable (input) && (*buf == NULL)) {
+  if (*buf == NULL && GST_BUFFER_SIZE (input) == size && bclass->transform_ip) {
+    if (gst_buffer_is_writable (input)) {
       /* Input buffer is already writable, just ref and return it */
       *buf = input;
       gst_buffer_ref (input);
@@ -823,15 +823,15 @@ gst_base_transform_default_prepare_buf (GstBaseTransform * trans,
    * buffer flags */
   if (*buf != input && GST_MINI_OBJECT_REFCOUNT_VALUE (*buf) == 1) {
 
+    if (copy_inbuf && gst_buffer_is_writable (*buf))
+      memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size);
+
     gst_buffer_stamp (*buf, input);
     GST_BUFFER_FLAGS (*buf) |= GST_BUFFER_FLAGS (input) &
         (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
         GST_BUFFER_FLAG_DELTA_UNIT);
   }
 
-  if (copy_inbuf && gst_buffer_is_writable (*buf))
-    memcpy (GST_BUFFER_DATA (*buf), GST_BUFFER_DATA (input), size);
-
   return ret;
 }
 
@@ -1070,7 +1070,11 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
     GST_LOG_OBJECT (trans, "handling buffer %p of size %d and offset NONE",
         inbuf, GST_BUFFER_SIZE (inbuf));
 
-  if (!trans->negotiated && !trans->passthrough)
+  /* Don't allow buffer handling before negotiation, except in passthrough mode
+   * or if the class doesn't implement a set_caps function (in which case it doesn't
+   * care about caps)
+   */
+  if (!trans->negotiated && !trans->passthrough && (bclass->set_caps != NULL))
     goto not_negotiated;
 
   if (trans->passthrough) {
@@ -1088,6 +1092,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
   }
 
   want_in_place = (bclass->transform_ip != NULL) && trans->always_in_place;
+  *outbuf = NULL;
 
   if (want_in_place) {
     /* If want_in_place is TRUE, we may need to prepare a new output buffer 
index ae8bba8..2f42a81 100644 (file)
@@ -51,9 +51,6 @@ struct _GstBaseTransform {
   gboolean      passthrough;
   gboolean      always_in_place;
 
-  /* Set if caps on each pad are equal */
-  gboolean      have_same_caps;
-
   GstCaps      *cache_caps1;
   guint                 cache_caps1_size;
   GstCaps      *cache_caps2;
@@ -70,8 +67,12 @@ struct _GstBaseTransform {
   gint64         segment_stop;
   gint64         segment_base;
 
+  /* FIXME: When adjusting the padding, move this to a nice place in the structure */
+  /* Set if caps on each pad are equal */
+  gboolean      have_same_caps;
+
   /*< private >*/
-  gpointer       _gst_reserved[GST_PADDING];
+  gpointer       _gst_reserved[GST_PADDING - 1];
 };
 
 /**
index b113007..9a6b168 100644 (file)
@@ -102,7 +102,8 @@ static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps);
 static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base,
     GstBuffer * buf);
-
+static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans,
+    GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
 
 static void
 gst_capsfilter_base_init (gpointer g_class)
@@ -135,12 +136,12 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
   trans_class = (GstBaseTransformClass *) klass;
   trans_class->transform_caps = gst_capsfilter_transform_caps;
   trans_class->transform_ip = gst_capsfilter_transform_ip;
+  trans_class->prepare_output_buffer = gst_capsfilter_prepare_buf;
 }
 
 static void
 gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class)
 {
-  gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (filter), TRUE);
   filter->filter_caps = gst_caps_new_any ();
 }
 
@@ -216,15 +217,61 @@ gst_capsfilter_transform_caps (GstBaseTransform * base,
 static GstFlowReturn
 gst_capsfilter_transform_ip (GstBaseTransform * base, GstBuffer * buf)
 {
-  /* Ensure that outgoing buffers have caps if we can, so that pipelines
-   * like:
-   *   gst-launch filesrc location=rawsamples.raw ! 
-   *       audio/x-raw-int,width=16,depth=16,rate=48000,channels=2,
-   *       endianness=4321,signed='(boolean)'true ! alsasink
-   * will work.
-   */
-  if (GST_BUFFER_CAPS (buf) == NULL) {
+  /* No actual work here. It's all done in the prepare output buffer
+   * func. */
+  return GST_FLOW_OK;
+}
+
+/* Output buffer preparation... if the buffer has no caps, and
+ * our allowed output caps is fixed, then give the caps to the
+ * buffer.
+ * This ensures that outgoing buffers have caps if we can, so 
+ * that pipelines like:
+ *   gst-launch filesrc location=rawsamples.raw ! 
+ *       audio/x-raw-int,width=16,depth=16,rate=48000,channels=2,
+ *       endianness=4321,signed='(boolean)'true ! alsasink
+ * will work.
+ */
+static GstFlowReturn
+gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
+    gint size, GstCaps * caps, GstBuffer ** buf)
+{
+  if (GST_BUFFER_CAPS (input) != NULL) {
+    /* Output buffer already has caps */
+    GST_DEBUG_OBJECT (trans, "Input buffer already has caps");
+    gst_buffer_ref (input);
+    *buf = input;
+  } else {
+    /* Buffer has no caps. See if the output pad only supports fixed caps */
+    GstCaps *out_caps;
+
+    if (GST_PAD_CAPS (trans->srcpad) != NULL) {
+      gst_caps_ref (GST_PAD_CAPS (trans->srcpad));
+      out_caps = GST_PAD_CAPS (trans->srcpad);
+    } else {
+      out_caps = gst_pad_get_allowed_caps (trans->srcpad);
+      g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
+    }
+
+    if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) {
+      GST_DEBUG_OBJECT (trans, "Have fixed output caps %"
+          GST_PTR_FORMAT " to apply to buffer with no caps", out_caps);
+      if (gst_buffer_is_writable (input)) {
+        gst_buffer_ref (input);
+        *buf = input;
+      } else {
+        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
+        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
+      }
+      GST_BUFFER_CAPS (input) = out_caps;
+
+      if (GST_PAD_CAPS (trans->srcpad) == NULL)
+        gst_pad_set_caps (trans->srcpad, out_caps);
+    } else {
+      gst_caps_unref (out_caps);
+    }
   }
 
-  return GST_FLOW_OK;
+  return GST_BASE_TRANSFORM_CLASS (parent_class)->
+      prepare_output_buffer (trans, input, size, caps, buf);
 }
index c20fce9..83974a9 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "config.h"
 #include <gst/check/gstcheck.h>
-#include <gst/controller/gst-controller.h>
+#include <gst/controller/gstcontroller.h>
 
 /* LOCAL TEST ELEMENT */