X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=gst%2Fgstcaps.c;h=48b4f9aff7cb993471c9870d60a452603e6c4e38;hb=12f835ca438b2e229a7f71ae069baea21aecfde7;hp=3bfe62bde56ac3de77d5c8ad20949443c46b4ff2;hpb=35ea12eeea50030d798787a44d20f1363849fa8e;p=platform%2Fupstream%2Fgstreamer.git
diff --git a/gst/gstcaps.c b/gst/gstcaps.c
index 3bfe62b..48b4f9a 100644
--- a/gst/gstcaps.c
+++ b/gst/gstcaps.c
@@ -13,30 +13,26 @@
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/**
* SECTION:gstcaps
* @short_description: Structure describing sets of media formats
- * @see_also: #GstStructure
+ * @see_also: #GstStructure, #GstMiniObject
*
- * Caps (capabilities) are lighweight refcounted objects describing media types.
+ * Caps (capabilities) are lightweight refcounted objects describing media types.
* They are composed of an array of #GstStructure.
*
* Caps are exposed on #GstPadTemplate to describe all possible types a
* given pad can handle. They are also stored in the #GstRegistry along with
* a description of the #GstElement.
*
- * Caps are exposed on the element pads using the gst_pad_get_caps() pad
+ * Caps are exposed on the element pads using the gst_pad_query_caps() pad
* function. This function describes the possible types that the pad can
* handle or produce at runtime.
*
- * Caps are also attached to buffers to describe to content of the data
- * pointed to by the buffer with gst_buffer_set_caps(). Caps attached to
- * a #GstBuffer allow for format negotiation upstream and downstream.
- *
* A #GstCaps can be constructed with the following code fragment:
*
*
@@ -44,7 +40,7 @@
*
* GstCaps *caps;
* caps = gst_caps_new_simple ("video/x-raw",
- * "format", G_TYPE_STRING, "I420"),
+ * "format", G_TYPE_STRING, "I420",
* "framerate", GST_TYPE_FRACTION, 25, 1,
* "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1,
* "width", G_TYPE_INT, 320,
@@ -54,13 +50,13 @@
*
*
* A #GstCaps is fixed when it has no properties with ranges or lists. Use
- * gst_caps_is_fixed() to test for fixed caps. Only fixed caps can be
- * set on a #GstPad or #GstBuffer.
+ * gst_caps_is_fixed() to test for fixed caps. Fixed caps can be used in a
+ * caps event to notify downstream elements of the current media type.
*
* Various methods exist to work with the media types such as subtracting
* or intersecting.
*
- * Last reviewed on 2007-02-13 (0.10.10)
+ * Last reviewed on 2011-03-28 (0.11.3)
*/
#ifdef HAVE_CONFIG_H
@@ -75,8 +71,14 @@
#define DEBUG_REFCOUNT
+typedef struct _GstCapsImpl
+{
+ GstCaps caps;
+
+ GPtrArray *array;
+} GstCapsImpl;
-#define GST_CAPS_ARRAY(c) ((GPtrArray *)((c)->priv))
+#define GST_CAPS_ARRAY(c) (((GstCapsImpl *)(c))->array)
#define GST_CAPS_LEN(c) (GST_CAPS_ARRAY(c)->len)
@@ -144,6 +146,9 @@ _gst_caps_copy (const GstCaps * caps)
GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
n = GST_CAPS_LEN (caps);
+ GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, caps, "doing copy %p -> %p",
+ caps, newcaps);
+
for (i = 0; i < n; i++) {
structure = gst_caps_get_structure_unchecked (caps, i);
gst_caps_append_structure (newcaps, gst_structure_copy (structure));
@@ -172,26 +177,24 @@ _gst_caps_free (GstCaps * caps)
g_ptr_array_free (GST_CAPS_ARRAY (caps), TRUE);
#ifdef DEBUG_REFCOUNT
- GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
+ GST_CAT_TRACE (GST_CAT_CAPS, "freeing caps %p", caps);
#endif
- g_slice_free1 (GST_MINI_OBJECT_SIZE (caps), caps);
+ g_slice_free1 (sizeof (GstCapsImpl), caps);
}
static void
-gst_caps_init (GstCaps * caps, gsize size)
+gst_caps_init (GstCaps * caps)
{
- 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;
+ gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), 0, _gst_caps_type,
+ (GstMiniObjectCopyFunction) _gst_caps_copy, NULL,
+ (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
+ * in practice
* GST_CAPS_ARRAY (caps) = g_ptr_array_sized_new (32);
*/
- caps->priv = g_ptr_array_new ();
+ GST_CAPS_ARRAY (caps) = g_ptr_array_new ();
}
/**
@@ -199,6 +202,7 @@ gst_caps_init (GstCaps * caps, gsize size)
*
* Creates a new #GstCaps that is empty. That is, the returned
* #GstCaps contains no media formats.
+ * The #GstCaps is guaranteed to be writable.
* Caller is responsible for unreffing the returned caps.
*
* Returns: (transfer full): the new #GstCaps
@@ -208,9 +212,9 @@ gst_caps_new_empty (void)
{
GstCaps *caps;
- caps = g_slice_new (GstCaps);
+ caps = (GstCaps *) g_slice_new (GstCapsImpl);
- gst_caps_init (caps, sizeof (GstCaps));
+ gst_caps_init (caps);
#ifdef DEBUG_REFCOUNT
GST_CAT_TRACE (GST_CAT_CAPS, "created caps %p", caps);
@@ -345,17 +349,7 @@ gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
return caps;
}
-GType
-gst_static_caps_get_type (void)
-{
- static GType staticcaps_type = 0;
-
- if (G_UNLIKELY (staticcaps_type == 0)) {
- staticcaps_type = g_pointer_type_register_static ("GstStaticCaps");
- }
- return staticcaps_type;
-}
-
+G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps);
/**
* gst_static_caps_get:
@@ -370,20 +364,19 @@ gst_static_caps_get_type (void)
GstCaps *
gst_static_caps_get (GstStaticCaps * static_caps)
{
- GstCaps *caps;
+ GstCaps **caps;
g_return_val_if_fail (static_caps != NULL, NULL);
- caps = (GstCaps *) static_caps;
+ caps = &static_caps->caps;
/* refcount is 0 when we need to convert */
- if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) == 0)) {
+ if (G_UNLIKELY (*caps == NULL)) {
const char *string;
- GstCaps temp;
G_LOCK (static_caps_lock);
/* check if other thread already updated */
- if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0))
+ if (G_UNLIKELY (*caps != NULL))
goto done;
string = static_caps->string;
@@ -391,30 +384,22 @@ gst_static_caps_get (GstStaticCaps * static_caps)
if (G_UNLIKELY (string == NULL))
goto no_string;
- GST_CAT_TRACE (GST_CAT_CAPS, "creating %p", static_caps);
-
- /* we construct the caps on the stack, then copy over the struct into our
- * 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. */
- gst_caps_init (&temp, sizeof (GstCaps));
+ *caps = gst_caps_from_string (string);
/* convert to string */
- if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
+ if (G_UNLIKELY (*caps == NULL))
g_critical ("Could not convert static caps \"%s\"", string);
- GST_MINI_OBJECT_REFCOUNT (&temp) = 0;
- memcpy (caps, &temp, sizeof (GstCaps));
- gst_caps_ref (caps);
-
- GST_CAT_TRACE (GST_CAT_CAPS, "created %p", static_caps);
+ GST_CAT_TRACE (GST_CAT_CAPS, "created %p from string %s", static_caps,
+ string);
done:
G_UNLOCK (static_caps_lock);
}
/* ref the caps, makes it not writable */
- gst_caps_ref (caps);
+ if (G_LIKELY (*caps != NULL))
+ gst_caps_ref (*caps);
- return caps;
+ return *caps;
/* ERRORS */
no_string:
@@ -427,30 +412,16 @@ no_string:
/**
* gst_static_caps_cleanup:
- * @static_caps: the #GstStaticCaps to convert
+ * @static_caps: the #GstStaticCaps to clean
*
- * Clean up the caps contained in @static_caps when the refcount is 0.
+ * Clean up the cached caps contained in @static_caps.
*/
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;
- }
+ G_LOCK (static_caps_lock);
+ gst_caps_replace (&static_caps->caps, NULL);
+ G_UNLOCK (static_caps_lock);
}
/* manipulation */
@@ -458,7 +429,7 @@ gst_static_caps_cleanup (GstStaticCaps * static_caps)
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 */
+ /* don't use index_fast, gst_caps_simplify relies on the order */
GstStructure *s = g_ptr_array_remove_index (GST_CAPS_ARRAY (caps), idx);
gst_structure_set_parent_refcount (s, NULL);
@@ -470,13 +441,11 @@ gst_caps_remove_and_get_structure (GstCaps * caps, guint idx)
* @caps: the #GstCaps to retrieve from
* @index: Index of the structure to retrieve
*
- * Retrieves the stucture with the given index from the list of structures
+ * Retrieves the structure with the given index from the list of structures
* contained in @caps. The caller becomes the owner of the returned structure.
*
* Returns: (transfer full): a pointer to the #GstStructure corresponding
* to @index.
- *
- * Since: 0.10.30
*/
GstStructure *
gst_caps_steal_structure (GstCaps * caps, guint index)
@@ -509,64 +478,58 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2)
g_return_if_fail (GST_IS_CAPS (caps2));
g_return_if_fail (IS_WRITABLE (caps1));
- caps2 = gst_caps_make_writable (caps2);
-
if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
- /* FIXME: this leaks */
GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
- for (i = GST_CAPS_LEN (caps2) - 1; i >= 0; i--) {
- structure = gst_caps_remove_and_get_structure (caps2, i);
- gst_structure_free (structure);
- }
+ gst_caps_unref (caps2);
} else {
+ caps2 = gst_caps_make_writable (caps2);
+
for (i = GST_CAPS_LEN (caps2); i; i--) {
structure = gst_caps_remove_and_get_structure (caps2, 0);
gst_caps_append_structure_unchecked (caps1, structure);
}
+ gst_caps_unref (caps2); /* guaranteed to free it */
}
- gst_caps_unref (caps2); /* guaranteed to free it */
}
/**
* gst_caps_merge:
- * @caps1: the #GstCaps that will take the new entries
+ * @caps1: (transfer full): the #GstCaps that will take the new entries
* @caps2: (transfer full): the #GstCaps to merge in
*
* Appends the structures contained in @caps2 to @caps1 if they are not yet
* expressed by @caps1. The structures in @caps2 are not copied -- they are
- * transferred to @caps1, and then @caps2 is freed.
+ * transferred to a writable copy of @caps1, and then @caps2 is freed.
* If either caps is ANY, the resulting caps will be ANY.
*
- * Since: 0.10.10
+ * Returns: (transfer full): the merged caps.
*/
-void
+GstCaps *
gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
{
GstStructure *structure;
int i;
+ GstCaps *result;
- g_return_if_fail (GST_IS_CAPS (caps1));
- g_return_if_fail (GST_IS_CAPS (caps2));
- g_return_if_fail (IS_WRITABLE (caps1));
-
- caps2 = gst_caps_make_writable (caps2);
+ g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
+ g_return_val_if_fail (GST_IS_CAPS (caps2), NULL);
if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
- for (i = GST_CAPS_LEN (caps2) - 1; i >= 0; i--) {
- structure = gst_caps_remove_and_get_structure (caps2, i);
- gst_structure_free (structure);
- }
+ gst_caps_unref (caps2);
+ result = caps1;
} else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
- GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAG_ANY;
- for (i = GST_CAPS_LEN (caps1) - 1; i >= 0; i--) {
- structure = gst_caps_remove_and_get_structure (caps1, i);
- gst_structure_free (structure);
- }
+ gst_caps_unref (caps1);
+ result = caps2;
} else {
+ caps2 = gst_caps_make_writable (caps2);
+
for (i = GST_CAPS_LEN (caps2); i; i--) {
structure = gst_caps_remove_and_get_structure (caps2, 0);
- gst_caps_merge_structure (caps1, structure);
+ caps1 = gst_caps_merge_structure (caps1, structure);
}
+ gst_caps_unref (caps2);
+ result = caps1;
+
/* this is too naive
GstCaps *com = gst_caps_intersect (caps1, caps2);
GstCaps *add = gst_caps_subtract (caps2, com);
@@ -577,7 +540,8 @@ gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
gst_caps_unref (com);
*/
}
- gst_caps_unref (caps2); /* guaranteed to free it */
+
+ return result;
}
/**
@@ -622,38 +586,41 @@ gst_caps_remove_structure (GstCaps * caps, guint idx)
/**
* gst_caps_merge_structure:
- * @caps: the #GstCaps that will the new structure
+ * @caps: (transfer full): the #GstCaps to merge into
* @structure: (transfer full): the #GstStructure to merge
*
- * Appends @structure to @caps if its not already expressed by @caps. The
- * structure is not copied; @caps becomes the owner of @structure.
+ * Appends @structure to @caps if its not already expressed by @caps.
+ *
+ * Returns: (transfer full): the merged caps.
*/
-void
+GstCaps *
gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
{
- g_return_if_fail (GST_IS_CAPS (caps));
- g_return_if_fail (IS_WRITABLE (caps));
+ GstStructure *structure1;
+ int i;
+ gboolean unique = TRUE;
- if (G_LIKELY (structure)) {
- GstStructure *structure1;
- int i;
- gboolean unique = TRUE;
-
- /* check each structure */
- 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)) {
- unique = FALSE;
- break;
- }
- }
- if (unique) {
- gst_caps_append_structure_unchecked (caps, structure);
- } else {
- gst_structure_free (structure);
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
+
+ if (G_UNLIKELY (structure == NULL))
+ return caps;
+
+ /* check each structure */
+ 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)) {
+ unique = FALSE;
+ break;
}
}
+ if (unique) {
+ caps = gst_caps_make_writable (caps);
+ gst_caps_append_structure_unchecked (caps, structure);
+ } else {
+ gst_structure_free (structure);
+ }
+ return caps;
}
/**
@@ -736,23 +703,29 @@ gst_caps_copy_nth (const GstCaps * caps, guint nth)
/**
* gst_caps_truncate:
- * @caps: the #GstCaps to truncate
+ * @caps: (transfer full): the #GstCaps to truncate
+ *
+ * Discard all but the first structure from @caps. Useful when
+ * fixating.
*
- * Destructively discard all but the first structure from @caps. Useful when
- * fixating. @caps must be writable.
+ * Returns: (transfer full): truncated caps
*/
-void
+GstCaps *
gst_caps_truncate (GstCaps * caps)
{
gint i;
- g_return_if_fail (GST_IS_CAPS (caps));
- g_return_if_fail (IS_WRITABLE (caps));
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
i = GST_CAPS_LEN (caps) - 1;
+ if (i == 0)
+ return caps;
+ caps = gst_caps_make_writable (caps);
while (i > 0)
gst_caps_remove_structure (caps, i--);
+
+ return caps;
}
/**
@@ -764,8 +737,6 @@ gst_caps_truncate (GstCaps * caps)
* Sets the given @field on all structures of @caps to the given @value.
* This is a convenience function for calling gst_structure_set_value() on
* all structures of @caps.
- *
- * Since: 0.10.26
**/
void
gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
@@ -792,10 +763,6 @@ gst_caps_set_value (GstCaps * caps, const char *field, const GValue * value)
*
* Sets fields in a #GstCaps. The arguments must be passed in the same
* manner as gst_structure_set(), and be NULL-terminated.
- * Prior to GStreamer version 0.10.26, this function failed when
- * @caps was not simple. If your code needs to work with those versions
- * of GStreamer, you may only call this function when GST_CAPS_IS_SIMPLE()
- * is %TRUE for @caps.
*/
void
gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
@@ -833,10 +800,6 @@ gst_caps_set_simple_valist (GstCaps * caps, const char *field, va_list varargs)
*
* Sets fields in a #GstCaps. The arguments must be passed in the same
* manner as gst_structure_set(), and be NULL-terminated.
- * Prior to GStreamer version 0.10.26, this function failed when
- * @caps was not simple. If your code needs to work with those versions
- * of GStreamer, you may only call this function when GST_CAPS_IS_SIMPLE()
- * is %TRUE for @caps.
*/
void
gst_caps_set_simple (GstCaps * caps, const char *field, ...)
@@ -1020,8 +983,6 @@ gst_caps_is_subset (const GstCaps * subset, const GstCaps * superset)
* for more information.
*
* Returns: %TRUE if @structure is a subset of @caps
- *
- * Since: 0.10.36
*/
gboolean
gst_caps_is_subset_structure (const GstCaps * caps,
@@ -1058,25 +1019,17 @@ gst_caps_is_subset_structure (const GstCaps * caps,
* This function does not work reliably if optional properties for caps
* are included on one caps and omitted on the other.
*
- * This function deals correctly with passing NULL for any of the caps.
- *
* Returns: TRUE if both caps are equal.
*/
gboolean
gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
{
- /* FIXME 0.11: NULL pointers are no valid Caps but indicate an error
- * So there should be an assertion that caps1 and caps2 != NULL */
+ g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
+ g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
- /* NULL <-> NULL is allowed here */
if (G_UNLIKELY (caps1 == caps2))
return TRUE;
- /* one of them NULL => they are different (can't be both NULL because
- * we checked that above) */
- if (G_UNLIKELY (caps1 == NULL || caps2 == NULL))
- return FALSE;
-
if (G_UNLIKELY (gst_caps_is_fixed (caps1) && gst_caps_is_fixed (caps2)))
return gst_caps_is_equal_fixed (caps1, caps2);
@@ -1090,28 +1043,19 @@ gst_caps_is_equal (const GstCaps * caps1, const GstCaps * caps2)
*
* Checks if the given caps are exactly the same set of caps.
*
- * This function deals correctly with passing NULL for any of the caps.
- *
* Returns: TRUE if both caps are strictly equal.
- *
- * Since: 0.10.36
*/
gboolean
gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
{
int i;
- /* FIXME 0.11: NULL pointers are no valid Caps but indicate an error
- * So there should be an assertion that caps1 and caps2 != NULL */
- /* NULL <-> NULL is allowed here */
+ g_return_val_if_fail (GST_IS_CAPS (caps1), FALSE);
+ g_return_val_if_fail (GST_IS_CAPS (caps2), FALSE);
+
if (G_UNLIKELY (caps1 == caps2))
return TRUE;
- /* one of them NULL => they are different (can't be both NULL because
- * we checked that above) */
- if (G_UNLIKELY (caps1 == NULL || caps2 == NULL))
- return FALSE;
-
if (GST_CAPS_LEN (caps1) != GST_CAPS_LEN (caps2))
return FALSE;
@@ -1135,8 +1079,6 @@ gst_caps_is_strictly_equal (const GstCaps * caps1, const GstCaps * caps2)
* be empty
*
* Returns: %TRUE if intersection would be not empty
- *
- * Since: 0.10.25
*/
gboolean
gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
@@ -1165,7 +1107,7 @@ gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
* much better than a simple loop.
*
* This algorithm zigzags over the caps structures as demonstrated in
- * the folowing matrix:
+ * the following matrix:
*
* caps1 0 1 2 3
* +------------- total distance: +-------------
@@ -1207,7 +1149,7 @@ gst_caps_can_intersect (const GstCaps * caps1, const GstCaps * caps2)
}
static GstCaps *
-gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_intersect_zig_zag (GstCaps * caps1, GstCaps * caps2)
{
guint64 i; /* index can be up to 2 * G_MAX_UINT */
guint j, k, len1, len2;
@@ -1219,17 +1161,17 @@ 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_ref (caps1);
/* empty caps on either side, return empty */
if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
- return gst_caps_new_empty ();
+ return gst_caps_ref (GST_CAPS_NONE);
/* 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_ref (caps2);
if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
- return _gst_caps_copy (caps1);
+ return gst_caps_ref (caps1);
dest = gst_caps_new_empty ();
@@ -1237,7 +1179,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
* much better than a simple loop.
*
* This algorithm zigzags over the caps structures as demonstrated in
- * the folowing matrix:
+ * the following matrix:
*
* caps1
* +-------------
@@ -1266,7 +1208,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
istruct = gst_structure_intersect (struct1, struct2);
- gst_caps_merge_structure (dest, istruct);
+ dest = gst_caps_merge_structure (dest, istruct);
/* move down left */
k++;
if (G_UNLIKELY (j == 0))
@@ -1291,7 +1233,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
* Returns: the new #GstCaps
*/
static GstCaps *
-gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_intersect_first (GstCaps * caps1, GstCaps * caps2)
{
guint i;
guint j, len1, len2;
@@ -1303,17 +1245,17 @@ gst_caps_intersect_first (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_ref (caps1);
/* empty caps on either side, return empty */
if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
- return gst_caps_new_empty ();
+ return gst_caps_ref (GST_CAPS_NONE);
/* 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_ref (caps2);
if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
- return gst_caps_copy (caps1);
+ return gst_caps_ref (caps1);
dest = gst_caps_new_empty ();
@@ -1325,7 +1267,7 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
struct2 = gst_caps_get_structure_unchecked (caps2, j);
istruct = gst_structure_intersect (struct1, struct2);
if (istruct)
- gst_caps_merge_structure (dest, istruct);
+ dest = gst_caps_merge_structure (dest, istruct);
}
}
@@ -1343,10 +1285,9 @@ gst_caps_intersect_first (const GstCaps * caps1, const GstCaps * caps2)
* used.
*
* Returns: the new #GstCaps
- * Since: 0.10.33
*/
GstCaps *
-gst_caps_intersect_full (const GstCaps * caps1, const GstCaps * caps2,
+gst_caps_intersect_full (GstCaps * caps1, GstCaps * caps2,
GstCapsIntersectMode mode)
{
g_return_val_if_fail (GST_IS_CAPS (caps1), NULL);
@@ -1374,7 +1315,7 @@ gst_caps_intersect_full (const GstCaps * caps1, const GstCaps * caps2,
* Returns: the new #GstCaps
*/
GstCaps *
-gst_caps_intersect (const GstCaps * caps1, const GstCaps * caps2)
+gst_caps_intersect (GstCaps * caps1, GstCaps * caps2)
{
return gst_caps_intersect_full (caps1, caps2, GST_CAPS_INTERSECT_ZIG_ZAG);
}
@@ -1453,7 +1394,7 @@ gst_caps_structure_subtract (GSList ** into, const GstStructure * minuend,
* Returns: the resulting caps
*/
GstCaps *
-gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
+gst_caps_subtract (GstCaps * minuend, GstCaps * subtrahend)
{
guint i, j, sublen;
GstStructure *min;
@@ -1467,7 +1408,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_ref (minuend);
/* FIXME: Do we want this here or above?
The reason we need this is that there is no definition about what
@@ -1516,88 +1457,9 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
}
gst_caps_unref (src);
- gst_caps_do_simplify (dest);
- return dest;
-}
-
-/* union operation */
-
-#if 0
-static GstStructure *
-gst_caps_structure_union (const GstStructure * struct1,
- const GstStructure * struct2)
-{
- int i;
- GstStructure *dest;
- const GstStructureField *field1;
- const GstStructureField *field2;
- int ret;
-
- /* FIXME this doesn't actually work */
-
- if (struct1->name != struct2->name)
- return NULL;
-
- dest = gst_structure_new_id_empty (struct1->name);
-
- for (i = 0; i < struct1->fields->len; i++) {
- GValue dest_value = { 0 };
-
- field1 = GST_STRUCTURE_FIELD (struct1, i);
- field2 = gst_structure_id_get_field (struct2, field1->name);
-
- if (field2 == NULL) {
- continue;
- } else {
- if (gst_value_union (&dest_value, &field1->value, &field2->value)) {
- gst_structure_set_value (dest, g_quark_to_string (field1->name),
- &dest_value);
- } else {
- ret = gst_value_compare (&field1->value, &field2->value);
- }
- }
- }
-
+ dest = gst_caps_simplify (dest);
return dest;
}
-#endif
-
-/**
- * gst_caps_union:
- * @caps1: a #GstCaps to union
- * @caps2: a #GstCaps to union
- *
- * Creates a new #GstCaps that contains all the formats that are in
- * either @caps1 and @caps2.
- *
- * Returns: the new #GstCaps
- */
-GstCaps *
-gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
-{
- GstCaps *dest1;
- GstCaps *dest2;
-
- /* NULL pointers are no correct GstCaps */
- g_return_val_if_fail (caps1 != NULL, NULL);
- g_return_val_if_fail (caps2 != NULL, NULL);
-
- if (CAPS_IS_EMPTY (caps1))
- return _gst_caps_copy (caps2);
-
- if (CAPS_IS_EMPTY (caps2))
- 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);
- gst_caps_append (dest1, dest2);
-
- gst_caps_do_simplify (dest1);
- return dest1;
-}
/* normalize/simplify operations */
@@ -1636,34 +1498,36 @@ gst_caps_normalize_foreach (GQuark field_id, const GValue * value, gpointer ptr)
/**
* gst_caps_normalize:
- * @caps: a #GstCaps to normalize
+ * @caps: (transfer full): a #GstCaps to normalize
*
- * Creates a new #GstCaps that represents the same set of formats as
+ * Returns a #GstCaps that represents the same set of formats as
* @caps, but contains no lists. Each list is expanded into separate
* @GstStructures.
*
- * Returns: the new #GstCaps
+ * This function takes ownership of @caps.
+ *
+ * Returns: (transfer full): the normalized #GstCaps
*/
GstCaps *
-gst_caps_normalize (const GstCaps * caps)
+gst_caps_normalize (GstCaps * caps)
{
NormalizeForeach nf;
- GstCaps *newcaps;
guint i;
g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
- newcaps = _gst_caps_copy (caps);
- nf.caps = newcaps;
+ caps = gst_caps_make_writable (caps);
+
+ nf.caps = caps;
- for (i = 0; i < gst_caps_get_size (newcaps); i++) {
- nf.structure = gst_caps_get_structure_unchecked (newcaps, i);
+ for (i = 0; i < gst_caps_get_size (nf.caps); i++) {
+ nf.structure = gst_caps_get_structure_unchecked (nf.caps, i);
while (!gst_structure_foreach (nf.structure,
gst_caps_normalize_foreach, &nf));
}
- return newcaps;
+ return nf.caps;
}
static gint
@@ -1716,7 +1580,7 @@ gst_caps_structure_figure_out_union (GQuark field_id, const GValue * value,
static gboolean
gst_caps_structure_simplify (GstStructure ** result,
- const GstStructure * simplify, GstStructure * compare)
+ GstStructure * simplify, GstStructure * compare)
{
GSList *list;
UnionField field = { 0, {0,}, NULL };
@@ -1739,7 +1603,7 @@ gst_caps_structure_simplify (GstStructure ** result,
/* try to union both structs */
field.compare = compare;
- if (gst_structure_foreach ((GstStructure *) simplify,
+ if (gst_structure_foreach (simplify,
gst_caps_structure_figure_out_union, &field)) {
gboolean ret = FALSE;
@@ -1784,37 +1648,40 @@ gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
}
/**
- * gst_caps_do_simplify:
- * @caps: a #GstCaps to simplify
+ * gst_caps_simplify:
+ * @caps: (transfer full): a #GstCaps to simplify
*
- * Modifies the given @caps inplace into a representation that represents the
+ * Converts the given @caps into a representation that represents the
* same set of formats, but in a simpler form. Component structures that are
* identical are merged. Component structures that have values that can be
* merged are also merged.
*
- * Returns: TRUE, if the caps could be simplified
+ * This method does not preserve the original order of @caps.
+ *
+ * Returns: The simplified caps.
*/
-gboolean
-gst_caps_do_simplify (GstCaps * caps)
+GstCaps *
+gst_caps_simplify (GstCaps * caps)
{
GstStructure *simplify, *compare, *result = NULL;
gint i, j, start;
- gboolean changed = FALSE;
- g_return_val_if_fail (caps != NULL, FALSE);
- g_return_val_if_fail (IS_WRITABLE (caps), FALSE);
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
- if (gst_caps_get_size (caps) < 2)
- return FALSE;
+ start = GST_CAPS_LEN (caps) - 1;
+ /* one caps, already as simple as can be */
+ if (start == 0)
+ return caps;
+
+ caps = gst_caps_make_writable (caps);
g_ptr_array_sort (GST_CAPS_ARRAY (caps), gst_caps_compare_structures);
- start = GST_CAPS_LEN (caps) - 1;
- for (i = GST_CAPS_LEN (caps) - 1; i >= 0; i--) {
+ for (i = start; i >= 0; i--) {
simplify = gst_caps_get_structure_unchecked (caps, i);
+ compare = gst_caps_get_structure_unchecked (caps, start);
if (gst_structure_get_name_id (simplify) !=
- gst_structure_get_name_id (gst_caps_get_structure_unchecked (caps,
- start)))
+ gst_structure_get_name_id (compare))
start = i;
for (j = start; j >= 0; j--) {
if (j == i)
@@ -1833,38 +1700,36 @@ gst_caps_do_simplify (GstCaps * caps)
start--;
break;
}
- changed = TRUE;
}
}
}
-
- if (!changed)
- return FALSE;
-
- /* gst_caps_do_simplify (caps); */
- return TRUE;
+ return caps;
}
/**
* gst_caps_fixate:
- * @caps: a #GstCaps to fixate
+ * @caps: (transfer full): a #GstCaps to fixate
*
- * Modifies the given @caps inplace into a representation with only fixed
+ * Modifies the given @caps 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.
+ * fixated with gst_structure_fixate().
+ *
+ * Returns: (transfer full): the fixated caps
*/
-void
+GstCaps *
gst_caps_fixate (GstCaps * caps)
{
GstStructure *s;
- g_return_if_fail (GST_IS_CAPS (caps));
- g_return_if_fail (IS_WRITABLE (caps));
+ g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
/* default fixation */
- gst_caps_truncate (caps);
+ caps = gst_caps_truncate (caps);
+ caps = gst_caps_make_writable (caps);
s = gst_caps_get_structure (caps, 0);
gst_structure_fixate (s);
+
+ return caps;
}
/* utility */
@@ -1880,7 +1745,7 @@ gst_caps_fixate (GstCaps * caps)
* |[
* GST_LOG ("caps are %" GST_PTR_FORMAT, caps);
* ]|
- * This prints the caps in human readble form.
+ * This prints the caps in human readable form.
*
* Returns: (transfer full): a newly allocated string representing @caps.
*/