From 58b18a36248e3cccd8657a4fd4ad4c914268f889 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 29 Nov 2003 06:31:10 +0000 Subject: [PATCH] Merge gstvalue and gststructure from CAPS branch Original commit message from CVS: Merge gstvalue and gststructure from CAPS branch --- gst/gststructure.c | 482 +++++++++++++++++++++++++++++++++++++++++++-- gst/gststructure.h | 9 +- gst/gsttag.c | 6 +- gst/gsttaglist.c | 6 +- gst/gstvalue.c | 199 +++++++++++++++++-- gst/gstvalue.h | 20 +- 6 files changed, 679 insertions(+), 43 deletions(-) diff --git a/gst/gststructure.c b/gst/gststructure.c index f92dd32f59..763ead55fc 100644 --- a/gst/gststructure.c +++ b/gst/gststructure.c @@ -601,7 +601,7 @@ gst_structure_remove_all_fields(GstStructure *structure) * @fieldname: the name of the field * * Finds the field with the given name, and returns the type of the - * value it contains. If the field is not found, G_TYPE_NONE is + * value it contains. If the field is not found, G_TYPE_INVALID is * returned. * * Returns: the #GValue of the field @@ -611,11 +611,11 @@ gst_structure_get_field_type(const GstStructure *structure, const gchar *fieldna { GstStructureField *field; - g_return_val_if_fail(structure != NULL, G_TYPE_NONE); - g_return_val_if_fail(fieldname != NULL, G_TYPE_NONE); + g_return_val_if_fail(structure != NULL, G_TYPE_INVALID); + g_return_val_if_fail(fieldname != NULL, G_TYPE_INVALID); field = gst_structure_get_field(structure, fieldname); - if(field == NULL) return G_TYPE_NONE; + if(field == NULL) return G_TYPE_INVALID; return G_VALUE_TYPE(&field->value); } @@ -865,6 +865,67 @@ gst_structure_get_string(const GstStructure *structure, const gchar *fieldname) return g_value_get_string(&field->value); } +typedef struct _GstStructureAbbreviation { + char *type_name; + GType type; +} GstStructureAbbreviation; + +static GstStructureAbbreviation _gst_structure_abbrs[] = { + { "int", G_TYPE_INT }, + { "i", G_TYPE_INT }, + { "float", G_TYPE_FLOAT }, + { "f", G_TYPE_FLOAT }, + { "double", G_TYPE_DOUBLE }, + { "d", G_TYPE_DOUBLE }, +//{ "fourcc", GST_TYPE_FOURCC }, + { "boolean", G_TYPE_BOOLEAN }, + { "bool", G_TYPE_BOOLEAN }, + { "b", G_TYPE_BOOLEAN }, + { "string", G_TYPE_STRING }, + { "str", G_TYPE_STRING }, + { "s", G_TYPE_STRING } +}; + +static GType _gst_structure_from_abbr(const char *type_name) +{ + int i; + + g_return_val_if_fail(type_name != NULL, G_TYPE_INVALID); + + for(i=0;iname)); for(i=0;ifields->len;i++){ GValue s_val = { 0 }; + GType type; field = GST_STRUCTURE_FIELD(structure, i); g_value_init(&s_val, G_TYPE_STRING); + g_value_transform (&field->value, &s_val); - g_value_transform(&field->value, &s_val); - g_string_append_printf(s, ", %s:%s", g_quark_to_string(field->name), - g_value_get_string(&s_val)); - g_value_unset(&s_val); + type = G_VALUE_TYPE (&field->value); + + if (type == GST_TYPE_LIST) { + GPtrArray *ptr_array = g_value_peek_pointer (&field->value); + if (ptr_array->len > 0){ + GValue *value = g_ptr_array_index (ptr_array, 0); + + type = G_VALUE_TYPE (value); + } else { + type = G_TYPE_INT; + } + } else if (G_VALUE_TYPE(&field->value) == GST_TYPE_INT_RANGE) { + type = G_TYPE_INT; + } else if (G_VALUE_TYPE(&field->value) == GST_TYPE_DOUBLE_RANGE) { + type = G_TYPE_DOUBLE; + } + g_string_append_printf(s, ", %s:%s=%s", g_quark_to_string(field->name), + _gst_structure_to_abbr(type), g_value_get_string(&s_val)); + g_value_unset (&s_val); } return g_string_free(s, FALSE); } +/* + * r will still point to the string. if end == next, the string will not be + * null-terminated. In all other cases it will be. + * end = pointer to char behind end of string, next = pointer to start of + * unread data. + * THIS FUNCTION MODIFIES THE STRING AND DETECTS INSIDE A NONTERMINATED STRING + */ +static gboolean +_gst_structure_parse_string (gchar *r, gchar **end, gchar **next) +{ + gchar *w; + gchar c = '\0'; + + w = r; + if (*r == '\'' || *r == '\"') { + c = *r; + r++; + } + + for (;;r++) { + if (*r == '\0') { + if (c) { + goto error; + } else { + goto found; + } + } + + if (*r == '\\') { + r++; + if (*r == '\0') + goto error; + *w++ = *r; + continue; + } + + if (*r == c) { + r++; + if (*r == '\0') + goto found; + break; + } + + if (!c) { + if (g_ascii_isspace (*r)) + break; + /* this needs to be escaped */ + if (*r == ',' || *r == ')' || *r == ']' || *r == ':' || + *r == ';' || *r == '(' || *r == '[') + break; + } + *w++ = *r; + } + +found: + while (g_ascii_isspace (*r)) r++; + if (w != r) + *w++ = '\0'; + *end = w; + *next = r; + return TRUE; + +error: + return FALSE; +} + +static gboolean +_gst_structure_parse_value (gchar *s, gchar **after, GType type, + GValue *value) +{ + gboolean ret = FALSE; + gchar *val; + gchar *end; + + if (type == G_TYPE_INVALID) return FALSE; + + while (g_ascii_isspace (*s)) s++; + + g_value_init(value, type); + + val = s; + switch (type) { + case G_TYPE_INT: + { + int x; + x = strtol (val, &s, 0); + if (val != s) { + g_value_set_int (value, x); + ret = TRUE; + } + } + break; + case G_TYPE_FLOAT: + { + double x; + x = g_ascii_strtod (val, &s); + if (val != s) { + g_value_set_float (value, x); + ret = TRUE; + } + } + break; + case G_TYPE_DOUBLE: + { + double x; + x = g_ascii_strtod (val, &s); + if (val != s) { + g_value_set_double (value, x); + ret = TRUE; + } + } + break; + case G_TYPE_BOOLEAN: + { + int len; + + ret = _gst_structure_parse_string (val, &end, &s); + len = end - val; + if (ret && len > 0) { + if (g_ascii_strncasecmp (val, "true", len) == 0 || + g_ascii_strncasecmp (val, "yes", len) == 0 || + g_ascii_strncasecmp (val, "t", len) == 0 || + strncmp (val, "1", len)) { + g_value_set_boolean (value, TRUE); + } else if (g_ascii_strncasecmp (val, "false", len) == 0 || + g_ascii_strncasecmp (val, "no", len) == 0 || + g_ascii_strncasecmp (val, "f", len) == 0 || + strncmp (val, "0", len)) { + g_value_set_boolean (value, FALSE); + } else { + ret = FALSE; + } + } + } + break; + case G_TYPE_STRING: + { + ret = _gst_structure_parse_string (val, &end, &s); + if (ret) { + g_value_set_string_take_ownership (value, + g_strndup(val, end - val)); + ret = TRUE; + } + } + break; + default: + /* FIXME: make more general */ + if (type == GST_TYPE_FOURCC) { + guint32 fourcc = 0; + if (g_ascii_isdigit (*s)) { + fourcc = strtoul (val, &s, 0); + if (val != s) { + ret = TRUE; + } + } else { + ret = _gst_structure_parse_string (val, &end, &s); +g_print("end - val = %d\n", end - val); + if (end - val >= 4) { + fourcc = GST_MAKE_FOURCC(val[0], val[1], val[2], val[3]); + ret = TRUE; + } + } + gst_value_set_fourcc (value, fourcc); + } else { + g_critical("type %s not handled", g_type_name(type)); + } + break; + } + + *after = s; + + return ret; +} + +static gboolean +_gst_structure_parse_range (gchar *s, gchar **after, GType type, + GValue *value) +{ + GValue value1 = { 0 }; + GValue value2 = { 0 }; + GType range_type; + gboolean ret; + + if (type == G_TYPE_DOUBLE) { + range_type = GST_TYPE_DOUBLE_RANGE; + } else if (type == G_TYPE_INT) { + range_type = GST_TYPE_INT_RANGE; + } else { + return FALSE; + } + +g_print("%d \"%s\"\n", __LINE__, s); + if (*s != '[') return FALSE; + s++; + +g_print("%d \"%s\"\n", __LINE__, s); + ret = _gst_structure_parse_value(s, &s, type, &value1); + if (ret == FALSE) return FALSE; + + while (g_ascii_isspace (*s)) s++; + +g_print("%d \"%s\"\n", __LINE__, s); + if (*s != ',') return FALSE; + s++; + + while (g_ascii_isspace (*s)) s++; + +g_print("%d \"%s\"\n", __LINE__, s); + ret = _gst_structure_parse_value(s, &s, type, &value2); + if (ret == FALSE) return FALSE; + + while (g_ascii_isspace (*s)) s++; + +g_print("%d \"%s\"\n", __LINE__, s); + if (*s != ']') return FALSE; + s++; + + g_value_init(value, range_type); + if (range_type == GST_TYPE_DOUBLE_RANGE) { + gst_value_set_double_range(value, g_value_get_double(&value1), + g_value_get_double(&value2)); + } else { + gst_value_set_int_range(value, g_value_get_int(&value1), + g_value_get_int(&value2)); + } + + *after = s; + return TRUE; +} + +static gboolean +_gst_structure_parse_list (gchar *s, gchar **after, GType type, GValue *value) +{ + GValue list_value = { 0 }; + gboolean ret; + + g_value_init(value, GST_TYPE_LIST); + + if (*s != '(') return FALSE; + s++; + + while (g_ascii_isspace (*s)) s++; + if (*s == ')') { + s++; + *after = s; + return TRUE; + } + + ret = _gst_structure_parse_value(s, &s, type, &list_value); + if (ret == FALSE) return FALSE; + + while (g_ascii_isspace (*s)) s++; + + while (*s != ')') { + if (*s != ',') return FALSE; + s++; + + while (g_ascii_isspace (*s)) s++; + + memset (&list_value, 0, sizeof (list_value)); + ret = _gst_structure_parse_value(s, &s, type, &list_value); + if (ret == FALSE) return FALSE; + + while (g_ascii_isspace (*s)) s++; + } + + s++; + + *after = s; + return TRUE; +} + +static gboolean +_gst_structure_parse_field (gchar *str, gchar **after, GstStructureField *field) +{ + /* NAME[:TYPE]=VALUE */ + gchar *name; + gchar *type_name; + gchar *s, *del; + gboolean have_type = FALSE; + GType type = G_TYPE_INVALID; + int ret; + +g_print("parsing: \"%s\"\n", str); + name = s = str; + while (g_ascii_isalnum (*s) || *s == '_' || *s == '-') s++; + del = s; + while (g_ascii_isspace (*s)) s++; + if (!(*s == '=' || *s == ':')) return FALSE; + if (*s == ':') have_type = TRUE; + s++; + while (g_ascii_isspace (*s)) s++; + *del = '\0'; + + field->name = g_quark_from_string (name); + + if (have_type) { + while (g_ascii_isspace (*s)) s++; + type_name = s; + while (g_ascii_isalnum (*s) || *s == '_' || *s == '-') s++; + del = s; + while (g_ascii_isspace (*s)) s++; + if (*s != '=') return FALSE; + s++; + while (g_ascii_isspace (*s)) s++; + *del = '\0'; + +g_print("type name is \"%s\"\n",type_name); + type = _gst_structure_from_abbr(type_name); +g_print("type n is \"%s\"\n",g_type_name(type)); + + if (type == G_TYPE_INVALID) return FALSE; + + } else { + if (g_ascii_isdigit (*s) || + ((*s == '-' || *s == '+') && g_ascii_isdigit (s[1]))) { + char *t = s; + while (g_ascii_isdigit (*t)) t++; + if (*t == '.'){ + type = G_TYPE_DOUBLE; + } else { + type = G_TYPE_INT; + } + } else if (g_ascii_isalpha (*s) || *s == '"' || *s == '\'') { + type = G_TYPE_STRING; + } + } + + if (*s == '[') { + ret = _gst_structure_parse_range (s, &s, type, &field->value); + } else if (*s == '(') { + ret = _gst_structure_parse_list (s, &s, type, &field->value); + } else { + ret = _gst_structure_parse_value(s, &s, type, &field->value); + } + + *after = s; + + return ret; +} + /** * gst_structure_from_string: * @structure: a #GstStructure @@ -908,15 +1327,54 @@ gst_structure_to_string(const GstStructure *structure) * Returns: a new #GstStructure */ GstStructure * -gst_structure_from_string (const gchar *string) +gst_structure_from_string (const gchar *string, gchar **end) { - /* FIXME */ + char *name; + char *copy; + char *w; + char *r; + char save; + GstStructure *structure; + GstStructureField field = { 0 }; + gboolean res; g_return_val_if_fail(string != NULL, NULL); - g_assert_not_reached(); + copy = g_strdup(string); + r = copy; - return NULL; + name = r; + res = _gst_structure_parse_string (r, &w, &r); + if (!res) return NULL; + + while (g_ascii_isspace(*r)) r++; + if(*r != 0 && *r != ';' && *r != ',') return NULL; + + save = *w; + *w = 0; + structure = gst_structure_empty_new(name); + *w = save; + + while (*r && (*r != ';')){ + if(*r != ',') { + return NULL; + } + r++; + while (*r && g_ascii_isspace(*r)) r++; + + memset(&field,0,sizeof(field)); + res = _gst_structure_parse_field (r, &r, &field); +g_print("returned %d \"%s\"\n", res, r); + if (!res) { + gst_structure_free (structure); + return NULL; + } + gst_structure_set_field(structure, &field); + while (*r && g_ascii_isspace(*r)) r++; + } + + if (end) *end = (char *)string + (r - copy); + return structure; } static void diff --git a/gst/gststructure.h b/gst/gststructure.h index 4ea6b10c6d..15967c8c5b 100644 --- a/gst/gststructure.h +++ b/gst/gststructure.h @@ -59,7 +59,7 @@ GstStructure *gst_structure_new_valist(const gchar *name, GstStructure *gst_structure_copy(GstStructure *structure); void gst_structure_free(GstStructure *structure); -const gchar *gst_structure_get_name(GstStructure *structure); +G_CONST_RETURN gchar *gst_structure_get_name(GstStructure *structure); void gst_structure_set_name(GstStructure *structure, const gchar *name); void gst_structure_set_field_copy (GstStructure *structure, const GstStructureField *field); @@ -73,7 +73,8 @@ void gst_structure_set_value(GstStructure *structure, const gchar *field, void gst_structure_set(GstStructure *structure, const gchar *field, ...); void gst_structure_set_valist(GstStructure *structure, const gchar *field, va_list varargs); -const GValue *gst_structure_get_value(const GstStructure *structure, const gchar *field); +G_CONST_RETURN GValue *gst_structure_get_value(const GstStructure *structure, + const gchar *field); GstStructureField *gst_structure_get_field(const GstStructure *structure, const gchar *fieldname); GstStructureField *gst_structure_id_get_field(const GstStructure *structure, @@ -100,11 +101,11 @@ gboolean gst_structure_get_fourcc(const GstStructure *structure, const gchar *fi guint32 *value); gboolean gst_structure_get_double(const GstStructure *structure, const gchar *field, gdouble *value); -const gchar *gst_structure_get_string(const GstStructure *structure, +G_CONST_RETURN gchar *gst_structure_get_string(const GstStructure *structure, const gchar *field); gchar * gst_structure_to_string(const GstStructure *structure); -GstStructure * gst_structure_from_string (const gchar *string); +GstStructure * gst_structure_from_string (const gchar *string, gchar **end); G_END_DECLS diff --git a/gst/gsttag.c b/gst/gsttag.c index e2761e0e05..558939b039 100644 --- a/gst/gsttag.c +++ b/gst/gsttag.c @@ -245,7 +245,7 @@ gst_tag_register (gchar *name, GType type, gchar *nick, gchar *blurb, g_return_if_fail (name != NULL); g_return_if_fail (nick != NULL); g_return_if_fail (blurb != NULL); - g_return_if_fail (type != 0 && type != GST_VALUE_TYPE_LIST); + g_return_if_fail (type != 0 && type != GST_TYPE_LIST); key = g_quark_from_string (name); info = gst_tag_lookup (key); @@ -547,7 +547,7 @@ gst_tag_list_get_tag_size (const GstTagList *list, const gchar *tag) value = gst_structure_get_value ((GstStructure *) list, tag); if (value == NULL) return 0; - if (G_VALUE_TYPE (value) != GST_VALUE_TYPE_LIST) + if (G_VALUE_TYPE (value) != GST_TYPE_LIST) return 1; return gst_value_list_get_size (value); @@ -761,7 +761,7 @@ gst_tag_list_copy_value (GValue *dest, const GstTagList *list, const gchar *tag) src = gst_structure_get_value ((GstStructure *) list, tag); if (!src) return FALSE; - if (G_VALUE_TYPE (src) == GST_VALUE_TYPE_LIST) { + if (G_VALUE_TYPE (src) == GST_TYPE_LIST) { GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag)); /* must be there or lists aren't allowed */ g_assert (info->merge_func); diff --git a/gst/gsttaglist.c b/gst/gsttaglist.c index e2761e0e05..558939b039 100644 --- a/gst/gsttaglist.c +++ b/gst/gsttaglist.c @@ -245,7 +245,7 @@ gst_tag_register (gchar *name, GType type, gchar *nick, gchar *blurb, g_return_if_fail (name != NULL); g_return_if_fail (nick != NULL); g_return_if_fail (blurb != NULL); - g_return_if_fail (type != 0 && type != GST_VALUE_TYPE_LIST); + g_return_if_fail (type != 0 && type != GST_TYPE_LIST); key = g_quark_from_string (name); info = gst_tag_lookup (key); @@ -547,7 +547,7 @@ gst_tag_list_get_tag_size (const GstTagList *list, const gchar *tag) value = gst_structure_get_value ((GstStructure *) list, tag); if (value == NULL) return 0; - if (G_VALUE_TYPE (value) != GST_VALUE_TYPE_LIST) + if (G_VALUE_TYPE (value) != GST_TYPE_LIST) return 1; return gst_value_list_get_size (value); @@ -761,7 +761,7 @@ gst_tag_list_copy_value (GValue *dest, const GstTagList *list, const gchar *tag) src = gst_structure_get_value ((GstStructure *) list, tag); if (!src) return FALSE; - if (G_VALUE_TYPE (src) == GST_VALUE_TYPE_LIST) { + if (G_VALUE_TYPE (src) == GST_TYPE_LIST) { GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag)); /* must be there or lists aren't allowed */ g_assert (info->merge_func); diff --git a/gst/gstvalue.c b/gst/gstvalue.c index 79586e8452..c13cc802d8 100644 --- a/gst/gstvalue.c +++ b/gst/gstvalue.c @@ -48,7 +48,7 @@ struct _GstValueIntersectInfo { GType gst_type_fourcc; GType gst_type_int_range; GType gst_type_double_range; -GType gst_value_type_list; +GType gst_type_list; GArray *gst_value_compare_funcs; GArray *gst_value_union_funcs; @@ -169,6 +169,42 @@ gst_value_list_get_value (const GValue *value, guint index) return (const GValue *) &g_array_index ((GArray *) value->data[0].v_pointer, GValue, index); } +/* special case function for any union */ +static gboolean +gst_value_union_lists (GValue *dest, const GValue *value1, const GValue *value2) +{ + guint i, value1_length, value2_length; + GArray *array; + + value1_length = (GST_VALUE_HOLDS_LIST (value1) ? gst_value_list_get_size (value1) : 1); + value2_length = (GST_VALUE_HOLDS_LIST (value2) ? gst_value_list_get_size (value2) : 1); + g_value_init (dest, GST_TYPE_LIST); + array = (GArray *) dest->data[0].v_pointer; + g_array_set_size (array, value1_length + value2_length); + + if (GST_VALUE_HOLDS_LIST (value1)) { + for (i = 0; i < value1_length; i++) { + g_value_init (&g_array_index(array, GValue, i), G_VALUE_TYPE (gst_value_list_get_value (value1, i))); + g_value_copy (gst_value_list_get_value (value1, i), &g_array_index(array, GValue, i)); + } + } else { + g_value_init (&g_array_index(array, GValue, 0), G_VALUE_TYPE (value1)); + g_value_copy (value1, &g_array_index(array, GValue, 0)); + } + + if (GST_VALUE_HOLDS_LIST (value2)) { + for (i = 0; i < value2_length; i++) { + g_value_init (&g_array_index(array, GValue, i + value1_length), G_VALUE_TYPE (gst_value_list_get_value (value2, i))); + g_value_copy (gst_value_list_get_value (value2, i), &g_array_index(array, GValue, i + value1_length)); + } + } else { + g_value_init (&g_array_index(array, GValue, value1_length), G_VALUE_TYPE (value2)); + g_value_copy (value2, &g_array_index(array, GValue, value1_length)); + } + + return TRUE; +} + /** * gst_value_list_concat: * @dest: an uninitialized #GValue to take the result @@ -176,7 +212,7 @@ gst_value_list_get_value (const GValue *value, guint index) * @value2: second value to put into the union * * Concatenates copies of value1 and value2 into a list. dest will be - * initialized to the type GST_VALUE_TYPE_LIST. + * initialized to the type GST_TYPE_LIST. */ void gst_value_list_concat (GValue *dest, const GValue *value1, const GValue *value2) @@ -191,7 +227,7 @@ gst_value_list_concat (GValue *dest, const GValue *value1, const GValue *value2) value1_length = (GST_VALUE_HOLDS_LIST (value1) ? gst_value_list_get_size (value1) : 1); value2_length = (GST_VALUE_HOLDS_LIST (value2) ? gst_value_list_get_size (value2) : 1); - g_value_init (dest, GST_VALUE_TYPE_LIST); + g_value_init (dest, GST_TYPE_LIST); array = (GArray *) dest->data[0].v_pointer; g_array_set_size (array, value1_length + value2_length); @@ -402,14 +438,43 @@ gst_value_get_double_range_max (const GValue *value) return value->data[1].v_double; } +/* GstCaps */ + +#if 0 +void +gst_value_set_caps (GValue *value, const GstCaps2 *caps) +{ + g_return_if_fail (GST_VALUE_HOLDS_CAPS (value)); + + value->data[0].v_pointer = gst_caps2_copy (caps); +} + +const GstCaps2 * +gst_value_get_caps (const GValue *value) +{ + g_return_val_if_fail (GST_VALUE_HOLDS_CAPS (value), 0); + + return value->data[0].v_pointer; +} +#endif + /* fourcc */ static void gst_value_transform_fourcc_string (const GValue *src_value, GValue *dest_value) { - dest_value->data[0].v_pointer = g_strdup_printf(GST_FOURCC_FORMAT, - GST_FOURCC_ARGS(src_value->data[0].v_long)); + guint32 fourcc = src_value->data[0].v_long; + + if (g_ascii_isprint ((fourcc>>0) & 0xff) && + g_ascii_isprint ((fourcc>>8) & 0xff) && + g_ascii_isprint ((fourcc>>16) & 0xff) && + g_ascii_isprint ((fourcc>>24) & 0xff)){ + dest_value->data[0].v_pointer = g_strdup_printf( + "\"" GST_FOURCC_FORMAT "\"", GST_FOURCC_ARGS(fourcc)); + } else { + dest_value->data[0].v_pointer = g_strdup_printf("0x%08x", fourcc); + } } static void @@ -420,6 +485,42 @@ gst_value_transform_int_range_string (const GValue *src_value, (int)src_value->data[0].v_long, (int)src_value->data[1].v_long); } +static void +gst_value_transform_double_range_string (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_pointer = g_strdup_printf("[%g,%g]", + src_value->data[0].v_double, src_value->data[1].v_double); +} + +static void +gst_value_transform_list_string (const GValue *src_value, + GValue *dest_value) +{ + GValue *list_value; + GArray *array; + GString *s; + int i; + char *list_s; + + array = src_value->data[0].v_pointer; + + s = g_string_new("("); + for(i=0;ilen;i++){ + list_value = &g_array_index(array, GValue, i); + + if (i != 0) { + g_string_append (s, ", "); + } + list_s = g_strdup_value_contents (list_value); + g_string_append (s, list_s); + g_free (list_s); + } + g_string_append (s, ")"); + + dest_value->data[0].v_pointer = g_string_free (s, FALSE); +} + /* comparison functions */ static int @@ -444,6 +545,18 @@ gst_value_compare_double (const GValue *value1, const GValue *value2) return GST_VALUE_UNORDERED; } +static int +gst_value_compare_float (const GValue *value1, const GValue *value2) +{ + if (value1->data[0].v_float > value2->data[0].v_float) + return GST_VALUE_GREATER_THAN; + if (value1->data[0].v_float < value2->data[0].v_float) + return GST_VALUE_LESS_THAN; + if (value1->data[0].v_float == value2->data[0].v_float) + return GST_VALUE_EQUAL; + return GST_VALUE_UNORDERED; +} + static int gst_value_compare_string (const GValue *value1, const GValue *value2) { @@ -456,10 +569,53 @@ gst_value_compare_string (const GValue *value1, const GValue *value2) static int gst_value_compare_fourcc (const GValue *value1, const GValue *value2) { +g_print("comparing fourccs\n"); if (value2->data[0].v_int == value1->data[0].v_int) return GST_VALUE_EQUAL; return GST_VALUE_UNORDERED; } +static int +gst_value_compare_int_range (const GValue *value1, const GValue *value2) +{ + if (value2->data[0].v_int == value1->data[0].v_int && + value2->data[0].v_int == value1->data[0].v_int) return GST_VALUE_EQUAL; + return GST_VALUE_UNORDERED; +} + +static int +gst_value_compare_double_range (const GValue *value1, const GValue *value2) +{ + if (value2->data[0].v_double == value1->data[0].v_double && + value2->data[0].v_double == value1->data[0].v_double) + return GST_VALUE_EQUAL; + return GST_VALUE_UNORDERED; +} + +static int +gst_value_compare_list (const GValue *value1, const GValue *value2) +{ + int i,j; + GArray *array1 = value1->data[0].v_pointer; + GArray *array2 = value2->data[0].v_pointer; + GValue *v1; + GValue *v2; + + if (array1->len != array2->len) return GST_VALUE_UNORDERED; + + for(i=0;ilen;i++){ + v1 = &g_array_index (array1, GValue, i); + for(j=0;jlen;j++){ + v2 = &g_array_index (array2, GValue, j); + if (gst_value_compare(v1, v2) == GST_VALUE_EQUAL) break; + } + if (j==array1->len) { + return GST_VALUE_UNORDERED; + } + } + + return GST_VALUE_EQUAL; +} + gboolean gst_value_can_compare (const GValue *value1, const GValue *value2) { @@ -482,7 +638,8 @@ gst_value_compare (const GValue *value1, const GValue *value2) GstValueCompareInfo *compare_info; int i; - g_return_val_if_fail(G_VALUE_TYPE(value1) == G_VALUE_TYPE(value2), 0); + if (G_VALUE_TYPE(value1) != G_VALUE_TYPE(value2)) return GST_VALUE_UNORDERED; + for(i=0;ilen;i++){ compare_info = &g_array_index(gst_value_compare_funcs, GstValueCompareInfo, i); @@ -491,7 +648,8 @@ gst_value_compare (const GValue *value1, const GValue *value2) return compare_info->func(value1, value2); } - g_return_val_if_fail(0 /* type not found */, GST_VALUE_UNORDERED); + g_critical("unable to compare values of type %s\n", + g_type_name (G_VALUE_TYPE (value1))); return GST_VALUE_UNORDERED; } @@ -536,8 +694,7 @@ gst_value_union (GValue *dest, const GValue *value1, const GValue *value2) return union_info->func(dest, value1, value2); } } - gst_value_list_concat (dest, value1, value2); - return TRUE; + return gst_value_union_lists (dest, value1, value2); } void @@ -618,23 +775,31 @@ gst_value_intersect (GValue *dest, const GValue *value1, const GValue *value2) { GstValueIntersectInfo *intersect_info; int i; + int ret = FALSE; +g_print("intersecting %s=%s and %s=%s\n", + g_type_name(G_VALUE_TYPE(value1)), g_strdup_value_contents(value1), + g_type_name(G_VALUE_TYPE(value2)), g_strdup_value_contents(value2)); for(i=0;ilen;i++){ intersect_info = &g_array_index(gst_value_intersect_funcs, GstValueIntersectInfo, i); if(intersect_info->type1 == G_VALUE_TYPE(value1) && intersect_info->type2 == G_VALUE_TYPE(value2)) { - return intersect_info->func(dest, value1, value2); + ret = intersect_info->func(dest, value1, value2); +g_print("result is %d %s\n", ret, ret?g_strdup_value_contents(dest):"none1"); + return ret; } } if(gst_value_compare(value1, value2) == GST_VALUE_EQUAL){ g_value_init(dest, G_VALUE_TYPE(value1)); g_value_copy(value1, dest); - return TRUE; + ret = TRUE; +g_print("result is %d %s\n", ret, ret?g_strdup_value_contents(dest):"none2"); } - return FALSE; +g_print("result is %d %s\n", ret, ret?g_strdup_value_contents(dest):"none3"); + return ret; } void @@ -724,21 +889,29 @@ _gst_value_initialize (void) gst_value_lcopy_list }; info.value_table = &value_table; - gst_value_type_list = g_type_register_static (G_TYPE_BOXED, "GstValueList", &info, 0); + gst_type_list = g_type_register_static (G_TYPE_BOXED, "GstValueList", &info, 0); } g_value_register_transform_func (GST_TYPE_FOURCC, G_TYPE_STRING, gst_value_transform_fourcc_string); g_value_register_transform_func (GST_TYPE_INT_RANGE, G_TYPE_STRING, gst_value_transform_int_range_string); + g_value_register_transform_func (GST_TYPE_DOUBLE_RANGE, G_TYPE_STRING, + gst_value_transform_double_range_string); + g_value_register_transform_func (GST_TYPE_LIST, G_TYPE_STRING, + gst_value_transform_list_string); gst_value_compare_funcs = g_array_new(FALSE, FALSE, sizeof(GstValueCompareInfo)); gst_value_register_compare_func (G_TYPE_INT, gst_value_compare_int); + gst_value_register_compare_func (G_TYPE_FLOAT, gst_value_compare_float); gst_value_register_compare_func (G_TYPE_DOUBLE, gst_value_compare_double); gst_value_register_compare_func (G_TYPE_STRING, gst_value_compare_string); gst_value_register_compare_func (GST_TYPE_FOURCC, gst_value_compare_fourcc); + gst_value_register_compare_func (GST_TYPE_INT_RANGE, gst_value_compare_int_range); + gst_value_register_compare_func (GST_TYPE_DOUBLE_RANGE, gst_value_compare_double_range); + gst_value_register_compare_func (GST_TYPE_LIST, gst_value_compare_list); gst_value_union_funcs = g_array_new(FALSE, FALSE, sizeof(GstValueUnionInfo)); diff --git a/gst/gstvalue.h b/gst/gstvalue.h index 0fa57cacd1..a6cc2a4d8c 100644 --- a/gst/gstvalue.h +++ b/gst/gstvalue.h @@ -21,6 +21,7 @@ #define __GST_VALUE_H__ #include +#include G_BEGIN_DECLS @@ -41,16 +42,16 @@ typedef int (* GstValueIntersectFunc) (GValue *dest, const GValue *value1, ((gchar) (((fourcc)>>16)&0xff)), \ ((gchar) (((fourcc)>>24)&0xff)) +#define GST_VALUE_HOLDS_FOURCC(x) (G_VALUE_HOLDS(x, gst_type_fourcc)) +#define GST_VALUE_HOLDS_INT_RANGE(x) (G_VALUE_HOLDS(x, gst_type_int_range)) +#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_HOLDS(x, gst_type_double_range)) +#define GST_VALUE_HOLDS_LIST(x) (G_VALUE_HOLDS(x, gst_type_list)) +#define GST_VALUE_HOLDS_CAPS(x) TRUE /* FIXME */ + #define GST_TYPE_FOURCC gst_type_fourcc #define GST_TYPE_INT_RANGE gst_type_int_range #define GST_TYPE_DOUBLE_RANGE gst_type_double_range -#define GST_VALUE_TYPE_LIST gst_value_type_list - -#define GST_VALUE_HOLDS_FOURCC(x) (G_VALUE_TYPE(x) == gst_type_fourcc) -#define GST_VALUE_HOLDS_INT_RANGE(x) (G_VALUE_TYPE(x) == gst_type_int_range) -#define GST_VALUE_HOLDS_DOUBLE_RANGE(x) (G_VALUE_TYPE(x) == gst_type_double_range) -#define GST_VALUE_HOLDS_LIST(x) (G_VALUE_TYPE(x) == GST_VALUE_TYPE_LIST) -#define GST_VALUE_HOLDS_CAPS(x) TRUE /* FIXME */ +#define GST_TYPE_LIST gst_type_list #define GST_VALUE_LESS_THAN (-1) #define GST_VALUE_EQUAL 0 @@ -60,7 +61,7 @@ typedef int (* GstValueIntersectFunc) (GValue *dest, const GValue *value1, extern GType gst_type_fourcc; extern GType gst_type_int_range; extern GType gst_type_double_range; -extern GType gst_value_type_list; +extern GType gst_type_list; void gst_value_set_fourcc (GValue *value, guint32 fourcc); guint32 gst_value_get_fourcc (const GValue *value); @@ -73,6 +74,9 @@ void gst_value_set_double_range (GValue *value, double start, double end); double gst_value_get_double_range_min (const GValue *value); double gst_value_get_double_range_max (const GValue *value); +const GstCaps2 *gst_value_get_caps (const GValue *value); +void gst_value_set_caps (GValue *calue, const GstCaps2 *caps); + void gst_value_list_prepend_value (GValue *value, const GValue *prepend_value); void gst_value_list_append_value (GValue *value, const GValue *prepend_value); guint gst_value_list_get_size (const GValue *value);