summaryrefslogtreecommitdiff
path: root/gst/gstcaps.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/gstcaps.c')
-rw-r--r--gst/gstcaps.c100
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;