capsfeatures: Add GST_CAPS_FEATURES_ANY
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 2 Apr 2013 20:13:22 +0000 (22:13 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Tue, 2 Apr 2013 20:17:22 +0000 (22:17 +0200)
This is equal to any other caps features but results in unfixed caps. It
would be used by elements that only look at the buffer metadata or are
currently working in passthrough mode, and as such don't care about any
specific features.

docs/gst/gstreamer-sections.txt
gst/gstcaps.c
gst/gstcapsfeatures.c
gst/gstcapsfeatures.h
tests/check/gst/gstcapsfeatures.c

index d743b48..5183a12 100644 (file)
@@ -459,6 +459,7 @@ gst_caps_intersect_mode_get_type
 GstCapsFeatures
 gst_caps_features_new
 gst_caps_features_new_empty
+gst_caps_features_new_any
 gst_caps_features_new_id
 gst_caps_features_new_id_valist
 gst_caps_features_new_valist
@@ -472,6 +473,7 @@ gst_caps_features_to_string
 gst_caps_features_set_parent_refcount
 
 gst_caps_features_is_equal
+gst_caps_features_is_any
 
 gst_caps_features_contains
 gst_caps_features_contains_id
index 0e8c798..aaa1131 100644 (file)
@@ -1075,12 +1075,17 @@ gboolean
 gst_caps_is_fixed (const GstCaps * caps)
 {
   GstStructure *structure;
+  GstCapsFeatures *features;
 
   g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
 
   if (GST_CAPS_LEN (caps) != 1)
     return FALSE;
 
+  features = gst_caps_get_features (caps, 0);
+  if (features && gst_caps_features_is_any (features))
+    return FALSE;
+
   structure = gst_caps_get_structure_unchecked (caps, 0);
 
   return gst_structure_foreach (structure, gst_caps_is_fixed_foreach, NULL);
index 3a50254..56cd2d9 100644 (file)
@@ -55,9 +55,11 @@ struct _GstCapsFeatures
   GType type;
   gint *parent_refcount;
   GArray *array;
+  gboolean is_any;
 };
 
 GType _gst_caps_features_type = 0;
+GstCapsFeatures *_gst_caps_features_any = NULL;
 GstCapsFeatures *_gst_caps_features_memory_system_memory = NULL;
 static GQuark _gst_caps_feature_memory_system_memory = 0;
 
@@ -82,6 +84,7 @@ _priv_gst_caps_features_initialize (void)
   g_value_register_transform_func (_gst_caps_features_type, G_TYPE_STRING,
       gst_caps_features_transform_to_string);
 
+  _gst_caps_features_any = gst_caps_features_new_any ();
   _gst_caps_features_memory_system_memory =
       gst_caps_features_new_id (_gst_caps_feature_memory_system_memory, 0);
 
@@ -148,6 +151,7 @@ gst_caps_features_new_empty (void)
   features->type = _gst_caps_features_type;
   features->parent_refcount = NULL;
   features->array = g_array_new (FALSE, FALSE, sizeof (GQuark));
+  features->is_any = FALSE;
 
   GST_TRACE ("created caps features %p", features);
 
@@ -155,6 +159,28 @@ gst_caps_features_new_empty (void)
 }
 
 /**
+ * gst_caps_features_new_any:
+ *
+ * Creates a new, ANY #GstCapsFeatures. This will be equal
+ * to any other #GstCapsFeatures but caps with these are
+ * unfixed.
+ *
+ * Free-function: gst_caps_features_free
+ *
+ * Returns: (transfer full): a new, ANY #GstCapsFeatures
+ */
+GstCapsFeatures *
+gst_caps_features_new_any (void)
+{
+  GstCapsFeatures *features;
+
+  features = gst_caps_features_new_empty ();
+  features->is_any = TRUE;
+
+  return features;
+}
+
+/**
  * gst_caps_features_new:
  * @feature1: name of first feature to set
  * @...: additional features
@@ -388,6 +414,11 @@ priv_gst_caps_features_append_to_gstring (const GstCapsFeatures * features,
 
   g_return_if_fail (features != NULL);
 
+  if (features->array->len == 0 && features->is_any) {
+    g_string_append (s, "ANY");
+    return;
+  }
+
   n = features->array->len;
   for (i = 0; i < n; i++) {
     GQuark *quark = &g_array_index (features->array, GQuark, i);
@@ -422,6 +453,11 @@ gst_caps_features_from_string (const gchar * features)
   if (!features || *features == '\0')
     return ret;
 
+  if (strcmp (features, "ANY") == 0) {
+    ret->is_any = TRUE;
+    return ret;
+  }
+
   /* Skip trailing spaces */
   while (*features == ' ')
     features++;
@@ -582,6 +618,9 @@ gst_caps_features_contains_id (const GstCapsFeatures * features, GQuark feature)
   g_return_val_if_fail (features != NULL, FALSE);
   g_return_val_if_fail (feature != 0, FALSE);
 
+  if (features->is_any)
+    return TRUE;
+
   n = features->array->len;
   if (n == 0)
     return feature == _gst_caps_feature_memory_system_memory;
@@ -612,6 +651,9 @@ gst_caps_features_is_equal (const GstCapsFeatures * features1,
   g_return_val_if_fail (features1 != NULL, FALSE);
   g_return_val_if_fail (features2 != NULL, FALSE);
 
+  if (features1->is_any || features2->is_any)
+    return TRUE;
+
   /* Check for the sysmem==empty case */
   if (features1->array->len == 0 && features2->array->len == 0)
     return TRUE;
@@ -637,6 +679,22 @@ gst_caps_features_is_equal (const GstCapsFeatures * features1,
 }
 
 /**
+ * gst_caps_features_is_any:
+ * @features: a #GstCapsFeatures.
+ *
+ * Returns %TRUE if @features is %GST_CAPS_FEATURES_ANY.
+ *
+ * Returns: %TRUE if @features is %GST_CAPS_FEATURES_ANY.
+ */
+gboolean
+gst_caps_features_is_any (const GstCapsFeatures * features)
+{
+  g_return_val_if_fail (features != NULL, FALSE);
+
+  return features->is_any;
+}
+
+/**
  * gst_caps_features_add:
  * @features: a #GstCapsFeatures.
  * @feature: a feature.
@@ -649,6 +707,7 @@ gst_caps_features_add (GstCapsFeatures * features, const gchar * feature)
   g_return_if_fail (features != NULL);
   g_return_if_fail (IS_MUTABLE (features));
   g_return_if_fail (feature != NULL);
+  g_return_if_fail (!features->is_any);
 
   gst_caps_features_add_id (features, g_quark_from_string (feature));
 }
@@ -666,6 +725,7 @@ gst_caps_features_add_id (GstCapsFeatures * features, GQuark feature)
   g_return_if_fail (features != NULL);
   g_return_if_fail (IS_MUTABLE (features));
   g_return_if_fail (feature != 0);
+  g_return_if_fail (!features->is_any);
 
   if (!gst_caps_feature_name_is_valid (g_quark_to_string (feature))) {
     g_warning ("Invalid caps feature name: %s", g_quark_to_string (feature));
index cb0359c..62d9e3c 100644 (file)
@@ -35,6 +35,9 @@ typedef struct _GstCapsFeatures GstCapsFeatures;
 
 #define GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY "memory:SystemMemory"
 
+GST_EXPORT GstCapsFeatures *_gst_caps_features_any;
+#define GST_CAPS_FEATURES_ANY (_gst_caps_features_any)
+
 GST_EXPORT GstCapsFeatures *_gst_caps_features_memory_system_memory;
 #define GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY (_gst_caps_features_memory_system_memory)
 
@@ -42,6 +45,7 @@ GType             gst_caps_features_get_type (void);
 gboolean          gst_is_caps_features (gconstpointer obj);
 
 GstCapsFeatures * gst_caps_features_new_empty (void);
+GstCapsFeatures * gst_caps_features_new_any (void);
 GstCapsFeatures * gst_caps_features_new (const gchar *feature1, ...);
 GstCapsFeatures * gst_caps_features_new_valist (const gchar *feature1, va_list varargs);
 GstCapsFeatures * gst_caps_features_new_id (GQuark feature1, ...);
@@ -63,6 +67,8 @@ gboolean          gst_caps_features_contains (const GstCapsFeatures * features,
 gboolean          gst_caps_features_contains_id (const GstCapsFeatures * features, GQuark feature);
 gboolean          gst_caps_features_is_equal (const GstCapsFeatures * features1, const GstCapsFeatures * features2);
 
+gboolean          gst_caps_features_is_any (const GstCapsFeatures * features);
+
 void              gst_caps_features_add (GstCapsFeatures * features, const gchar * feature);
 void              gst_caps_features_add_id ( GstCapsFeatures * features, GQuark feature);
 
index 0c4b04e..5f76aa7 100644 (file)
@@ -77,6 +77,20 @@ GST_START_TEST (test_from_to_string)
   gst_caps_features_free (a);
   gst_caps_features_free (b);
   g_free (str);
+
+  a = gst_caps_features_new_any ();
+  fail_unless (a != NULL);
+  fail_unless (gst_caps_features_is_any (a));
+  str = gst_caps_features_to_string (a);
+  fail_unless (str != NULL);
+  fail_unless_equals_string (str, "ANY");
+  b = gst_caps_features_from_string (str);
+  fail_unless (b != NULL);
+  fail_unless (gst_caps_features_is_equal (a, b));
+  fail_unless (gst_caps_features_is_any (b));
+  gst_caps_features_free (a);
+  gst_caps_features_free (b);
+  g_free (str);
 }
 
 GST_END_TEST;