* <title>Creating caps</title>
* <programlisting>
* GstCaps *caps;
- * caps = gst_caps_new_simple ("video/x-raw-yuv",
- * "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
+ * caps = gst_caps_new_simple ("video/x-raw",
+ * "format", G_TYPE_STRING, "I420"),
* "framerate", GST_TYPE_FRACTION, 25, 1,
* "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
* "width", G_TYPE_INT, 320,
#define DEBUG_REFCOUNT
+
+#define GST_CAPS_ARRAY(c) ((GPtrArray *)((c)->priv))
+
+#define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
+
#define IS_WRITABLE(caps) \
(GST_CAPS_REFCOUNT_VALUE (caps) == 1)
(!CAPS_IS_ANY(caps) && CAPS_IS_EMPTY_SIMPLE(caps))
#define CAPS_IS_EMPTY_SIMPLE(caps) \
- (((caps)->structs == NULL) || ((caps)->structs->len == 0))
+ ((GST_CAPS_ARRAY (caps) == NULL) || (GST_CAPS_LEN (caps) == 0))
/* quick way to get a caps structure at an index without doing a type or array
* length check */
#define gst_caps_get_structure_unchecked(caps, index) \
- ((GstStructure *)g_ptr_array_index ((caps)->structs, (index)))
+ ((GstStructure *)g_ptr_array_index (GST_CAPS_ARRAY (caps), (index)))
/* quick way to append a structure without checking the args */
#define gst_caps_append_structure_unchecked(caps, structure) G_STMT_START{\
GstStructure *__s=structure; \
- gst_structure_set_parent_refcount (__s, &GST_MINI_OBJECT_REFCOUNT(caps)); \
- g_ptr_array_add (caps->structs, __s); \
+ if (gst_structure_set_parent_refcount (__s, &GST_MINI_OBJECT_REFCOUNT(caps))) \
+ g_ptr_array_add (GST_CAPS_ARRAY (caps), __s); \
}G_STMT_END
/* lock to protect multiple invocations of static caps to caps conversion */
GType _gst_caps_type = 0;
+GST_DEFINE_MINI_OBJECT_TYPE (GstCaps, gst_caps);
+
void
-_gst_caps_initialize (void)
+_priv_gst_caps_initialize (void)
{
- if (G_LIKELY (_gst_caps_type == 0)) {
- _gst_caps_type = gst_mini_object_register ("GstCaps");
+ _gst_caps_type = gst_caps_get_type ();
- g_value_register_transform_func (_gst_caps_type,
- G_TYPE_STRING, gst_caps_transform_to_string);
- }
+ g_value_register_transform_func (_gst_caps_type,
+ G_TYPE_STRING, gst_caps_transform_to_string);
}
static GstCaps *
newcaps = gst_caps_new_empty ();
GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
- n = caps->structs->len;
+ n = GST_CAPS_LEN (caps);
for (i = 0; i < n; i++) {
structure = gst_caps_get_structure_unchecked (caps, i);
/* The refcount must be 0, but since we're only called by gst_caps_unref,
* don't bother testing. */
- len = caps->structs->len;
+ len = GST_CAPS_LEN (caps);
/* This can be used to get statistics about caps sizes */
/*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
for (i = 0; i < len; i++) {
gst_structure_set_parent_refcount (structure, NULL);
gst_structure_free (structure);
}
- g_ptr_array_free (caps->structs, TRUE);
+ g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE);
#ifdef DEBUG_REFCOUNT
GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
/* the 32 has been determined by logging caps sizes in _gst_caps_free
* but g_ptr_array uses 16 anyway if it expands once, so this does not help
* in practise
- * caps->structs = g_ptr_array_sized_new (32);
+ * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
*/
- caps->structs = g_ptr_array_new ();
+ caps->priv = g_ptr_array_new ();
}
/**
return caps;
}
-/**
- * gst_caps_make_writable:
- * @caps: (transfer full): the #GstCaps to make writable
- *
- * Returns a writable copy of @caps.
- *
- * If there is only one reference count on @caps, the caller must be the owner,
- * and so this function will return the caps object unchanged. If on the other
- * hand there is more than one reference on the object, a new caps object will
- * be returned. The caller's reference on @caps will be removed, and instead the
- * caller will own a reference to the returned object.
- *
- * In short, this function unrefs the caps in the argument and refs the caps
- * that it returns. Don't access the argument after calling this function. See
- * also: gst_caps_ref().
- *
- * Returns: (transfer full): the same #GstCaps object.
- */
-GstCaps *
-gst_caps_make_writable (GstCaps * caps)
-{
- GstCaps *copy;
-
- g_return_val_if_fail (caps != NULL, NULL);
-
- /* we are the only instance reffing this caps */
- if (IS_WRITABLE (caps))
- return caps;
-
- /* else copy */
- GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy caps");
- copy = _gst_caps_copy (caps);
- gst_caps_unref (caps);
-
- return copy;
-}
-
GType
gst_static_caps_get_type (void)
{
gst_caps_init (caps, sizeof (GstCaps));
/* now copy stuff over to the real caps. */
GST_CAPS_FLAGS (caps) = GST_CAPS_FLAGS (&temp);
- caps->structs = temp.structs;
+ caps->priv = GST_CAPS_ARRAY (&temp);
GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps);
done:
}
}
+/**
+ * gst_static_caps_cleanup:
+ * @static_caps: the #GstStaticCaps to convert
+ *
+ * Clean up the caps contained in @static_caps when the refcount is 0.
+ */
+void
+gst_static_caps_cleanup (GstStaticCaps * static_caps)
+{
+ GstCaps *caps = (GstCaps *) static_caps;
+
+ /* FIXME: this is not threadsafe */
+ if (GST_CAPS_REFCOUNT_VALUE (caps) == 1) {
+ GstStructure *structure;
+ guint i, clen;
+
+ clen = GST_CAPS_LEN (caps);
+
+ for (i = 0; i < clen; i++) {
+ structure = (GstStructure *) gst_caps_get_structure (caps, i);
+ gst_structure_set_parent_refcount (structure, NULL);
+ gst_structure_free (structure);
+ }
+ g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE);
+ GST_CAPS_REFCOUNT (caps) = 0;
+ }
+}
+
/* manipulation */
static GstStructure *
gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
{
/* don't use index_fast, gst_caps_do_simplify relies on the order */
- GstStructure *s = g_ptr_array_remove_index (caps->structs, idx);
+ GstStructure *s = g_ptr_array_remove_index (GST_CAPS_ARRAY (caps), idx);
gst_structure_set_parent_refcount (s, NULL);
return s;
g_return_val_if_fail (caps != NULL, NULL);
g_return_val_if_fail (IS_WRITABLE (caps), NULL);
- if (G_UNLIKELY (index >= caps->structs->len))
+ if (G_UNLIKELY (index >= GST_CAPS_LEN (caps)))
return NULL;
return gst_caps_remove_and_get_structure (caps, index);
}
-static gboolean
-gst_structure_is_equal_foreach (GQuark field_id, const GValue * val2,
- gpointer data)
-{
- GstStructure *struct1 = (GstStructure *) data;
- const GValue *val1 = gst_structure_id_get_value (struct1, field_id);
-
- if (G_UNLIKELY (val1 == NULL))
- return FALSE;
- if (gst_value_compare (val1, val2) == GST_VALUE_EQUAL) {
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
- gpointer user_data)
-{
- GstStructure *subtract_from = user_data;
- GValue subtraction = { 0, };
- const GValue *other;
-
- if (!(other = gst_structure_id_get_value (subtract_from, field_id)))
- /* field is missing in one set */
- return FALSE;
-
- /* equal values are subset */
- if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
- return TRUE;
-
- /*
- * 1 - [1,2] = empty
- * -> !subset
- *
- * [1,2] - 1 = 2
- * -> 1 - [1,2] = empty
- * -> subset
- *
- * [1,3] - [1,2] = 3
- * -> [1,2] - [1,3] = empty
- * -> subset
- *
- * {1,2} - {1,3} = 2
- * -> {1,3} - {1,2} = 3
- * -> !subset
- *
- * First caps subtraction needs to return a non-empty set, second
- * subtractions needs to give en empty set.
- */
- if (gst_value_subtract (&subtraction, other, value)) {
- g_value_unset (&subtraction);
- /* !empty result, swapping must be empty */
- if (!gst_value_subtract (&subtraction, value, other))
- return TRUE;
-
- g_value_unset (&subtraction);
- }
- return FALSE;
-}
-
-static gboolean
-gst_caps_structure_is_subset (const GstStructure * minuend,
- const GstStructure * subtrahend)
-{
- if ((minuend->name != subtrahend->name) ||
- (gst_structure_n_fields (minuend) !=
- gst_structure_n_fields (subtrahend))) {
- return FALSE;
- }
-
- return gst_structure_foreach ((GstStructure *) subtrahend,
- gst_caps_structure_is_subset_field, (gpointer) minuend);
-}
-
/**
* gst_caps_append:
* @caps1: the #GstCaps that will be appended to
if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
/* FIXME: this leaks */
GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAGS_ANY;
- for (i = caps2->structs->len - 1; i >= 0; i--) {
+ for (i = GST_CAPS_LEN (caps2) - 1; i >= 0; i--) {
structure = gst_caps_remove_and_get_structure (caps2, i);
gst_structure_free (structure);
}
} else {
- for (i = caps2->structs->len; i; i--) {
+ for (i = GST_CAPS_LEN (caps2); i; i--) {
structure = gst_caps_remove_and_get_structure (caps2, 0);
gst_caps_append_structure_unchecked (caps1, structure);
}
g_return_if_fail (IS_WRITABLE (caps2));
if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
- for (i = caps2->structs->len - 1; i >= 0; i--) {
+ for (i = GST_CAPS_LEN (caps2) - 1; i >= 0; i--) {
structure = gst_caps_remove_and_get_structure (caps2, i);
gst_structure_free (structure);
}
} else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAGS_ANY;
- for (i = caps1->structs->len - 1; i >= 0; i--) {
+ for (i = GST_CAPS_LEN (caps1) - 1; i >= 0; i--) {
structure = gst_caps_remove_and_get_structure (caps1, i);
gst_structure_free (structure);
}
} else {
- for (i = caps2->structs->len; i; i--) {
+ for (i = GST_CAPS_LEN (caps2); i; i--) {
structure = gst_caps_remove_and_get_structure (caps2, 0);
gst_caps_merge_structure (caps1, structure);
}
g_return_if_fail (IS_WRITABLE (caps));
if (G_LIKELY (structure)) {
- g_return_if_fail (structure->parent_refcount == NULL);
gst_caps_append_structure_unchecked (caps, structure);
}
}
/**
* gst_caps_merge_structure:
- * @caps: the #GstCaps that will the the new structure
+ * @caps: the #GstCaps that will the new structure
* @structure: (transfer full): the #GstStructure to merge
*
* Appends @structure to @caps if its not already expressed by @caps. The
int i;
gboolean unique = TRUE;
- g_return_if_fail (structure->parent_refcount == NULL);
/* check each structure */
- for (i = caps->structs->len - 1; i >= 0; i--) {
+ for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
structure1 = gst_caps_get_structure_unchecked (caps, i);
/* if structure is a subset of structure1, then skip it */
- if (gst_caps_structure_is_subset (structure1, structure)) {
+ if (gst_structure_is_subset (structure, structure1)) {
unique = FALSE;
break;
}
{
g_return_val_if_fail (GST_IS_CAPS (caps), 0);
- return caps->structs->len;
+ return GST_CAPS_LEN (caps);
}
/**
gst_caps_get_structure (const GstCaps * caps, guint index)
{
g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
- g_return_val_if_fail (index < caps->structs->len, NULL);
+ g_return_val_if_fail (index < GST_CAPS_LEN (caps), NULL);
return gst_caps_get_structure_unchecked (caps, index);
}
newcaps = gst_caps_new_empty ();
GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
- if (G_LIKELY (caps->structs->len > nth)) {
+ if (G_LIKELY (GST_CAPS_LEN (caps) > nth)) {
structure = gst_caps_get_structure_unchecked (caps, nth);
gst_caps_append_structure_unchecked (newcaps,
gst_structure_copy (structure));
g_return_if_fail (GST_IS_CAPS (caps));
g_return_if_fail (IS_WRITABLE (caps));
- i = caps->structs->len - 1;
+ i = GST_CAPS_LEN (caps) - 1;
while (i > 0)
gst_caps_remove_structure (caps, i--);
g_return_if_fail (field != NULL);
g_return_if_fail (G_IS_VALUE (value));
- len = caps->structs->len;
+ len = GST_CAPS_LEN (caps);
for (i = 0; i < len; i++) {
GstStructure *structure = gst_caps_get_structure_unchecked (caps, i);
gst_structure_set_value (structure, field, value);
g_warning ("Don't use G_TYPE_DATE, use GST_TYPE_DATE instead\n");
type = GST_TYPE_DATE;
}
-#if GLIB_CHECK_VERSION(2,23,3)
G_VALUE_COLLECT_INIT (&value, type, varargs, 0, &err);
-#else
- g_value_init (&value, type);
- G_VALUE_COLLECT (&value, varargs, 0, &err);
-#endif
if (G_UNLIKELY (err)) {
g_critical ("%s", err);
return;
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
- if (caps->structs->len != 1)
+ if (GST_CAPS_LEN (caps) != 1)
return FALSE;
structure = gst_caps_get_structure_unchecked (caps, 0);
struct1 = gst_caps_get_structure_unchecked (caps1, 0);
struct2 = gst_caps_get_structure_unchecked (caps2, 0);
- if (struct1->name != struct2->name) {
- return FALSE;
- }
- if (struct1->fields->len != struct2->fields->len) {
- return FALSE;
- }
-
- return gst_structure_foreach (struct1, gst_structure_is_equal_foreach,
- struct2);
+ return gst_structure_is_equal (struct1, struct2);
}
/**
gboolean
gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
{
- GstCaps *caps;
- gboolean ret;
+ GstStructure *s1, *s2;
+ gboolean ret = TRUE;
+ gint i, j;
g_return_val_if_fail (subset != NULL, FALSE);
g_return_val_if_fail (superset != NULL, FALSE);
if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset))
return FALSE;
- caps = gst_caps_subtract (subset, superset);
- ret = CAPS_IS_EMPTY_SIMPLE (caps);
- gst_caps_unref (caps);
+ for (i = GST_CAPS_LEN (subset) - 1; i >= 0; i--) {
+ for (j = GST_CAPS_LEN (superset) - 1; j >= 0; j--) {
+ s1 = gst_caps_get_structure_unchecked (subset, i);
+ s2 = gst_caps_get_structure_unchecked (superset, j);
+ if (gst_structure_is_subset (s1, s2)) {
+ /* If we found a superset, continue with the next
+ * subset structure */
+ break;
+ }
+ }
+ /* If we found no superset for this subset structure
+ * we return FALSE immediately */
+ if (j == -1) {
+ ret = FALSE;
+ break;
+ }
+ }
+
return ret;
}
/**
+ * gst_caps_is_subset_structure:
+ * @caps: a #GstCaps
+ * @structure: a potential #GstStructure subset of @caps
+ *
+ * Checks if @structure is a subset of @caps. See gst_caps_is_subset()
+ * for more information.
+ *
+ * Returns: %TRUE if @structure is a subset of @caps
+ *
+ * Since: 0.10.35
+ */
+gboolean
+gst_caps_is_subset_structure (const GstCaps * caps,
+ const GstStructure * structure)
+{
+ GstStructure *s;
+ gint i;
+
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (structure != NULL, FALSE);
+
+ if (CAPS_IS_ANY (caps))
+ return TRUE;
+ if (CAPS_IS_EMPTY (caps))
+ return FALSE;
+
+ for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
+ s = gst_caps_get_structure_unchecked (caps, i);
+ if (gst_structure_is_subset (structure, s)) {
+ /* If we found a superset return TRUE */
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
* gst_caps_is_equal:
* @caps1: a #GstCaps
* @caps2: another #GstCaps
/* intersect operation */
-typedef struct
-{
- GstStructure *dest;
- const GstStructure *intersect;
-}
-IntersectData;
-
-static gboolean
-gst_caps_structure_intersect_field1 (GQuark id, const GValue * val1,
- gpointer data)
-{
- IntersectData *idata = (IntersectData *) data;
- const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
-
- if (G_UNLIKELY (val2 == NULL)) {
- gst_structure_id_set_value (idata->dest, id, val1);
- } else {
- GValue dest_value = { 0 };
- if (gst_value_intersect (&dest_value, val1, val2)) {
- gst_structure_id_set_value (idata->dest, id, &dest_value);
- g_value_unset (&dest_value);
- } else {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static gboolean
-gst_caps_structure_intersect_field2 (GQuark id, const GValue * val1,
- gpointer data)
-{
- IntersectData *idata = (IntersectData *) data;
- const GValue *val2 = gst_structure_id_get_value (idata->intersect, id);
-
- if (G_UNLIKELY (val2 == NULL)) {
- gst_structure_id_set_value (idata->dest, id, val1);
- }
- return TRUE;
-}
-
-static GstStructure *
-gst_caps_structure_intersect (const GstStructure * struct1,
- const GstStructure * struct2)
-{
- IntersectData data;
-
- g_assert (struct1 != NULL);
- g_assert (struct2 != NULL);
-
- if (G_UNLIKELY (struct1->name != struct2->name))
- return NULL;
-
- /* copy fields from struct1 which we have not in struct2 to target
- * intersect if we have the field in both */
- data.dest = gst_structure_id_empty_new (struct1->name);
- data.intersect = struct2;
- if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
- gst_caps_structure_intersect_field1, &data)))
- goto error;
-
- /* copy fields from struct2 which we have not in struct1 to target */
- data.intersect = struct1;
- if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct2,
- gst_caps_structure_intersect_field2, &data)))
- goto error;
-
- return data.dest;
-
-error:
- gst_structure_free (data.dest);
- return NULL;
-}
-
-static gboolean
-gst_caps_structure_can_intersect_field (GQuark id, const GValue * val1,
- gpointer data)
-{
- GstStructure *other = (GstStructure *) data;
- const GValue *val2 = gst_structure_id_get_value (other, id);
-
- if (G_LIKELY (val2)) {
- if (!gst_value_can_intersect (val1, val2)) {
- return FALSE;
- } else {
- gint eq = gst_value_compare (val1, val2);
-
- if (eq == GST_VALUE_UNORDERED) {
- /* we need to try interseting */
- GValue dest_value = { 0 };
- if (gst_value_intersect (&dest_value, val1, val2)) {
- g_value_unset (&dest_value);
- } else {
- return FALSE;
- }
- } else if (eq != GST_VALUE_EQUAL) {
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-static gboolean
-gst_caps_structure_can_intersect (const GstStructure * struct1,
- const GstStructure * struct2)
-{
- g_assert (struct1 != NULL);
- g_assert (struct2 != NULL);
-
- if (G_UNLIKELY (struct1->name != struct2->name))
- return FALSE;
-
- /* tries to intersect if we have the field in both */
- if (G_UNLIKELY (!gst_structure_foreach ((GstStructure *) struct1,
- gst_caps_structure_can_intersect_field, (gpointer) struct2)))
- return FALSE;
-
- return TRUE;
-}
-
/**
* gst_caps_can_intersect:
* @caps1: a #GstCaps to intersect
* structures. The result is that the intersections are ordered based on the
* sum of the indexes in the list.
*/
- len1 = caps1->structs->len;
- len2 = caps2->structs->len;
+ len1 = GST_CAPS_LEN (caps1);
+ len2 = GST_CAPS_LEN (caps2);
for (i = 0; i < len1 + len2 - 1; i++) {
/* superset index goes from 0 to sgst_caps_structure_intersectuperset->structs->len-1 */
j = MIN (i, len1 - 1);
/* subset index stays 0 until i reaches superset->structs->len, then it
* counts up from 1 to subset->structs->len - 1 */
- k = MAX (0, i - j);
+ k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
/* now run the diagonal line, end condition is the left or bottom
* border */
struct1 = gst_caps_get_structure_unchecked (caps1, j);
struct2 = gst_caps_get_structure_unchecked (caps2, k);
- if (gst_caps_structure_can_intersect (struct1, struct2)) {
+ if (gst_structure_can_intersect (struct1, struct2)) {
return TRUE;
}
/* move down left */
* the structures diagonally down, then we iterate over the caps2
* structures.
*/
- len1 = caps1->structs->len;
- len2 = caps2->structs->len;
+ len1 = GST_CAPS_LEN (caps1);
+ len2 = GST_CAPS_LEN (caps2);
for (i = 0; i < len1 + len2 - 1; i++) {
- /* caps1 index goes from 0 to caps1->structs->len-1 */
+ /* caps1 index goes from 0 to GST_CAPS_LEN (caps1)-1 */
j = MIN (i, len1 - 1);
- /* caps2 index stays 0 until i reaches caps1->structs->len, then it counts
- * up from 1 to caps2->structs->len - 1 */
- k = MAX (0, i - j);
+ /* caps2 index stays 0 until i reaches GST_CAPS_LEN (caps1), then it counts
+ * up from 1 to GST_CAPS_LEN (caps2) - 1 */
+ k = (i > j) ? (i - j) : 0; /* MAX (0, i - j) */
/* now run the diagonal line, end condition is the left or bottom
* border */
struct1 = gst_caps_get_structure_unchecked (caps1, j);
struct2 = gst_caps_get_structure_unchecked (caps2, k);
- istruct = gst_caps_structure_intersect (struct1, struct2);
+ istruct = gst_structure_intersect (struct1, struct2);
- gst_caps_append_structure (dest, istruct);
+ gst_caps_merge_structure (dest, istruct);
/* move down left */
k++;
if (G_UNLIKELY (j == 0))
dest = gst_caps_new_empty ();
- len1 = caps1->structs->len;
- len2 = caps2->structs->len;
+ len1 = GST_CAPS_LEN (caps1);
+ len2 = GST_CAPS_LEN (caps2);
for (i = 0; i < len1; i++) {
struct1 = gst_caps_get_structure_unchecked (caps1, i);
for (j = 0; j < len2; j++) {
struct2 = gst_caps_get_structure_unchecked (caps2, j);
- istruct = gst_caps_structure_intersect (struct1, struct2);
+ istruct = gst_structure_intersect (struct1, struct2);
if (istruct)
- gst_caps_append_structure (dest, istruct);
+ gst_caps_merge_structure (dest, istruct);
}
}
/**
* gst_caps_subtract:
- * @minuend: #GstCaps to substract from
- * @subtrahend: #GstCaps to substract
+ * @minuend: #GstCaps to subtract from
+ * @subtrahend: #GstCaps to subtract
*
* Subtracts the @subtrahend from the @minuend.
* <note>This function does not work reliably if optional properties for caps
You can only remove everything or nothing and that is done above.
Note: there's a test that checks this behaviour. */
g_return_val_if_fail (!CAPS_IS_ANY (minuend), NULL);
- sublen = subtrahend->structs->len;
+ sublen = GST_CAPS_LEN (subtrahend);
g_assert (sublen > 0);
src = _gst_caps_copy (minuend);
src = dest;
}
dest = gst_caps_new_empty ();
- srclen = src->structs->len;
+ srclen = GST_CAPS_LEN (src);
for (j = 0; j < srclen; j++) {
min = gst_caps_get_structure_unchecked (src, j);
if (gst_structure_get_name_id (min) == gst_structure_get_name_id (sub)) {
gst_structure_set_parent_refcount (old, NULL);
gst_structure_free (old);
gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
- g_ptr_array_index (caps->structs, i) = new;
+ g_ptr_array_index (GST_CAPS_ARRAY (caps), i) = new;
}
/**
if (gst_caps_get_size (caps) < 2)
return FALSE;
- g_ptr_array_sort (caps->structs, gst_caps_compare_structures);
+ g_ptr_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
- start = caps->structs->len - 1;
- for (i = caps->structs->len - 1; i >= 0; i--) {
+ start = GST_CAPS_LEN (caps) - 1;
+ for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
simplify = gst_caps_get_structure_unchecked (caps, i);
if (gst_structure_get_name_id (simplify) !=
gst_structure_get_name_id (gst_caps_get_structure_unchecked (caps,
return TRUE;
}
-/* utility */
-
/**
- * gst_caps_replace:
- * @caps: (inout) (transfer full): a pointer to #GstCaps
- * @newcaps: a #GstCaps to replace *caps
+ * gst_caps_fixate:
+ * @caps: a #GstCaps to fixate
*
- * Replaces *caps with @newcaps. Unrefs the #GstCaps in the location
- * pointed to by @caps, if applicable, then modifies @caps to point to
- * @newcaps. An additional ref on @newcaps is taken.
- *
- * This function does not take any locks so you might want to lock
- * the object owning @caps pointer.
+ * Modifies the given @caps inplace into a representation with only fixed
+ * values. First the caps will be truncated and then the first structure will be
+ * fixated with gst_structure_fixate(). @caps should be writable.
*/
void
-gst_caps_replace (GstCaps ** caps, GstCaps * newcaps)
+gst_caps_fixate (GstCaps * caps)
{
- GstCaps *oldcaps;
-
- g_return_if_fail (caps != NULL);
-
- oldcaps = *caps;
-
- GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p, %p -> %p", caps, oldcaps, newcaps);
-
- if (newcaps != oldcaps) {
- if (newcaps)
- gst_caps_ref (newcaps);
+ GstStructure *s;
- *caps = newcaps;
+ g_return_if_fail (GST_IS_CAPS (caps));
+ g_return_if_fail (IS_WRITABLE (caps));
- if (oldcaps)
- gst_caps_unref (oldcaps);
- }
+ /* default fixation */
+ gst_caps_truncate (caps);
+ s = gst_caps_get_structure (caps, 0);
+ gst_structure_fixate (s);
}
+/* utility */
+
/**
* gst_caps_to_string:
* @caps: a #GstCaps
/* estimate a rough string length to avoid unnecessary reallocs in GString */
slen = 0;
- clen = caps->structs->len;
+ clen = GST_CAPS_LEN (caps);
for (i = 0; i < clen; i++) {
slen +=
STRUCTURE_ESTIMATED_STRING_LEN (gst_caps_get_structure_unchecked (caps,