diff options
author | Wim Taymans <wtaymans@redhat.com> | 2014-07-18 15:51:01 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2014-07-18 15:51:01 +0200 |
commit | 1aa09170320fda255753052df5d71c416c9df05e (patch) | |
tree | 52a8e0f51716d09052cf5fe124213ea860ec5b36 | |
parent | 4c38895f4b71cabecd857e1fbc765b01aad21867 (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.c | 100 | ||||
-rw-r--r-- | gst/gstcaps.h | 8 | ||||
-rw-r--r-- | gst/parse/parse.l | 9 | ||||
-rw-r--r-- | win32/common/libgstreamer.def | 2 |
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 |