plugins/elements/gstcapsfilter.c: The caps intersection algorithm can produce multipl...
authorJan Schmidt <thaytan@mad.scientist.com>
Thu, 18 May 2006 09:07:55 +0000 (09:07 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Thu, 18 May 2006 09:07:55 +0000 (09:07 +0000)
Original commit message from CVS:
* plugins/elements/gstcapsfilter.c: (gst_capsfilter_prepare_buf):
The caps intersection algorithm can produce multiple copies of the
caps. Until that is fixed, we need to simplify the result to be
sure whether the allowed caps are fixed or not.
* plugins/elements/gstqueue.c: (gst_queue_init),
(gst_queue_bufferalloc), (gst_queue_acceptcaps),
(gst_queue_push_one):
Proxied buffer alloc should not set the caps on the source pad.
When pushing buffers, we always accept the caps change that triggers.
This prevents negotiation errors caused by caps changing mid-stream
and then being refused on our source pad (because upstream is now
refusing those caps).

ChangeLog
plugins/elements/gstcapsfilter.c
plugins/elements/gstqueue.c

index 375f46b..1703b72 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2006-05-18  Jan Schmidt  <thaytan@mad.scientist.com>
+
+       * plugins/elements/gstcapsfilter.c: (gst_capsfilter_prepare_buf):
+       The caps intersection algorithm can produce multiple copies of the
+       caps. Until that is fixed, we need to simplify the result to be
+       sure whether the allowed caps are fixed or not.
+
+       * plugins/elements/gstqueue.c: (gst_queue_init),
+       (gst_queue_bufferalloc), (gst_queue_acceptcaps),
+       (gst_queue_push_one):
+       Proxied buffer alloc should not set the caps on the source pad.
+       When pushing buffers, we always accept the caps change that triggers.
+       This prevents negotiation errors caused by caps changing mid-stream 
+       and then being refused on our source pad (because upstream is now
+       refusing those caps).
+
 2006-05-18  Tim-Philipp Müller  <tim at centricular dot net>
 
        * tests/examples/helloworld/helloworld.c: (main):
index f8ce429..f01abf7 100644 (file)
@@ -257,6 +257,9 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
       g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
     }
 
+    out_caps = gst_caps_make_writable (out_caps);
+    gst_caps_do_simplify (out_caps);
+
     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);
@@ -272,6 +275,8 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
       if (GST_PAD_CAPS (trans->srcpad) == NULL)
         gst_pad_set_caps (trans->srcpad, out_caps);
     } else {
+      GST_DEBUG_OBJECT (trans, "Have unfixed output caps %" GST_PTR_FORMAT,
+          out_caps);
       gst_caps_unref (out_caps);
     }
   }
index b399f07..8b7c4ff 100644 (file)
@@ -146,6 +146,7 @@ static void gst_queue_get_property (GObject * object,
 static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
 static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset,
     guint size, GstCaps * caps, GstBuffer ** buf);
+static gboolean gst_queue_acceptcaps (GstPad * pad, GstCaps * caps);
 static gboolean gst_queue_push_one (GstQueue * queue);
 static void gst_queue_loop (GstPad * pad);
 
@@ -357,6 +358,8 @@ gst_queue_init (GstQueue * queue)
       GST_DEBUG_FUNCPTR (gst_queue_src_activate_push));
   gst_pad_set_link_function (queue->srcpad,
       GST_DEBUG_FUNCPTR (gst_queue_link_src));
+  gst_pad_set_acceptcaps_function (queue->srcpad,
+      GST_DEBUG_FUNCPTR (gst_queue_acceptcaps));
   gst_pad_set_getcaps_function (queue->srcpad,
       GST_DEBUG_FUNCPTR (gst_queue_getcaps));
   gst_pad_set_event_function (queue->srcpad,
@@ -476,13 +479,19 @@ gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
 
   queue = GST_QUEUE (GST_PAD_PARENT (pad));
 
-  result =
-      gst_pad_alloc_buffer_and_set_caps (queue->srcpad, offset, size, caps,
-      buf);
+  /* Forward to src pad, without setting caps on the src pad */
+  result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf);
 
   return result;
 }
 
+static gboolean
+gst_queue_acceptcaps (GstPad * pad, GstCaps * caps)
+{
+  /* The only time our acceptcaps method should be called is on the srcpad
+   * when we push a buffer, in which case we always accept those caps */
+  return TRUE;
+}
 
 static void
 gst_queue_locked_flush (GstQueue * queue)
@@ -767,6 +776,11 @@ gst_queue_push_one (GstQueue * queue)
       queue->cur_level.time -= GST_BUFFER_DURATION (data);
 
     GST_QUEUE_MUTEX_UNLOCK (queue);
+    /* Set caps on the src pad first, because otherwise when we push it will
+     * check that we accept the caps which checks upstream, whereas 
+     * explicitly setting the caps doesn't */
+    gst_pad_set_caps (queue->srcpad, GST_BUFFER_CAPS (data));
+
     result = gst_pad_push (queue->srcpad, GST_BUFFER (data));
     /* need to check for srcresult here as well */
     GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);