diff options
Diffstat (limited to 'gst/gstcaps.c')
-rw-r--r-- | gst/gstcaps.c | 100 |
1 files changed, 86 insertions, 14 deletions
diff --git a/gst/gstcaps.c b/gst/gstcaps.c index 51f7ae4e0..50c4cb356 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -56,6 +56,10 @@ * support one level of nesting. Using more levels will lead to unexpected * behavior when using serialization features, such as gst_caps_to_string() or * gst_value_serialize() and their counterparts. + * + * Since 1.6, Mixed caps can be created. These are caps that contain multiple + * (fixed) structures that each describe a format. The actual structure that + * describes a buffer must be determined in a media specific way. */ #ifdef HAVE_CONFIG_H @@ -93,6 +97,8 @@ typedef struct _GstCapsImpl /* same as gst_caps_is_any () */ #define CAPS_IS_ANY(caps) \ (!!(GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_ANY)) +#define CAPS_IS_MIXED(caps) \ + (!!(GST_CAPS_FLAGS(caps) & GST_CAPS_FLAG_MIXED)) /* same as gst_caps_is_empty () */ #define CAPS_IS_EMPTY(caps) \ @@ -371,6 +377,33 @@ gst_caps_new_full_valist (GstStructure * structure, va_list var_args) return caps; } +/** + * gst_caps_new_mixed: + * @struct1: the first structure to add + * @...: additional structures to add + * + * Creates a new mixed #GstCaps and adds all the structures listed as + * arguments. The list must be %NULL-terminated. The structures + * are not copied; the returned #GstCaps owns the structures. + * + * Returns: (transfer full): the new mixed #GstCaps + * + * Since: 1.6 + */ +GstCaps * +gst_caps_new_mixed (GstStructure * struct1, ...) +{ + GstCaps *caps; + va_list var_args; + + va_start (var_args, struct1); + caps = gst_caps_new_full_valist (struct1, var_args); + GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_MIXED); + va_end (var_args); + + return caps; +} + G_DEFINE_POINTER_TYPE (GstStaticCaps, gst_static_caps); /** @@ -1090,6 +1123,24 @@ gst_caps_is_empty (const GstCaps * caps) return CAPS_IS_EMPTY_SIMPLE (caps); } +/** + * gst_caps_is_mixed: + * @caps: the #GstCaps to test + * + * Determines if @caps represents a mixed media format. + * + * Returns: %TRUE if @caps represents a mixed format. + * + * Since: 1.6 + */ +gboolean +gst_caps_is_mixed (const GstCaps * caps) +{ + g_return_val_if_fail (GST_IS_CAPS (caps), FALSE); + + return (CAPS_IS_MIXED (caps)); +} + static gboolean gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value, gpointer unused) @@ -1105,6 +1156,9 @@ gst_caps_is_fixed_foreach (GQuark field_id, const GValue * value, * one structure, and each field in the structure describes a fixed type. * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST. * + * Since 1.6, Mixed caps are allowed to have multiple structures and is fixed when + * all of the structures are fixed. + * * Returns: %TRUE if @caps is fixed */ gboolean @@ -1115,7 +1169,7 @@ gst_caps_is_fixed (const GstCaps * caps) g_return_val_if_fail (GST_IS_CAPS (caps), FALSE); - if (GST_CAPS_LEN (caps) != 1) + if (GST_CAPS_LEN (caps) != 1 && !CAPS_IS_MIXED (caps)) return FALSE; features = gst_caps_get_features_unchecked (caps, 0); @@ -2053,8 +2107,8 @@ gst_caps_simplify (GstCaps * caps) g_return_val_if_fail (GST_IS_CAPS (caps), NULL); start = GST_CAPS_LEN (caps) - 1; - /* one caps, already as simple as can be */ - if (start == 0) + /* one caps or mixed, already as simple as can be */ + if (start == 0 || CAPS_IS_MIXED (caps)) return caps; caps = gst_caps_make_writable (caps); @@ -2109,6 +2163,8 @@ gst_caps_simplify (GstCaps * caps) * values. First the caps will be truncated and then the first structure will be * fixated with gst_structure_fixate(). * + * Mixed caps will have each of the structures be fixated. + * * Returns: (transfer full): the fixated caps */ GstCaps * @@ -2116,22 +2172,27 @@ gst_caps_fixate (GstCaps * caps) { GstStructure *s; GstCapsFeatures *f; + guint i, len; g_return_val_if_fail (GST_IS_CAPS (caps), NULL); /* default fixation */ - caps = gst_caps_truncate (caps); + if (!CAPS_IS_MIXED (caps)) + caps = gst_caps_truncate (caps); caps = gst_caps_make_writable (caps); - 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_unchecked (caps, 0); - if (f && gst_caps_features_is_any (f)) { - f = gst_caps_features_new_empty (); - gst_caps_set_features (caps, 0, f); - } + len = GST_CAPS_LEN (caps); + for (i = 0; i < len; i++) { + s = gst_caps_get_structure (caps, i); + gst_structure_fixate (s); + + /* Set features to sysmem if they're still ANY */ + f = gst_caps_get_features_unchecked (caps, i); + if (f && gst_caps_features_is_any (f)) { + f = gst_caps_features_new_empty (); + gst_caps_set_features (caps, i, f); + } + } return caps; } @@ -2160,6 +2221,7 @@ gst_caps_to_string (const GstCaps * caps) { guint i, slen, clen; GString *s; + gboolean mixed; /* NOTE: This function is potentially called by the debug system, * so any calls to gst_log() (and GST_DEBUG(), GST_LOG(), etc.) @@ -2177,8 +2239,10 @@ gst_caps_to_string (const GstCaps * caps) return g_strdup ("EMPTY"); } + mixed = CAPS_IS_MIXED (caps); + /* estimate a rough string length to avoid unnecessary reallocs in GString */ - slen = 0; + slen = mixed ? 6 : 0; clen = GST_CAPS_LEN (caps); for (i = 0; i < clen; i++) { GstCapsFeatures *f; @@ -2192,6 +2256,9 @@ gst_caps_to_string (const GstCaps * caps) } s = g_string_sized_new (slen); + if (mixed) + g_string_append (s, "(MIXED)"); + for (i = 0; i < clen; i++) { GstStructure *structure; GstCapsFeatures *features; @@ -2236,6 +2303,11 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string) return TRUE; } + if (g_ascii_strncasecmp ("(MIXED)", string, 7) == 0) { + GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAG_MIXED); + string += 7; + } + copy = s = g_strdup (string); do { GstCapsFeatures *features = NULL; |