X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstcaps.c;h=db4e067b9fdd655dcd6cbe29a918d2350ca3f4c1;hb=8170c34c943e83c7fdef30394bbbff09418a2e6c;hp=94b700019d4cdcdd969fbcb8417c89ab0fbd4342;hpb=ec6e452f6314b10e883c6f95366867a02c775ff0;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 94b7000..db4e067 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -43,8 +43,8 @@ * Creating caps * * 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, @@ -73,53 +73,36 @@ #include #include -#ifdef GST_DISABLE_DEPRECATED -#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED) -#include -xmlNodePtr gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent); -GstCaps *gst_caps_load_thyself (xmlNodePtr parent); -#endif -#endif - #define DEBUG_REFCOUNT -#define CAPS_POISON(caps) G_STMT_START{ \ - if (caps) { \ - GstCaps *_newcaps = gst_caps_copy (caps); \ - gst_caps_unref(caps); \ - caps = _newcaps; \ - } \ -} G_STMT_END -#define STRUCTURE_POISON(structure) G_STMT_START{ \ - if (structure) { \ - GstStructure *_newstruct = gst_structure_copy (structure); \ - gst_structure_free(structure); \ - structure = _newstruct; \ - } \ -} G_STMT_END + +#define GST_CAPS_ARRAY(c) ((GPtrArray *)((c)->priv)) + +#define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len) + #define IS_WRITABLE(caps) \ - (g_atomic_int_get (&(caps)->refcount) == 1) + (GST_CAPS_REFCOUNT_VALUE (caps) == 1) /* same as gst_caps_is_any () */ #define CAPS_IS_ANY(caps) \ - ((caps)->flags & GST_CAPS_FLAGS_ANY) + (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAGS_ANY) /* same as gst_caps_is_empty () */ #define CAPS_IS_EMPTY(caps) \ (!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, &caps->refcount); \ - 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 */ @@ -129,26 +112,80 @@ static void gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value); static gboolean gst_caps_from_string_inplace (GstCaps * caps, const gchar * string); -static GstCaps *gst_caps_copy_conditional (GstCaps * src); -GType -gst_caps_get_type (void) +GType _gst_caps_type = 0; + +void +_gst_caps_initialize (void) +{ + _gst_caps_type = gst_mini_object_register ("GstCaps"); + + g_value_register_transform_func (_gst_caps_type, + G_TYPE_STRING, gst_caps_transform_to_string); +} + +static GstCaps * +_gst_caps_copy (const GstCaps * caps) { - static GType gst_caps_type = 0; + GstCaps *newcaps; + GstStructure *structure; + guint i, n; - if (G_UNLIKELY (gst_caps_type == 0)) { - gst_caps_type = g_boxed_type_register_static ("GstCaps", - (GBoxedCopyFunc) gst_caps_copy_conditional, - (GBoxedFreeFunc) gst_caps_unref); + g_return_val_if_fail (GST_IS_CAPS (caps), NULL); - g_value_register_transform_func (gst_caps_type, - G_TYPE_STRING, gst_caps_transform_to_string); + newcaps = gst_caps_new_empty (); + GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps); + n = GST_CAPS_LEN (caps); + + for (i = 0; i < n; i++) { + structure = gst_caps_get_structure_unchecked (caps, i); + gst_caps_append_structure (newcaps, gst_structure_copy (structure)); } - return gst_caps_type; + return newcaps; } /* creation/deletion */ +static void +_gst_caps_free (GstCaps * caps) +{ + GstStructure *structure; + guint i, len; + + /* The refcount must be 0, but since we're only called by gst_caps_unref, + * don't bother testing. */ + 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++) { + structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i); + gst_structure_set_parent_refcount (structure, NULL); + gst_structure_free (structure); + } + g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE); + +#ifdef DEBUG_REFCOUNT + GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps); +#endif + g_slice_free1 (GST_MINI_OBJECT_SIZE (caps), caps); +} + +static void +gst_caps_init (GstCaps * caps, gsize size) +{ + gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), _gst_caps_type, size); + + caps->mini_object.copy = (GstMiniObjectCopyFunction) _gst_caps_copy; + caps->mini_object.dispose = NULL; + caps->mini_object.free = (GstMiniObjectFreeFunction) _gst_caps_free; + + /* 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 + * GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32); + */ + caps->priv = g_ptr_array_new (); +} /** * gst_caps_new_empty: @@ -162,17 +199,11 @@ gst_caps_get_type (void) GstCaps * gst_caps_new_empty (void) { - GstCaps *caps = g_slice_new (GstCaps); + GstCaps *caps; - caps->type = GST_TYPE_CAPS; - caps->refcount = 1; - caps->flags = GST_CAPS_FLAGS_NONE; - caps->structs = g_ptr_array_new (); - /* 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); - */ + caps = g_slice_new (GstCaps); + + gst_caps_init (caps, sizeof (GstCaps)); #ifdef DEBUG_REFCOUNT GST_CAT_LOG (GST_CAT_CAPS, "created caps %p", caps); @@ -194,7 +225,7 @@ gst_caps_new_any (void) { GstCaps *caps = gst_caps_new_empty (); - caps->flags = GST_CAPS_FLAGS_ANY; + GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAGS_ANY); return caps; } @@ -283,162 +314,6 @@ gst_caps_new_full_valist (GstStructure * structure, va_list var_args) return caps; } -/** - * gst_caps_copy: - * @caps: the #GstCaps to copy - * - * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a - * refcount of 1, owned by the caller. The structures are copied as well. - * - * Note that this function is the semantic equivalent of a gst_caps_ref() - * followed by a gst_caps_make_writable(). If you only want to hold on to a - * reference to the data, you should use gst_caps_ref(). - * - * When you are finished with the caps, call gst_caps_unref() on it. - * - * Returns: (transfer full): the new #GstCaps - */ -GstCaps * -gst_caps_copy (const GstCaps * caps) -{ - GstCaps *newcaps; - GstStructure *structure; - guint i, n; - - g_return_val_if_fail (GST_IS_CAPS (caps), NULL); - - newcaps = gst_caps_new_empty (); - newcaps->flags = caps->flags; - n = caps->structs->len; - - for (i = 0; i < n; i++) { - structure = gst_caps_get_structure_unchecked (caps, i); - gst_caps_append_structure_unchecked (newcaps, - gst_structure_copy (structure)); - } - - return newcaps; -} - -static void -_gst_caps_free (GstCaps * caps) -{ - GstStructure *structure; - guint i, len; - - /* The refcount must be 0, but since we're only called by gst_caps_unref, - * don't bother testing. */ - len = caps->structs->len; - /* 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++) { - structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i); - gst_structure_set_parent_refcount (structure, NULL); - gst_structure_free (structure); - } - g_ptr_array_free (caps->structs, TRUE); -#ifdef USE_POISONING - memset (caps, 0xff, sizeof (GstCaps)); -#endif - -#ifdef DEBUG_REFCOUNT - GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps); -#endif - g_slice_free (GstCaps, 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; -} - -/** - * gst_caps_ref: - * @caps: the #GstCaps to reference - * - * Add a reference to a #GstCaps object. - * - * From this point on, until the caller calls gst_caps_unref() or - * gst_caps_make_writable(), it is guaranteed that the caps object will not - * change. This means its structures won't change, etc. To use a #GstCaps - * object, you must always have a refcount on it -- either the one made - * implicitly by e.g. gst_caps_new_simple(), or via taking one explicitly with - * this function. - * - * Returns: (transfer full): the same #GstCaps object. - */ -GstCaps * -gst_caps_ref (GstCaps * caps) -{ - g_return_val_if_fail (caps != NULL, NULL); - -#ifdef DEBUG_REFCOUNT - GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p %d->%d", caps, - GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) + 1); -#endif - g_return_val_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0, NULL); - - g_atomic_int_inc (&caps->refcount); - - return caps; -} - -/** - * gst_caps_unref: - * @caps: (transfer full): the #GstCaps to unref - * - * Unref a #GstCaps and and free all its structures and the - * structures' values when the refcount reaches 0. - */ -void -gst_caps_unref (GstCaps * caps) -{ - g_return_if_fail (caps != NULL); - -#ifdef DEBUG_REFCOUNT - GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p %d->%d", caps, - GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) - 1); -#endif - - g_return_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0); - - /* if we ended up with the refcount at zero, free the caps */ - if (G_UNLIKELY (g_atomic_int_dec_and_test (&caps->refcount))) - _gst_caps_free (caps); -} - GType gst_static_caps_get_type (void) { @@ -471,13 +346,13 @@ gst_static_caps_get (GstStaticCaps * static_caps) caps = (GstCaps *) static_caps; /* refcount is 0 when we need to convert */ - if (G_UNLIKELY (g_atomic_int_get (&caps->refcount) == 0)) { + if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) == 0)) { const char *string; GstCaps temp; G_LOCK (static_caps_lock); /* check if other thread already updated */ - if (G_UNLIKELY (g_atomic_int_get (&caps->refcount) > 0)) + if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0)) goto done; string = static_caps->string; @@ -491,24 +366,16 @@ gst_static_caps_get (GstStaticCaps * static_caps) * real caps, refcount last. We do this because we must leave the refcount * of the result caps to 0 so that other threads don't run away with the * caps while we are constructing it. */ - temp.type = GST_TYPE_CAPS; - temp.flags = GST_CAPS_FLAGS_NONE; - temp.structs = g_ptr_array_new (); - - /* initialize the caps to a refcount of 1 so the caps can be writable for - * the next statement */ - temp.refcount = 1; + gst_caps_init (&temp, sizeof (GstCaps)); /* convert to string */ if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string))) g_critical ("Could not convert static caps \"%s\"", string); + gst_caps_init (caps, sizeof (GstCaps)); /* now copy stuff over to the real caps. */ - caps->type = temp.type; - caps->flags = temp.flags; - caps->structs = temp.structs; - /* and bump the refcount so other threads can now read */ - g_atomic_int_set (&caps->refcount, 1); + GST_CAPS_FLAGS (caps) = GST_CAPS_FLAGS (&temp); + caps->priv = GST_CAPS_ARRAY (&temp); GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps); done: @@ -528,13 +395,41 @@ no_string: } } +/** + * 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; @@ -559,7 +454,7 @@ gst_caps_steal_structure (GstCaps * caps, guint index) 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); @@ -585,18 +480,15 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2) g_return_if_fail (IS_WRITABLE (caps1)); g_return_if_fail (IS_WRITABLE (caps2)); -#ifdef USE_POISONING - CAPS_POISON (caps2); -#endif if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) { /* FIXME: this leaks */ - caps1->flags |= GST_CAPS_FLAGS_ANY; - for (i = caps2->structs->len - 1; i >= 0; i--) { + GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAGS_ANY; + 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); } @@ -627,22 +519,19 @@ gst_caps_merge (GstCaps * caps1, GstCaps * caps2) g_return_if_fail (IS_WRITABLE (caps1)); g_return_if_fail (IS_WRITABLE (caps2)); -#ifdef USE_POISONING - CAPS_POISON (caps2); -#endif 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))) { - caps1->flags |= GST_CAPS_FLAGS_ANY; - for (i = caps1->structs->len - 1; i >= 0; i--) { + GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAGS_ANY; + 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); } @@ -674,12 +563,6 @@ gst_caps_append_structure (GstCaps * caps, GstStructure * structure) g_return_if_fail (IS_WRITABLE (caps)); if (G_LIKELY (structure)) { - g_return_if_fail (structure->parent_refcount == NULL); -#if 0 -#ifdef USE_POISONING - STRUCTURE_POISON (structure); -#endif -#endif gst_caps_append_structure_unchecked (caps, structure); } } @@ -724,14 +607,8 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure) int i; gboolean unique = TRUE; - g_return_if_fail (structure->parent_refcount == NULL); -#if 0 -#ifdef USE_POISONING - STRUCTURE_POISON (structure); -#endif -#endif /* 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_structure_is_subset (structure, structure1)) { @@ -760,7 +637,7 @@ gst_caps_get_size (const GstCaps * caps) { g_return_val_if_fail (GST_IS_CAPS (caps), 0); - return caps->structs->len; + return GST_CAPS_LEN (caps); } /** @@ -790,7 +667,7 @@ GstStructure * 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); } @@ -814,9 +691,9 @@ gst_caps_copy_nth (const GstCaps * caps, guint nth) g_return_val_if_fail (GST_IS_CAPS (caps), NULL); newcaps = gst_caps_new_empty (); - newcaps->flags = caps->flags; + 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)); @@ -840,7 +717,7 @@ gst_caps_truncate (GstCaps * caps) 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--); @@ -868,7 +745,7 @@ gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value) 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); @@ -1007,7 +884,7 @@ gst_caps_is_fixed (const GstCaps * caps) 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); @@ -1085,8 +962,8 @@ gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset) if (CAPS_IS_ANY (subset) || CAPS_IS_EMPTY (superset)) return FALSE; - for (i = subset->structs->len - 1; i >= 0; i--) { - for (j = superset->structs->len - 1; j >= 0; j--) { + 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)) { @@ -1133,7 +1010,7 @@ gst_caps_is_subset_structure (const GstCaps * caps, if (CAPS_IS_EMPTY (caps)) return FALSE; - for (i = caps->structs->len - 1; i >= 0; i--) { + 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 */ @@ -1232,8 +1109,8 @@ gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2) * 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); @@ -1273,7 +1150,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2) /* caps are exactly the same pointers, just copy one caps */ if (G_UNLIKELY (caps1 == caps2)) - return gst_caps_copy (caps1); + return _gst_caps_copy (caps1); /* empty caps on either side, return empty */ if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2))) @@ -1281,9 +1158,9 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2) /* one of the caps is any, just copy the other caps */ if (G_UNLIKELY (CAPS_IS_ANY (caps1))) - return gst_caps_copy (caps2); + return _gst_caps_copy (caps2); if (G_UNLIKELY (CAPS_IS_ANY (caps2))) - return gst_caps_copy (caps1); + return _gst_caps_copy (caps1); dest = gst_caps_new_empty (); @@ -1303,13 +1180,13 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2) * 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 */ + /* 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 @@ -1371,8 +1248,8 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2) 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++) { @@ -1521,7 +1398,7 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend) return gst_caps_new_empty (); } if (CAPS_IS_EMPTY_SIMPLE (subtrahend)) - return gst_caps_copy (minuend); + return _gst_caps_copy (minuend); /* FIXME: Do we want this here or above? The reason we need this is that there is no definition about what @@ -1529,10 +1406,10 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend) 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 = _gst_caps_copy (minuend); for (i = 0; i < sublen; i++) { guint srclen; @@ -1542,7 +1419,7 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend) 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)) { @@ -1637,16 +1514,16 @@ gst_caps_union (const GstCaps * caps1, const GstCaps * caps2) g_return_val_if_fail (caps2 != NULL, NULL); if (CAPS_IS_EMPTY (caps1)) - return gst_caps_copy (caps2); + return _gst_caps_copy (caps2); if (CAPS_IS_EMPTY (caps2)) - return gst_caps_copy (caps1); + return _gst_caps_copy (caps1); if (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2)) return gst_caps_new_any (); - dest1 = gst_caps_copy (caps1); - dest2 = gst_caps_copy (caps2); + dest1 = _gst_caps_copy (caps1); + dest2 = _gst_caps_copy (caps2); gst_caps_append (dest1, dest2); gst_caps_do_simplify (dest1); @@ -1707,7 +1584,7 @@ gst_caps_normalize (const GstCaps * caps) g_return_val_if_fail (GST_IS_CAPS (caps), NULL); - newcaps = gst_caps_copy (caps); + newcaps = _gst_caps_copy (caps); nf.caps = newcaps; for (i = 0; i < gst_caps_get_size (newcaps); i++) { @@ -1833,8 +1710,8 @@ gst_caps_switch_structures (GstCaps * caps, GstStructure * old, { gst_structure_set_parent_refcount (old, NULL); gst_structure_free (old); - gst_structure_set_parent_refcount (new, &caps->refcount); - g_ptr_array_index (caps->structs, i) = new; + gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps)); + g_ptr_array_index (GST_CAPS_ARRAY (caps), i) = new; } /** @@ -1861,10 +1738,10 @@ gst_caps_do_simplify (GstCaps * caps) 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, @@ -1899,84 +1776,31 @@ gst_caps_do_simplify (GstCaps * caps) return TRUE; } -/* persistence */ - -#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED) /** - * gst_caps_save_thyself: - * @caps: a #GstCaps structure - * @parent: a XML parent node - * - * Serializes a #GstCaps to XML and adds it as a child node of @parent. + * gst_caps_fixate: + * @caps: a #GstCaps to fixate * - * Returns: a XML node 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. */ -xmlNodePtr -gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent) +void +gst_caps_fixate (GstCaps * caps) { - char *s = gst_caps_to_string (caps); - - xmlNewChild (parent, NULL, (xmlChar *) "caps", (xmlChar *) s); - g_free (s); - return parent; -} + GstStructure *s; -/** - * gst_caps_load_thyself: - * @parent: a XML node - * - * Creates a #GstCaps from its XML serialization. - * - * Returns: a new #GstCaps structure - */ -GstCaps * -gst_caps_load_thyself (xmlNodePtr parent) -{ - if (strcmp ("caps", (char *) parent->name) == 0) { - return gst_caps_from_string ((gchar *) xmlNodeGetContent (parent)); - } + g_return_if_fail (GST_IS_CAPS (caps)); + g_return_if_fail (IS_WRITABLE (caps)); - return NULL; + /* default fixation */ + gst_caps_truncate (caps); + s = gst_caps_get_structure (caps, 0); + gst_structure_fixate (s); } -#endif /* utility */ /** - * gst_caps_replace: - * @caps: (inout) (transfer full): a pointer to #GstCaps - * @newcaps: a #GstCaps to replace *caps - * - * 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. - */ -void -gst_caps_replace (GstCaps ** caps, GstCaps * newcaps) -{ - 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); - - *caps = newcaps; - - if (oldcaps) - gst_caps_unref (oldcaps); - } -} - -/** * gst_caps_to_string: * @caps: a #GstCaps * @@ -2015,7 +1839,7 @@ gst_caps_to_string (const GstCaps * caps) /* 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, @@ -2048,7 +1872,7 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string) gchar *s; if (strcmp ("ANY", string) == 0) { - caps->flags = GST_CAPS_FLAGS_ANY; + GST_CAPS_FLAGS (caps) = GST_CAPS_FLAGS_ANY; return TRUE; } if (strcmp ("EMPTY", string) == 0) { @@ -2115,13 +1939,3 @@ gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value) dest_value->data[0].v_pointer = gst_caps_to_string (src_value->data[0].v_pointer); } - -static GstCaps * -gst_caps_copy_conditional (GstCaps * src) -{ - if (src) { - return gst_caps_ref (src); - } else { - return NULL; - } -}