From: David Schleef Date: Mon, 3 Nov 2003 09:10:07 +0000 (+0000) Subject: Add GstStructure and GstValue X-Git-Tag: CAPS-ROOT~18 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5539c318e7c60a1bb041c08d9ebb833ec9e962f6;p=platform%2Fupstream%2Fgstreamer.git Add GstStructure and GstValue Original commit message from CVS: Add GstStructure and GstValue --- diff --git a/gst/Makefile.am b/gst/Makefile.am index b2f44a6..02367af 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -112,6 +112,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gstqueue.c \ gstquery.c \ gstscheduler.c \ + gststructure.c \ gstsystemclock.c \ gstthread.c \ gstthreaddummy.c \ @@ -121,6 +122,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ $(GST_URI_SRC) \ gsturitype.c \ gstutils.c \ + gstvalue.c \ $(GST_REGISTRY_SRC) \ gstregistrypool.c \ $(GST_PARSE_SRC) \ @@ -173,6 +175,7 @@ gst_headers = \ gstqueue.h \ gstquery.h \ gstscheduler.h \ + gststructure.h \ gstsystemclock.h \ gstthread.h \ gsttrace.h \ @@ -182,6 +185,7 @@ gst_headers = \ gsturi.h \ gsturitype.h \ gstutils.h \ + gstvalue.h \ gstregistry.h \ gstregistrypool.h \ gstparse.h \ diff --git a/gst/gst.c b/gst/gst.c index dee3371..d44f936 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -526,6 +526,8 @@ init_post (void) _gst_plugin_register_static (&plugin_desc); _gst_cpu_initialize (_gst_enable_cpu_opt); + _gst_structure_initialize (); + _gst_value_initialize (); _gst_props_initialize (); _gst_caps_initialize (); _gst_plugin_initialize (); diff --git a/gst/gst.h b/gst/gst.h index e7fd46d..8f48c40 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include #include #include diff --git a/gst/gststructure.c b/gst/gststructure.c new file mode 100644 index 0000000..bc695a6 --- /dev/null +++ b/gst/gststructure.c @@ -0,0 +1,853 @@ +/* GStreamer + * Copyright (C) 2003 David A. Schleef + * + * gststructure.c: lists of { GQuark, GValue } tuples + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include +#include + +//#define G_TYPE_FOURCC G_TYPE_FLOAT + +static GType _gst_structure_type; + +static void _gst_structure_transform_to_string(const GValue *src_value, + GValue *dest_value); + +static void _gst_structure_value_init (GValue *value); +static void _gst_structure_value_free (GValue *value); +static void _gst_structure_value_copy (const GValue *src, GValue *dest); +static gpointer _gst_structure_value_peek_pointer (const GValue *value); + + +GType gst_structure_get_type(void) +{ + return _gst_structure_type; +} + +void _gst_structure_initialize(void) +{ + static GTypeValueTable type_value_table = { + _gst_structure_value_init, + _gst_structure_value_free, + _gst_structure_value_copy, + _gst_structure_value_peek_pointer, + NULL, + NULL, + NULL, + NULL, + }; + static GTypeInfo structure_info = { + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, /* sizeof(GstStructure), */ + 0, + NULL, /* _gst_structure_init, */ + &type_value_table, + }; + + _gst_structure_type = g_type_register_static(G_TYPE_BOXED, "GstStructure", + &structure_info, 0); +#if 0 + _gst_structure_type = g_boxed_type_register_static("GstStructure", + (GBoxedCopyFunc) gst_structure_dup, + (GBoxedFreeFunc) gst_structure_free); +#endif + + g_value_register_transform_func(_gst_structure_type, G_TYPE_STRING, + _gst_structure_transform_to_string); +} + +/** + * gst_structure_empty_new: + * @name: name of new structure + * + * Creates a new, empty #GstStructure with the given name. + * + * Returns: a new, empty #GstStructure + */ +GstStructure *gst_structure_empty_new(const gchar *name) +{ + GstStructure *structure; + + g_return_val_if_fail(name != NULL, NULL); + + structure = g_new0(GstStructure, 1); + structure->name = g_quark_from_string(name); + structure->fields = g_array_new(FALSE,TRUE,sizeof(GstStructureField)); + + return structure; +} + +/** + * gst_structure_new: + * @name: name of new structure + * @firstfield: name of first field to set + * @...: additional arguments + * + * Creates a new #GstStructure with the given name. Parses the + * list of variable arguments and sets fields to the values listed. + * Variable arguments should be passed as field name, field type, + * and value. Last variable argument should be NULL. + * + * Returns: a new #GstStructure + */ +GstStructure *gst_structure_new(const gchar *name, + const gchar *firstfield, ...) +{ + GstStructure *structure; + va_list varargs; + + g_return_val_if_fail(name != NULL, NULL); + + va_start(varargs, firstfield); + + structure = gst_structure_new_valist(name,firstfield,varargs); + + va_end(varargs); + + return structure; +} + +/** + * gst_structure_new_valist: + * @name: name of new structure + * @firstfield: name of first field to set + * @varags: variable argument list + * + * Creates a new #GstStructure with the given name. Structure fields + * are set according to the varargs in a manner similar to + * @gst_structure_new. + * + * Returns: a new #GstStructure + */ +GstStructure *gst_structure_new_valist(const gchar *name, + const gchar *firstfield, va_list varargs) +{ + GstStructure *structure; + + g_return_val_if_fail(name != NULL, NULL); + + structure = gst_structure_empty_new(name); + gst_structure_set_valist(structure, firstfield, varargs); + + return structure; +} + +/** + * gst_structure_dup: + * @structure: a #GstStructure to duplicate + * + * Duplicates a #GstStructure and all its fields and values. + * + * Returns: a new #GstStructure. + */ +GstStructure *gst_structure_dup(GstStructure *structure) +{ + GstStructure *new_structure; + GstStructureField *field; + int i; + + g_return_val_if_fail(structure != NULL, NULL); + + new_structure = gst_structure_empty_new(g_quark_to_string(structure->name)); + new_structure->fields = g_array_set_size(new_structure->fields, + structure->fields->len); + new_structure->name = structure->name; + + for(i=0;ifields->len;i++){ + GstStructureField new_field = { 0 }; + + field = GST_STRUCTURE_FIELD(structure, i); + + new_field.name = field->name; + g_value_init(&new_field.value, G_VALUE_TYPE(&field->value)); + g_value_copy(&field->value, &new_field.value); + + g_array_append_val(new_structure->fields, new_field); + } + + return structure; +} + +/** + * gst_structure_free: + * @structure: the #GstStructure to free + * + * Frees a #GstStructure and all its fields and values. + */ +void gst_structure_free(GstStructure *structure) +{ + GstStructureField *field; + int i; + + return; + + g_return_if_fail(structure != NULL); + + for(i=0;ifields->len;i++){ + field = GST_STRUCTURE_FIELD(structure, i); + + if(G_IS_VALUE(&field->value)){ + g_value_unset(&field->value); + } + } + g_free(structure); +} + +/** + * gst_structure_get_name: + * @structure: a #GstStructure + * + * Accessor fuction. + * + * Returns: the name of the structure. + */ +const gchar *gst_structure_get_name(GstStructure *structure) +{ + g_return_val_if_fail(structure != NULL, NULL); + + return g_quark_to_string(structure->name); +} + +/** + * gst_structure_set_name: + * @structure: a #GstStructure + * @name: the new name of the structure + * + * Sets the name of the structure to the given name. The string + * provided is copied before being used. + */ +void gst_structure_set_name(GstStructure *structure, const gchar *name) +{ + g_return_if_fail(structure != NULL); + g_return_if_fail(name != NULL); + + structure->name = g_quark_from_string(name); +} + +/** + * gst_structure_id_set_value: + * @structure: a #GstStructure + * @field_id: a #GQuark representing a field + * @value: the new value of the field + * + * Sets the field with the given ID to the provided value. If the field + * does not exist, it is created. If the field exists, the previous + * value is freed. + */ +void gst_structure_id_set_value(GstStructure *structure, GQuark fieldname, + GValue *value) +{ + GstStructureField field = { 0 }; + + g_return_if_fail(structure != NULL); + g_return_if_fail(G_IS_VALUE(value)); + + field.name = fieldname; + g_value_init(&field.value, G_TYPE_INT); + g_value_copy(value, &field.value); + + gst_structure_set_field(structure, &field); +} + +/** + * gst_structure_set_value: + * @structure: a #GstStructure + * @field: the name of the field to set + * @value: the new value of the field + * + * Sets the field with the given name to the provided value. If the field + * does not exist, it is created. If the field exists, the previous + * value is freed. + */ +void gst_structure_set_value(GstStructure *structure, const gchar *field, + GValue *value) +{ + g_return_if_fail(structure != NULL); + g_return_if_fail(field != NULL); + g_return_if_fail(G_IS_VALUE(value)); + + gst_structure_id_set_value(structure, g_quark_from_string(field), value); +} + +/** + * gst_structure_set: + * @structure: a #GstStructure + * @field: the name of the field to set + * @...: variable arguments + * + * Parses the variable arguments and sets fields accordingly. + * Variable arguments should be in the form field name, field type + * (as a GType), value. The last variable argument should be NULL. + */ +void gst_structure_set(GstStructure *structure, const gchar *field, ...) +{ + va_list varargs; + + g_return_if_fail(structure != NULL); + + va_start(varargs, field); + + gst_structure_set_valist(structure,field,varargs); + + va_end(varargs); +} + +/** + * gst_structure_set: + * @structure: a #GstStructure + * @field: the name of the field to set + * @varargs: variable arguments + * + * va_list form of #gst_structure_set. + */ +void gst_structure_set_valist(GstStructure *structure, const gchar *fieldname, + va_list varargs) +{ + GType type; + int i; + double d; + char *s; + + g_return_if_fail(structure != NULL); + + while(fieldname){ + GstStructureField field = { 0 }; + + field.name = g_quark_from_string(fieldname); + + type = va_arg (varargs, GType); + + switch(type){ + case G_TYPE_INT: + i = va_arg(varargs, int); + g_value_init(&field.value, G_TYPE_INT); + g_value_set_int(&field.value, i); + break; + case G_TYPE_DOUBLE: + d = va_arg(varargs, double); + g_value_init(&field.value, G_TYPE_DOUBLE); + g_value_set_double(&field.value, d); + break; +#if 0 + case GST_TYPE_FOURCC: + i = va_arg(varargs, int); + g_value_init(&field.value, G_TYPE_FOURCC); + gst_value_set_fourcc(&field.value, i); + break; +#endif + case G_TYPE_BOOLEAN: + i = va_arg(varargs, int); + g_value_init(&field.value, G_TYPE_BOOLEAN); + g_value_set_boolean(&field.value, i); + break; + case G_TYPE_STRING: + s = va_arg(varargs, char *); + g_value_init(&field.value, G_TYPE_STRING); + g_value_set_string(&field.value, s); + break; + default: + g_assert_not_reached(); + break; + } + + gst_structure_set_field(structure, &field); + + fieldname = va_arg (varargs, gchar *); + } +} + +/** + * gst_structure_set_field: + * @structure: a #GstStructure + * @field: the #GstStructureField to set + * + * Sets a field in the structure. If the structure currently contains + * a field with the same name, it is replaced with the provided field. + * Otherwise, the field is added to the structure. The field's value + * is not deeply copied. + * + * This function is intended mainly for internal use. The function + * #gst_structure_set() is recommended instead of this one. + */ +void gst_structure_set_field(GstStructure *structure, GstStructureField *field) +{ + GstStructureField *f; + int i; + + for(i=0;ifields->len;i++){ + f = GST_STRUCTURE_FIELD(structure, i); + + if(f->name == field->name){ + g_value_unset(&f->value); + memcpy(f,field,sizeof(GstStructureField)); + return; + } + } + + g_array_append_val(structure->fields, *field); +} + +/** + * gst_structure_id_get_field: + * @structure: a #GstStructure + * @field_id: the GQuark of the field to get + * + * Gets the specified field from the structure. If there is no + * field with the given ID, NULL is returned. + * + * Returns: the #GstStructureField with the given ID + */ +GstStructureField *gst_structure_id_get_field(GstStructure *structure, + GQuark field_id) +{ + GstStructureField *field; + int i; + + g_return_val_if_fail(structure != NULL, NULL); + + for(i=0;ifields->len;i++){ + field = GST_STRUCTURE_FIELD(structure, i); + + if(field->name == field_id) return field; + } + + return NULL; +} + +/** + * gst_structure_get_field: + * @structure: a #GstStructure + * @fieldname: the name of the field to get + * + * Gets the specified field from the structure. If there is no + * field with the given ID, NULL is returned. + * + * Returns: the #GstStructureField with the given name + */ +GstStructureField * +gst_structure_get_field(GstStructure *structure, const gchar *fieldname) +{ + g_return_val_if_fail(structure != NULL, NULL); + g_return_val_if_fail(fieldname != NULL, NULL); + + return gst_structure_id_get_field(structure, + g_quark_from_string(fieldname)); +} + +/** + * gst_structure_get: + * @structure: a #GstStructure + * @fieldname: the name of the field to get + * + * Accessor function. + * + * Returns: the #GValue corresponding to the field with the given name. + */ +const GValue * +gst_structure_get(GstStructure *structure, const gchar *fieldname) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, NULL); + g_return_val_if_fail(fieldname != NULL, NULL); + + field = gst_structure_get_field(structure, fieldname); + if(field == NULL) return NULL; + + return &field->value; +} + +/** + * gst_structure_remove_field: + * @structure: a #GstStructure + * @fieldname: the name of the field to remove + * + * Removes the field with the given name. If the field with the given + * name does not exist, the structure is unchanged. + */ +void +gst_structure_remove_field(GstStructure *structure, const gchar *fieldname) +{ + GstStructureField *field; + GQuark id; + int i; + + g_return_if_fail(structure != NULL); + g_return_if_fail(fieldname != NULL); + + id = g_quark_from_string(fieldname); + + for(i=0;ifields->len;i++){ + field = GST_STRUCTURE_FIELD(structure, i); + + if(field->name == id){ + if(G_IS_VALUE(&field->value)){ + g_value_unset(&field->value); + } + structure->fields = g_array_remove_index(structure->fields, i); + return; + } + } +} + +/** + * gst_structure_get_field_type: + * @structure: a #GstStructure + * @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 + * returned. + * + * Returns: the #GValue of the field + */ +GType +gst_structure_get_field_type(GstStructure *structure, const gchar *fieldname) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, G_TYPE_NONE); + g_return_val_if_fail(fieldname != NULL, G_TYPE_NONE); + + field = gst_structure_get_field(structure, fieldname); + if(field == NULL) return G_TYPE_NONE; + + return G_VALUE_TYPE(&field->value); +} + +/** + * gst_structure_n_fields: + * @structure: a #GstStructure + * + * Accessor function. + * + * Returns: the number of fields in the structure + */ +gint +gst_structure_n_fields(GstStructure *structure) +{ + g_return_val_if_fail(structure != NULL, 0); + + return structure->fields->len; +} + +/** + * gst_structure_has_field: + * @structure: a #GstStructure + * @fieldname: the name of a field + * + * Accessor function. + * + * Returns: TRUE if the structure contains a field with the given name + */ +gboolean +gst_structure_has_field(GstStructure *structure, const gchar *fieldname) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, 0); + g_return_val_if_fail(fieldname != NULL, 0); + + field = gst_structure_get_field(structure, fieldname); + + return (field != NULL); +} + +/** + * gst_structure_has_field: + * @structure: a #GstStructure + * @fieldname: the name of a field + * @type: the type of a value + * + * Accessor function. + * + * Returns: TRUE if the structure contains a field with the given name and type + */ +gboolean +gst_structure_has_field_typed(GstStructure *structure, const gchar *fieldname, + GType type) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, 0); + g_return_val_if_fail(fieldname != NULL, 0); + + field = gst_structure_get_field(structure, fieldname); + if(field == NULL) return FALSE; + + return (G_VALUE_TYPE(&field->value) == type); +} + + +/* utility functions */ + +/** + * gst_structure_get_boolean: + * @structure: a #GstStructure + * @fieldname: the name of a field + * @ptr: a pointer to a #gboolean to set + * + * Sets the boolean pointed to by @ptr corresponding to the value of the + * given field. Caller is responsible for making sure the field exists + * and has the correct type. + * + * Returns: TRUE if the value could be set correctly + */ +gboolean +gst_structure_get_boolean(GstStructure *structure, const gchar *fieldname, + gboolean *value) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, FALSE); + g_return_val_if_fail(fieldname != NULL, FALSE); + + field = gst_structure_get_field(structure, fieldname); + + if(field == NULL) return FALSE; + if(!G_VALUE_HOLDS_BOOLEAN(&field->value))return FALSE; + + *value = g_value_get_boolean(&field->value); + + return TRUE; +} + +/** + * gst_structure_get_int: + * @structure: a #GstStructure + * @fieldname: the name of a field + * @ptr: a pointer to an int to set + * + * Sets the int pointed to by @ptr corresponding to the value of the + * given field. Caller is responsible for making sure the field exists + * and has the correct type. + * + * Returns: TRUE if the value could be set correctly + */ +gboolean +gst_structure_get_int(GstStructure *structure, const gchar *fieldname, + gint *value) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, FALSE); + g_return_val_if_fail(fieldname != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + field = gst_structure_get_field(structure, fieldname); + + if(field == NULL) return FALSE; + if(!G_VALUE_HOLDS_INT(&field->value))return FALSE; + + *value = g_value_get_int(&field->value); + + return TRUE; +} + +/** + * gst_structure_get_fourcc: + * @structure: a #GstStructure + * @fieldname: the name of a field + * @ptr: a pointer to a #GstFourcc to set + * + * Sets the #GstFourcc pointed to by @ptr corresponding to the value of the + * given field. Caller is responsible for making sure the field exists + * and has the correct type. + * + * Returns: TRUE if the value could be set correctly + */ +gboolean +gst_structure_get_fourcc(GstStructure *structure, const gchar *fieldname, + guint32 *value) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, FALSE); + g_return_val_if_fail(fieldname != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + field = gst_structure_get_field(structure, fieldname); + + if(field == NULL) return FALSE; + if(!G_VALUE_HOLDS_UINT(&field->value))return FALSE; + + *value = g_value_get_uint(&field->value); + + return TRUE; +} + +/** + * gst_structure_get_double: + * @structure: a #GstStructure + * @fieldname: the name of a field + * @ptr: a pointer to a #GstFourcc to set + * + * Sets the double pointed to by @ptr corresponding to the value of the + * given field. Caller is responsible for making sure the field exists + * and has the correct type. + * + * Returns: TRUE if the value could be set correctly + */ +gboolean gst_structure_get_double(GstStructure *structure, + const gchar *fieldname, gdouble *value) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, FALSE); + g_return_val_if_fail(fieldname != NULL, FALSE); + g_return_val_if_fail(value != NULL, FALSE); + + field = gst_structure_get_field(structure, fieldname); + + if(field == NULL) return FALSE; + if(!G_VALUE_HOLDS_DOUBLE(&field->value))return FALSE; + + *value = g_value_get_double(&field->value); + + return TRUE; +} + +/** + * gst_structure_get_string: + * @structure: a #GstStructure + * @fieldname: the name of a field + * @ptr: a pointer to a #GstFourcc to set + * + * Finds the field corresponding to @fieldname, and returns the string + * contained in the field's value. Caller is responsible for making + * sure the field exists and has the correct type. + * + * The string should not be modified, and remains valid until the next + * call to a gst_structure_*() function with the given structure. + * + * Returns: a pointer to the string + */ +const gchar * +gst_structure_get_string(GstStructure *structure, const gchar *fieldname) +{ + GstStructureField *field; + + g_return_val_if_fail(structure != NULL, NULL); + g_return_val_if_fail(fieldname != NULL, NULL); + + field = gst_structure_get_field(structure, fieldname); + + if(field == NULL) return FALSE; + if(!G_VALUE_HOLDS_STRING(&field->value))return FALSE; + + return g_value_get_string(&field->value); +} + +/** + * gst_structure_to_string: + * @structure: a #GstStructure + * + * Converts @structure to a human-readable representation. + * + * Returns: a pointer to string allocated by g_malloc() + */ +gchar * +gst_structure_to_string(GstStructure *structure) +{ + GstStructureField *field; + GString *s; + int i; + + g_return_val_if_fail(structure != NULL, NULL); + + s = g_string_new(""); + g_string_append_printf(s, "\"%s\"", g_quark_to_string(structure->name)); + for(i=0;ifields->len;i++){ + GValue s_val = { 0 }; + + field = GST_STRUCTURE_FIELD(structure, i); + + g_value_init(&s_val, G_TYPE_STRING); + + 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); + } + return g_string_free(s, FALSE); +} + +/** + * gst_structure_from_string: + * @structure: a #GstStructure + * + * Creates a #GstStructure from a string representation. + * + * Returns: a new #GstStructure + */ +GstStructure * +gst_structure_from_string (const gchar *string) +{ + /* FIXME */ + + g_return_val_if_fail(string != NULL, NULL); + + g_assert_not_reached(); + + return NULL; +} + +static void +_gst_structure_transform_to_string(const GValue *src_value, GValue *dest_value) +{ + g_return_if_fail(src_value != NULL); + g_return_if_fail(dest_value != NULL); + + dest_value->data[0].v_pointer = + gst_structure_to_string (src_value->data[0].v_pointer); +} + + +static void _gst_structure_value_init (GValue *value) +{ + value->data[0].v_pointer = gst_structure_empty_new(""); +} + +static void _gst_structure_value_free (GValue *value) +{ + gst_structure_free(value->data[0].v_pointer); + +} + +static void _gst_structure_value_copy (const GValue *src, GValue *dest) +{ + dest->data[0].v_pointer = gst_structure_dup(src->data[0].v_pointer); +} + +static gpointer _gst_structure_value_peek_pointer (const GValue *value) +{ + return value->data[0].v_pointer; +} + diff --git a/gst/gststructure.h b/gst/gststructure.h new file mode 100644 index 0000000..9a93480 --- /dev/null +++ b/gst/gststructure.h @@ -0,0 +1,104 @@ +/* GStreamer + * Copyright (C) <2003> David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_STRUCTURE_H__ +#define __GST_STRUCTURE_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GstStructure GstStructure; +typedef struct _GstStructureField GstStructureField; + +struct _GstStructure { + int len; + + GQuark name; + + GArray *fields; +}; + +struct _GstStructureField { + GQuark name; + GValue value; +}; + +#define GST_STRUCTURE_FIELD(structure, index) \ + &g_array_index((structure)->fields, GstStructureField, (index)) + +GType gst_structure_get_type(void); +void _gst_structure_initialize(void); + +GstStructure *gst_structure_empty_new(const gchar *name); +GstStructure *gst_structure_new(const gchar *name, + const gchar *firstfield, ...); +GstStructure *gst_structure_new_valist(const gchar *name, + const gchar *firstfield, va_list varargs); +GstStructure *gst_structure_dup(GstStructure *structure); +void gst_structure_free(GstStructure *structure); + +const gchar *gst_structure_get_name(GstStructure *structure); +void gst_structure_set_name(GstStructure *structure, const gchar *name); +void gst_structure_set_field(GstStructure *structure, + GstStructureField *field); + +void gst_structure_id_set_value(GstStructure *structure, GQuark field, + GValue *value); +void gst_structure_set_value(GstStructure *structure, const gchar *field, + GValue *value); +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(GstStructure *structure, const gchar *field); +GstStructureField *gst_structure_get_field(GstStructure *structure, + const gchar *fieldname); +GstStructureField *gst_structure_id_get_field(GstStructure *structure, + GQuark fieldname); +void gst_structure_remove_field(GstStructure *structure, const gchar *field); + +GType gst_structure_get_field_type(GstStructure *structure, + const gchar *field); +gint gst_structure_n_fields(GstStructure *structure); +gboolean gst_structure_has_field(GstStructure *structure, const gchar *field); +gboolean gst_structure_has_field_typed(GstStructure *structure, + const gchar *field, GType type); + +/* utility functions */ + +gboolean gst_structure_get_boolean(GstStructure *structure, const gchar *field, + gboolean *value); +gboolean gst_structure_get_int(GstStructure *structure, const gchar *field, + gint *value); +gboolean gst_structure_get_fourcc(GstStructure *structure, const gchar *field, + guint32 *value); +gboolean gst_structure_get_double(GstStructure *structure, const gchar *field, + gdouble *value); +const gchar *gst_structure_get_string(GstStructure *structure, + const gchar *field); + +gchar * gst_structure_to_string(GstStructure *structure); +GstStructure * gst_structure_from_string (const gchar *string); + + +G_END_DECLS + +#endif + diff --git a/gst/gstvalue.c b/gst/gstvalue.c new file mode 100644 index 0000000..669b87e --- /dev/null +++ b/gst/gstvalue.c @@ -0,0 +1,217 @@ +/* GStreamer + * Copyright (C) <2003> David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + + +GType gst_type_fourcc; +GType gst_type_int_range; +GType gst_type_double_range; + +static void +gst_value_init_fourcc (GValue *value) +{ + value->data[0].v_long = 0; +} + +static void +gst_value_copy_fourcc (const GValue *src_value, GValue *dest_value) +{ + dest_value->data[0].v_long = src_value->data[0].v_long; +} + +static gchar * +gst_value_collect_fourcc (GValue *value, guint n_collect_values, + GTypeCValue *collect_values, guint collect_flags) +{ + value->data[0].v_long = collect_values[0].v_long; + + return NULL; +} + +static gchar * +gst_value_lcopy_fourcc (const GValue *value, guint n_collect_values, + GTypeCValue *collect_values, guint collect_flags) +{ + guint32 *fourcc_p = collect_values[0].v_pointer; + + if (!fourcc_p) + return g_strdup_printf ("value location for `%s' passed as NULL", + G_VALUE_TYPE_NAME (value)); + + *fourcc_p = value->data[0].v_long; + + return NULL; +} + +void +gst_value_set_fourcc (GValue *value, guint32 fourcc) +{ + g_return_if_fail (GST_VALUE_HOLDS_FOURCC (value)); + + value->data[0].v_long = fourcc; +} + +guint32 +gst_value_get_fourcc (const GValue *value) +{ + g_return_val_if_fail (GST_VALUE_HOLDS_FOURCC (value), 0); + + return value->data[0].v_long; +} + +/* int range */ + +static void +gst_value_init_int_range (GValue *value) +{ + value->data[0].v_long = 0; +} + +static void +gst_value_copy_int_range (const GValue *src_value, GValue *dest_value) +{ + dest_value->data[0].v_long = src_value->data[0].v_long; +} + +static gchar * +gst_value_collect_int_range (GValue *value, guint n_collect_values, + GTypeCValue *collect_values, guint collect_flags) +{ + value->data[0].v_long = collect_values[0].v_long; + + return NULL; +} + +static gchar * +gst_value_lcopy_int_range (const GValue *value, guint n_collect_values, + GTypeCValue *collect_values, guint collect_flags) +{ + guint32 *int_range_p = collect_values[0].v_pointer; + + if (!int_range_p) + return g_strdup_printf ("value location for `%s' passed as NULL", + G_VALUE_TYPE_NAME (value)); + + *int_range_p = value->data[0].v_long; + + return NULL; +} + +void +gst_value_set_int_range (GValue *value, int start, int end) +{ + g_return_if_fail (GST_VALUE_HOLDS_FOURCC (value)); + + value->data[0].v_long = start; + value->data[1].v_long = end; +} + +int +gst_value_get_int_range_start (const GValue *value) +{ + g_return_val_if_fail (GST_VALUE_HOLDS_FOURCC (value), 0); + + return value->data[0].v_long; +} + +int +gst_value_get_int_range_end (const GValue *value) +{ + g_return_val_if_fail (GST_VALUE_HOLDS_FOURCC (value), 0); + + return value->data[1].v_long; +} + +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)); +} + +static void +gst_value_transform_int_range_string (const GValue *src_value, + GValue *dest_value) +{ + dest_value->data[0].v_pointer = g_strdup_printf("[%d,%d]", + (int)src_value->data[0].v_long, (int)src_value->data[1].v_long); +} + + +void +_gst_value_initialize (void) +{ + GTypeInfo info = { + 0, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + NULL, + NULL, + }; + //const GTypeFundamentalInfo finfo = { G_TYPE_FLAG_DERIVABLE, }; + + { + static const GTypeValueTable value_table = { + gst_value_init_fourcc, + NULL, + gst_value_copy_fourcc, + NULL, + "i", + gst_value_collect_fourcc, + "p", + gst_value_lcopy_fourcc + }; + info.value_table = &value_table; + gst_type_fourcc = g_type_register_static (G_TYPE_BOXED, "GstFourcc", &info, 0); + } + + { + static const GTypeValueTable value_table = { + gst_value_init_int_range, + NULL, + gst_value_copy_int_range, + NULL, + "i", + gst_value_collect_int_range, + "p", + gst_value_lcopy_int_range + }; + info.value_table = &value_table; + gst_type_int_range = g_type_register_static (G_TYPE_BOXED, "GstIntRange", &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); +} + + diff --git a/gst/gstvalue.h b/gst/gstvalue.h new file mode 100644 index 0000000..fa9be7f --- /dev/null +++ b/gst/gstvalue.h @@ -0,0 +1,54 @@ +/* GStreamer + * Copyright (C) <2003> David A. Schleef + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_VALUE_H__ +#define __GST_VALUE_H__ + +#include + +G_BEGIN_DECLS + +#define GST_VALUE_HOLDS_FOURCC(x) TRUE + +#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 + +extern GType gst_type_fourcc; +extern GType gst_type_int_range; +extern GType gst_type_double_range; + +void gst_value_set_fourcc (GValue *value, guint32 fourcc); +guint32 gst_value_get_fourcc (const GValue *value); + +void gst_value_set_int_range (GValue *value, int start, int end); +int gst_value_get_int_range_start (const GValue *value); +int gst_value_get_int_range_end (const GValue *value); + +void gst_value_set_double_range (GValue *value, double start, double end); +double gst_value_get_double_range_start (const GValue *value); +double gst_value_get_double_range_end (const GValue *value); + +void _gst_value_initialize (void); + +G_END_DECLS + +#endif + +