#define CAPS_IS_EMPTY_SIMPLE(caps) \
((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
-#define gst_caps_features_copy_conditional(f) ((f && !gst_caps_features_is_equal (f, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) ? gst_caps_features_copy (f) : NULL)
+#define gst_caps_features_copy_conditional(f) ((f && (gst_caps_features_is_any (f) || !gst_caps_features_is_equal (f, GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) ? gst_caps_features_copy (f) : NULL)
/* quick way to get a caps structure at an index without doing a type or array
* length check */
/* quick way to append a structure without checking the args */
#define gst_caps_append_structure_unchecked(caps, s, f) G_STMT_START{\
GstCapsArrayElement __e={s, f}; \
- if (__e.features && gst_caps_features_is_equal (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY, __e.features)) { \
- gst_caps_features_free (__e.features); \
- __e.features = NULL; \
- } \
if (gst_structure_set_parent_refcount (__e.structure, &GST_MINI_OBJECT_REFCOUNT(caps)) && \
(!__e.features || gst_caps_features_set_parent_refcount (__e.features, &GST_MINI_OBJECT_REFCOUNT(caps)))) \
g_array_append_val (GST_CAPS_ARRAY (caps), __e); \
*
* Appends @structure with @features to @caps. The structure is not copied; @caps
* becomes the owner of @structure.
+ *
+ * Since: 1.2
*/
void
gst_caps_append_structure_full (GstCaps * caps, GstStructure * structure,
/* if structure is a subset of structure1 and the
* there are no existing features, then skip it */
- if (gst_structure_is_subset (structure, structure1) &&
- gst_caps_features_is_equal (features1,
- GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) {
+ if (gst_caps_features_is_equal (features1,
+ GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)
+ && gst_structure_is_subset (structure, structure1)) {
unique = FALSE;
break;
}
* Appends @structure with @features to @caps if its not already expressed by @caps.
*
* Returns: (transfer full): the merged caps.
+ *
+ * Since: 1.2
*/
GstCaps *
gst_caps_merge_structure_full (GstCaps * caps, GstStructure * structure,
features1 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
/* if structure is a subset of structure1 and the
* the features are a subset, then skip it */
- if (gst_structure_is_subset (structure, structure1) &&
- gst_caps_features_is_equal (features_tmp, features1)) {
+ /* FIXME: We only skip if none of the features are
+ * ANY and are still equal. That way all ANY structures
+ * show up in the caps and no non-ANY structures are
+ * swallowed by ANY structures
+ */
+ if (((!gst_caps_features_is_any (features_tmp)
+ || gst_caps_features_is_any (features1))
+ && gst_caps_features_is_equal (features_tmp, features1))
+ && gst_structure_is_subset (structure, structure1)) {
unique = FALSE;
break;
}
*
* Returns: (transfer none): a pointer to the #GstCapsFeatures corresponding
* to @index
+ *
+ * Since: 1.2
*/
GstCapsFeatures *
gst_caps_get_features (const GstCaps * caps, guint index)
features = gst_caps_get_features_unchecked (caps, index);
if (!features)
- features = gst_caps_features_copy (GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY);
+ features = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
return features;
}
* @features: (allow-none) (transfer full): the #GstFeatures to set
*
* Sets the #GstCapsFeatures @features for the structure at @index.
+ *
+ * Since: 1.2
*/
void
gst_caps_set_features (GstCaps * caps, guint index, GstCapsFeatures * features)
storage = &gst_caps_get_features_unchecked (caps, index);
old = *storage;
*storage = features;
+
+ if (features)
+ gst_caps_features_set_parent_refcount (features, &GST_CAPS_REFCOUNT (caps));
+
if (old)
gst_caps_features_free (old);
}
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);
* @superset: a potentially greater #GstCaps
*
* Checks if all caps represented by @subset are also represented by @superset.
- * <note>This function does not work reliably if optional properties for caps
- * are included on one caps and omitted on the other.</note>
*
* Returns: %TRUE if @subset is a subset of @superset
*/
f2 = gst_caps_get_features_unchecked (superset, j);
if (!f2)
f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
- if (gst_structure_is_subset (s1, s2) &&
- gst_caps_features_is_equal (f1, f2)) {
+ if ((!gst_caps_features_is_any (f1) || gst_caps_features_is_any (f2)) &&
+ gst_caps_features_is_equal (f1, f2)
+ && gst_structure_is_subset (s1, s2)) {
/* If we found a superset, continue with the next
* subset structure */
break;
* for more information.
*
* Returns: %TRUE if @structure is a subset of @caps
+ *
+ * Since: 1.2
*/
gboolean
gst_caps_is_subset_structure_full (const GstCaps * caps,
f = gst_caps_get_features_unchecked (caps, i);
if (!f)
f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
- if (gst_structure_is_subset (structure, s) &&
- gst_caps_features_is_equal (features, f)) {
+ if ((!gst_caps_features_is_any (features) || gst_caps_features_is_any (f))
+ && gst_caps_features_is_equal (features, f)
+ && gst_structure_is_subset (structure, s)) {
/* If we found a superset return TRUE */
return TRUE;
}
* @caps2: another #GstCaps
*
* Checks if the given caps represent the same set of caps.
- * <note>This function does not work reliably if optional properties for caps
- * are included on one caps and omitted on the other.</note>
*
* Returns: TRUE if both caps are equal.
*/
if (!f2)
f2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
- if (!gst_structure_is_equal (s1, s2)
- || !gst_caps_features_is_equal (f1, f2))
+ if (gst_caps_features_is_any (f1) != gst_caps_features_is_any (f2) ||
+ !gst_caps_features_is_equal (f1, f2) ||
+ !gst_structure_is_equal (s1, s2))
return FALSE;
}
features2 = gst_caps_get_features_unchecked (caps2, k);
if (!features2)
features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
- if (gst_structure_can_intersect (struct1, struct2) &&
- gst_caps_features_is_equal (features1, features2)) {
+ if (gst_caps_features_is_equal (features1, features2) &&
+ gst_structure_can_intersect (struct1, struct2)) {
return TRUE;
}
/* move down left */
features2 = gst_caps_get_features_unchecked (caps2, k);
if (!features2)
features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
- istruct = gst_structure_intersect (struct1, struct2);
- if (istruct && gst_caps_features_is_equal (features1, features2))
- dest =
- gst_caps_merge_structure_full (dest, istruct,
- gst_caps_features_copy_conditional (features1));
+ if (gst_caps_features_is_equal (features1, features2)) {
+ istruct = gst_structure_intersect (struct1, struct2);
+ if (istruct) {
+ if (gst_caps_features_is_any (features1))
+ dest =
+ gst_caps_merge_structure_full (dest, istruct,
+ gst_caps_features_copy_conditional (features2));
+ else
+ dest =
+ gst_caps_merge_structure_full (dest, istruct,
+ gst_caps_features_copy_conditional (features1));
+ }
+ }
/* move down left */
k++;
if (G_UNLIKELY (j == 0))
features2 = gst_caps_get_features_unchecked (caps2, j);
if (!features2)
features2 = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
- istruct = gst_structure_intersect (struct1, struct2);
- if (istruct && gst_caps_features_is_equal (features1, features2))
- dest = gst_caps_merge_structure (dest, istruct);
+ if (gst_caps_features_is_equal (features1, features2)) {
+ istruct = gst_structure_intersect (struct1, struct2);
+ if (istruct) {
+ if (gst_caps_features_is_any (features1))
+ dest =
+ gst_caps_merge_structure_full (dest, istruct,
+ gst_caps_features_copy_conditional (features2));
+ else
+ dest =
+ gst_caps_merge_structure_full (dest, istruct,
+ gst_caps_features_copy_conditional (features1));
+ }
+ }
}
}
min_f = gst_caps_get_features_unchecked (src, j);
if (!min_f)
min_f = GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY;
+
+ /* Same reason as above for ANY caps */
+ g_return_val_if_fail (!gst_caps_features_is_any (min_f), NULL);
+
if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub) &&
gst_caps_features_is_equal (min_f, sub_f)) {
GSList *list;
gst_caps_fixate (GstCaps * caps)
{
GstStructure *s;
+ GstCapsFeatures *f;
g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
s = gst_caps_get_structure (caps, 0);
gst_structure_fixate (s);
+ /* Set features to sysmem if they're still ANY */
+ f = gst_caps_get_features (caps, 0);
+ if (f && gst_caps_features_is_any (f)) {
+ f = gst_caps_features_new_empty ();
+ gst_caps_set_features (caps, 0, f);
+ }
+
return caps;
}
features = gst_caps_get_features_unchecked (caps, i);
g_string_append (s, gst_structure_get_name (structure));
- if (features
- && !gst_caps_features_is_equal (features,
- GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) {
+ if (features && (gst_caps_features_is_any (features)
+ || !gst_caps_features_is_equal (features,
+ GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))) {
g_string_append_c (s, '(');
priv_gst_caps_features_append_to_gstring (features, s);
g_string_append_c (s, ')');