Index: gstcapsfilter.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/plugins/elements/gstcapsfilter.c,v
retrieving revision 1.24
diff -u -p -r1.24 gstcapsfilter.c
--- gstcapsfilter.c	16 Sep 2006 21:38:09 -0000	1.24
+++ gstcapsfilter.c	13 Oct 2006 08:40:22 -0000
@@ -205,14 +205,83 @@ gst_capsfilter_dispose (GObject * object
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
+static gboolean
+foreach_field_exists_in_other (GQuark field_id, const GValue * val,
+    gpointer data)
+{
+  const GstStructure * other_s;
+
+  other_s = (const GstStructure *) data;
+
+  /* don't compare value types, there could be lists, ranges, arrays etc. */
+  return (gst_structure_id_get_value (other_s, field_id) != NULL);
+}
+
+static gboolean
+is_structure_compatible_with_filter_struct (const GstStructure * s,
+    const GstStructure * filter_s)
+{
+  if (gst_structure_get_name_id (s) != gst_structure_get_name_id (filter_s))
+    return FALSE;
+
+  /* every field from filter_s must be in s for it to be compatible; if
+   * someone specified a field in a filter_caps structure it is not
+   * optional, but required */
+  return gst_structure_foreach (filter_s, foreach_field_exists_in_other,
+      (gpointer) s);
+}
+
+static gboolean
+is_structure_compatible_with_filter_caps (const GstStructure * s,
+    const GstCaps * filter_caps)
+{
+  gint i, num;
+
+  if (gst_caps_is_any (filter_caps))
+    return TRUE;
+
+  num = gst_caps_get_size (filter_caps);
+  for (i = 0; i < num; ++i) {
+    const GstStructure *filter_s;
+
+    filter_s = gst_caps_get_structure (filter_caps, i);
+    if (is_structure_compatible_with_filter_struct (s, filter_s))
+      return TRUE;
+  }
+
+  return FALSE;
+}
+
+
 static GstCaps *
 gst_capsfilter_transform_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps)
 {
   GstCapsFilter *capsfilter = GST_CAPSFILTER (base);
-  GstCaps *ret;
+  GstCaps *copy, *ret;
+
+  copy = gst_caps_copy (caps);
+
+  if (copy != NULL && !gst_caps_is_any (copy) && !gst_caps_is_empty (copy)) {
+    gint i;
+
+    for (i = 0; i < gst_caps_get_size (copy); ++i) {
+      const GstStructure *allowed_structure;
+
+      allowed_structure = gst_caps_get_structure (copy, i);
+      if (!is_structure_compatible_with_filter_caps (allowed_structure,
+          capsfilter->filter_caps)) {
+        GST_DEBUG_OBJECT (capsfilter, "structure %" GST_PTR_FORMAT " not "
+            "strictly compatible with filter caps %" GST_PTR_FORMAT,
+            allowed_structure, capsfilter->filter_caps);
+        gst_caps_remove_structure (copy, i);
+        --i; /* to offset the ++i to follow from the loop */
+      }
+    }
+  }
 
-  ret = gst_caps_intersect (caps, capsfilter->filter_caps);
+  ret = gst_caps_intersect (copy, capsfilter->filter_caps);
+  gst_caps_unref (copy);
 
   return ret;
 }
