summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2014-07-18 15:51:01 +0200
committerWim Taymans <wtaymans@redhat.com>2014-07-18 15:51:01 +0200
commit1aa09170320fda255753052df5d71c416c9df05e (patch)
tree52a8e0f51716d09052cf5fe124213ea860ec5b36
parent4c38895f4b71cabecd857e1fbc765b01aad21867 (diff)
caps: add MIXED capsmixed-caps
MIXED caps have a list of structures and are considered fixed when all structures are fixed. They can be used to specify caps on a stream that contains buffers in multiple formats.
-rw-r--r--gst/gstcaps.c100
-rw-r--r--gst/gstcaps.h8
-rw-r--r--gst/parse/parse.l9
-rw-r--r--win32/common/libgstreamer.def2
4 files changed, 100 insertions, 19 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;
diff --git a/gst/gstcaps.h b/gst/gstcaps.h
index 4b09b8eb7..ddb487c3d 100644
--- a/gst/gstcaps.h
+++ b/gst/gstcaps.h
@@ -41,11 +41,14 @@ GST_EXPORT GType _gst_caps_type;
* GstCapsFlags:
* @GST_CAPS_FLAG_ANY: Caps has no specific content, but can contain
* anything.
+ * @GST_CAPS_FLAG_MIXED: the caps contains multiple format
+ * descriptions, the active format description is media dependent.
*
* Extra flags for a caps.
*/
typedef enum {
- GST_CAPS_FLAG_ANY = (GST_MINI_OBJECT_FLAG_LAST << 0)
+ GST_CAPS_FLAG_ANY = (GST_MINI_OBJECT_FLAG_LAST << 0),
+ GST_CAPS_FLAG_MIXED = (GST_MINI_OBJECT_FLAG_LAST << 1)
} GstCapsFlags;
/**
@@ -375,6 +378,8 @@ GstCaps * gst_caps_new_full (GstStructure *struct1,
...) G_GNUC_NULL_TERMINATED G_GNUC_WARN_UNUSED_RESULT;
GstCaps * gst_caps_new_full_valist (GstStructure *structure,
va_list var_args) G_GNUC_WARN_UNUSED_RESULT;
+GstCaps * gst_caps_new_mixed (GstStructure *struct1,
+ ...) G_GNUC_NULL_TERMINATED G_GNUC_WARN_UNUSED_RESULT;
GType gst_static_caps_get_type (void);
GstCaps * gst_static_caps_get (GstStaticCaps *static_caps);
@@ -421,6 +426,7 @@ void gst_caps_set_simple_valist (GstCaps *caps,
gboolean gst_caps_is_any (const GstCaps *caps);
gboolean gst_caps_is_empty (const GstCaps *caps);
gboolean gst_caps_is_fixed (const GstCaps *caps);
+gboolean gst_caps_is_mixed (const GstCaps *caps);
gboolean gst_caps_is_always_compatible (const GstCaps *caps1,
const GstCaps *caps2);
gboolean gst_caps_is_subset (const GstCaps *subset,
diff --git a/gst/parse/parse.l b/gst/parse/parse.l
index 53afba8b6..f9de9abeb 100644
--- a/gst/parse/parse.l
+++ b/gst/parse/parse.l
@@ -72,10 +72,11 @@ _binref {_identifier}[[:space:]]*"."[[:space:]]*"("
/* links */
_mimechar [[:alnum:]-]
_mimetype {_mimechar}+"/"{_mimechar}+
-_capschar ("\\".)|([^\;!])
-_capsstring {_capschar}+
-_caps {_mimetype}(","[^!]|{_capsstring})*
-_link ("!"[[:space:]]*{_caps}([[:space:]]*(";"[[:space:]]*{_caps})*[[:space:]]*)*"!")|("!")
+_structchar ("\\".)|([^\;!])
+_structstring {_structchar}+
+_struct {_mimetype}(","[^!]|{_structstring})*
+_caps ("(MIXED)"[[:space:]]*)?{_struct}([[:space:]]*";"[[:space:]]*{_struct})*
+_link ("!"[[:space:]]*{_caps}[[:space:]]*"!")|("!")
%x value
%option noyywrap
diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def
index 2fda6b69f..df617cd8d 100644
--- a/win32/common/libgstreamer.def
+++ b/win32/common/libgstreamer.def
@@ -256,6 +256,7 @@ EXPORTS
gst_caps_is_equal
gst_caps_is_equal_fixed
gst_caps_is_fixed
+ gst_caps_is_mixed
gst_caps_is_strictly_equal
gst_caps_is_subset
gst_caps_is_subset_structure
@@ -268,6 +269,7 @@ EXPORTS
gst_caps_new_empty_simple
gst_caps_new_full
gst_caps_new_full_valist
+ gst_caps_new_mixed
gst_caps_new_simple
gst_caps_normalize
gst_caps_remove_structure