2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstprops.c: Properties subsystem for generic usage
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 //#define GST_DEBUG_ENABLED
24 #include "gst_private.h"
27 #include "gstpropsprivate.h"
29 static GMemChunk *_gst_props_entries_chunk;
30 static GMutex *_gst_props_entries_chunk_lock;
32 static GMemChunk *_gst_props_chunk;
33 static GMutex *_gst_props_chunk_lock;
35 static gboolean gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2);
37 static guint _arg_len[] = {
38 0, // GST_PROPS_END_ID_NUM = 0,
39 0, // GST_PROPS_LIST_ID_NUM,
40 1, // GST_PROPS_INT_ID_NUM,
41 2, // GST_PROPS_INT_RANGE_ID_NUM,
42 1, // GST_PROPS_FOURCC_ID_NUM,
43 1, // GST_PROPS_BOOL_ID_NUM,
44 1, // GST_PROPS_STRING_ID_NUM,
48 _gst_props_initialize (void)
50 _gst_props_entries_chunk = g_mem_chunk_new ("GstPropsEntries",
51 sizeof (GstPropsEntry), sizeof (GstPropsEntry) * 256,
53 _gst_props_entries_chunk_lock = g_mutex_new ();
55 _gst_props_chunk = g_mem_chunk_new ("GstProps",
56 sizeof (GstProps), sizeof (GstProps) * 256,
58 _gst_props_chunk_lock = g_mutex_new ();
62 gst_props_debug_entry (GstPropsEntry *entry)
64 switch (entry->propstype) {
65 case GST_PROPS_INT_ID:
66 GST_DEBUG (0, "%d\n", entry->data.int_data);
68 case GST_PROPS_FOURCC_ID_NUM:
69 GST_DEBUG (0, "%s\n", (gchar*)&entry->data.fourcc_data);
71 case GST_PROPS_BOOL_ID_NUM:
72 GST_DEBUG (0, "%d\n", entry->data.bool_data);
74 case GST_PROPS_STRING_ID_NUM:
75 GST_DEBUG (0, "%s\n", entry->data.string_data.string);
77 case GST_PROPS_INT_RANGE_ID_NUM:
78 GST_DEBUG (0, "%d-%d\n", entry->data.int_range_data.min,
79 entry->data.int_range_data.max);
87 gst_props_create_entry (GstPropsFactory factory, gint *skipped)
89 GstPropsFactoryEntry tag;
93 g_mutex_lock (_gst_props_entries_chunk_lock);
94 entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
95 g_mutex_unlock (_gst_props_entries_chunk_lock);
98 switch (GPOINTER_TO_INT (tag)) {
99 case GST_PROPS_INT_ID_NUM:
100 entry->propstype = GST_PROPS_INT_ID_NUM;
101 entry->data.int_data = GPOINTER_TO_INT (factory[i++]);
103 case GST_PROPS_INT_RANGE_ID_NUM:
104 entry->propstype = GST_PROPS_INT_RANGE_ID_NUM;
105 entry->data.int_range_data.min = GPOINTER_TO_INT (factory[i++]);
106 entry->data.int_range_data.max = GPOINTER_TO_INT (factory[i++]);
108 case GST_PROPS_FOURCC_ID_NUM:
109 entry->propstype = GST_PROPS_FOURCC_ID_NUM;
110 entry->data.fourcc_data = GPOINTER_TO_INT (factory[i++]);
112 case GST_PROPS_LIST_ID_NUM:
113 g_warning ("gstprops: list not allowed in list\n");
115 case GST_PROPS_BOOL_ID_NUM:
116 entry->propstype = GST_PROPS_BOOL_ID_NUM;
117 entry->data.bool_data = GPOINTER_TO_INT (factory[i++]);
119 case GST_PROPS_STRING_ID_NUM:
120 entry->propstype = GST_PROPS_STRING_ID_NUM;
121 entry->data.string_data.string = g_strdup (factory[i++]);
124 g_warning ("gstprops: unknown props id found\n");
125 g_mutex_lock (_gst_props_entries_chunk_lock);
126 g_mem_chunk_free (_gst_props_entries_chunk, entry);
127 g_mutex_unlock (_gst_props_entries_chunk_lock);
139 props_compare_func (gconstpointer a,
142 GstPropsEntry *entry1 = (GstPropsEntry *)a;
143 GstPropsEntry *entry2 = (GstPropsEntry *)b;
145 return (entry1->propid - entry2->propid);
149 props_find_func (gconstpointer a,
152 GstPropsEntry *entry2 = (GstPropsEntry *)a;
153 GQuark entry1 = (GQuark) GPOINTER_TO_INT (b);
155 return (entry1 - entry2->propid);
159 * gst_props_register:
160 * @factory: the factory to register
162 * Register the factory.
164 * Returns: the new property created from the factory
167 gst_props_register (GstPropsFactory factory)
171 return gst_props_register_count (factory, &dummy);
175 * gst_props_register_count:
176 * @factory: the factory to register
177 * @counter: count how many fields were consumed
179 * Register the factory.
181 * Returns: the new property created from the factory
184 gst_props_register_count (GstPropsFactory factory, guint *counter)
186 GstPropsFactoryEntry tag;
188 GstProps *props = NULL;
191 g_return_val_if_fail (factory != NULL, NULL);
197 g_mutex_lock (_gst_props_chunk_lock);
198 props = g_mem_chunk_alloc (_gst_props_chunk);
199 g_mutex_unlock (_gst_props_chunk_lock);
201 g_return_val_if_fail (props != NULL, NULL);
203 props->properties = NULL;
208 GstPropsEntry *entry;
210 if (tag < GST_PROPS_LAST_ID) {
211 g_warning ("properties seem to be wrong\n");
215 quark = g_quark_from_string ((gchar *)tag);
218 switch (GPOINTER_TO_INT (tag)) {
219 case GST_PROPS_LIST_ID_NUM:
221 GstPropsEntry *list_entry;
223 g_mutex_lock (_gst_props_entries_chunk_lock);
224 entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
225 g_mutex_unlock (_gst_props_entries_chunk_lock);
227 entry->propid = quark;
228 entry->propstype = GST_PROPS_LIST_ID_NUM;
229 entry->data.list_data.entries = NULL;
231 i++; // skip list tag
234 list_entry = gst_props_create_entry (&factory[i], &skipped);
235 list_entry->propid = quark;
238 entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, list_entry);
240 entry->data.list_data.entries = g_list_reverse (entry->data.list_data.entries);
241 i++; //skip NULL (list end)
246 entry = gst_props_create_entry (&factory[i], &skipped);
247 entry->propid = quark;
252 props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func);
265 * @entry: the property entries for the property
266 * @...: the property entries for the property
268 * Create a new property from the list of entries.
270 * Returns: the new property created from the list of entries
273 gst_props_new (GstPropsFactoryEntry entry, ...)
276 GstPropsFactoryEntry value;
279 GstPropsFactoryEntry *factory;
280 gboolean inlist = FALSE;
283 #define add_value(value) {\
284 GST_DEBUG (0,"%d %p\n", i, value);\
285 factory[i++] = value; \
288 factory = (GstPropsFactoryEntry *) g_realloc (factory, size*sizeof(GstPropsFactoryEntry));\
293 factory = (GstPropsFactoryEntry *) g_malloc (size*sizeof(GstPropsFactoryEntry));
295 va_start (var_args, entry);
297 value = (GstPropsFactoryEntry) entry;
306 value = va_arg (var_args, GstPropsFactoryEntry);
308 switch (GPOINTER_TO_INT (value)) {
309 case GST_PROPS_END_ID_NUM:
310 g_assert (inlist == TRUE);
315 case GST_PROPS_LIST_ID_NUM:
317 g_assert (inlist == FALSE);
324 skip = _arg_len[GPOINTER_TO_INT (value)];
329 value = va_arg (var_args, GstPropsFactoryEntry);
335 props = gst_props_register (factory);
342 * @props: the props to modify
343 * @name: the name of the entry to modify
344 * @entry: The new value of the property entry
345 * @...: More property entries.
347 * Modifies the value of the given entry in the props struct.
349 * Returns: the new modified property structure.
352 gst_props_set (GstProps *props, const gchar *name, GstPropsFactoryEntry entry, ...)
358 quark = g_quark_from_string (name);
360 lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
363 GstPropsEntry *thisentry;
364 GstPropsFactoryEntry value;
366 thisentry = (GstPropsEntry *)lentry->data;
368 va_start (var_args, entry);
370 value = (GstPropsFactoryEntry) entry;
372 switch (GPOINTER_TO_INT (value)) {
373 case GST_PROPS_INT_ID:
374 thisentry->propstype = GST_PROPS_INT_ID_NUM;
375 value = va_arg (var_args, GstPropsFactoryEntry);
376 thisentry->data.int_data = GPOINTER_TO_INT (value);
378 case GST_PROPS_FOURCC_ID_NUM:
379 thisentry->propstype = GST_PROPS_FOURCC_ID_NUM;
380 value = va_arg (var_args, GstPropsFactoryEntry);
381 thisentry->data.fourcc_data = GPOINTER_TO_INT (value);
383 case GST_PROPS_BOOL_ID_NUM:
384 thisentry->propstype = GST_PROPS_BOOL_ID_NUM;
385 value = va_arg (var_args, GstPropsFactoryEntry);
386 thisentry->data.bool_data = GPOINTER_TO_INT (value);
388 case GST_PROPS_STRING_ID_NUM:
389 thisentry->propstype = GST_PROPS_STRING_ID_NUM;
390 value = va_arg (var_args, GstPropsFactoryEntry);
391 thisentry->data.string_data.string = g_strdup (value);
394 g_print("gstprops: type not allowed\n");
399 g_print("gstprops: no property '%s' to change\n", name);
407 * @props: the props to unref
409 * Decrease the refcount of the property structure, destroying
410 * the property if the refcount is 0.
413 gst_props_unref (GstProps *props)
415 g_return_if_fail (props != NULL);
419 if (props->refcount == 0)
420 gst_props_destroy (props);
425 * @props: the props to ref
427 * Increase the refcount of the property structure.
430 gst_props_ref (GstProps *props)
432 g_return_if_fail (props != NULL);
439 * @props: the props to destroy
441 * Destroy the property, freeing all the memory that
445 gst_props_destroy (GstProps *props)
449 g_return_if_fail (props != NULL);
451 entries = props->properties;
454 GstPropsEntry *entry = (GstPropsEntry *)entries->data;
456 // FIXME also free the lists
457 g_mutex_lock (_gst_props_entries_chunk_lock);
458 g_mem_chunk_free (_gst_props_entries_chunk, entry);
459 g_mutex_unlock (_gst_props_entries_chunk_lock);
461 entries = g_list_next (entries);
464 g_list_free (props->properties);
469 * @props: the props to copy
471 * Copy the property structure.
473 * Returns: the new property that is a copy of the original
477 gst_props_copy (GstProps *props)
482 g_return_val_if_fail (props != NULL, NULL);
484 g_mutex_lock (_gst_props_chunk_lock);
485 new = g_mem_chunk_alloc (_gst_props_chunk);
486 g_mutex_unlock (_gst_props_chunk_lock);
488 new->properties = NULL;
490 properties = props->properties;
493 GstPropsEntry *entry = (GstPropsEntry *)properties->data;
494 GstPropsEntry *newentry;
496 g_mutex_lock (_gst_props_entries_chunk_lock);
497 newentry = g_mem_chunk_alloc (_gst_props_entries_chunk);
498 g_mutex_unlock (_gst_props_entries_chunk_lock);
500 // FIXME copy lists too
501 memcpy (newentry, entry, sizeof (GstPropsEntry));
503 new->properties = g_list_prepend (new->properties, newentry);
505 properties = g_list_next (properties);
507 new->properties = g_list_reverse (new->properties);
513 * gst_props_copy_on_write:
514 * @props: the props to copy on write
516 * Copy the property structure if the refcount is >1.
518 * Returns: A new props that can be safely written to.
521 gst_props_copy_on_write (GstProps *props)
523 GstProps *new = props;;
525 g_return_val_if_fail (props != NULL, NULL);
527 if (props->refcount > 1) {
528 new = gst_props_copy (props);
529 gst_props_unref (props);
537 * @props: the props to get the int value from
538 * @name: the name of the props entry to get.
540 * Get the named entry as an integer.
542 * Returns: the integer value of the named entry, 0 if not found.
545 gst_props_get_int (GstProps *props, const gchar *name)
550 quark = g_quark_from_string (name);
552 lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
555 GstPropsEntry *thisentry;
557 thisentry = (GstPropsEntry *)lentry->data;
559 return thisentry->data.int_data;
566 * gst_props_get_fourcc_int:
567 * @props: the props to get the fourcc value from
568 * @name: the name of the props entry to get.
570 * Get the named entry as a gulong fourcc.
572 * Returns: the fourcc value of the named entry, 0 if not found.
575 gst_props_get_fourcc_int (GstProps *props, const gchar *name)
580 quark = g_quark_from_string (name);
582 lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
585 GstPropsEntry *thisentry;
587 thisentry = (GstPropsEntry *)lentry->data;
589 return thisentry->data.fourcc_data;
596 * gst_props_get_boolean:
597 * @props: the props to get the fourcc value from
598 * @name: the name of the props entry to get.
600 * Get the named entry as a boolean value.
602 * Returns: the boolean value of the named entry, 0 if not found.
605 gst_props_get_boolean (GstProps *props, const gchar *name)
610 quark = g_quark_from_string (name);
612 lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
615 GstPropsEntry *thisentry;
617 thisentry = (GstPropsEntry *)lentry->data;
619 return thisentry->data.bool_data;
626 * gst_props_get_string:
627 * @props: the props to get the fourcc value from
628 * @name: the name of the props entry to get.
630 * Get the named entry as a string value.
632 * Returns: the string value of the named entry, NULL if not found.
635 gst_props_get_string (GstProps *props, const gchar *name)
640 quark = g_quark_from_string (name);
642 lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func);
645 GstPropsEntry *thisentry;
647 thisentry = (GstPropsEntry *)lentry->data;
649 return thisentry->data.string_data.string;
657 * @props: the property to merge into
658 * @tomerge: the property to merge
660 * Merge the properties of tomerge into props.
662 * Returns: the new merged property
665 gst_props_merge (GstProps *props, GstProps *tomerge)
669 g_return_val_if_fail (props != NULL, NULL);
670 g_return_val_if_fail (tomerge != NULL, NULL);
672 merge_props = tomerge->properties;
674 // FIXME do proper merging here...
675 while (merge_props) {
676 GstPropsEntry *entry = (GstPropsEntry *)merge_props->data;
678 props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func);
680 merge_props = g_list_next (merge_props);
687 /* entry2 is always a list, entry1 never is */
689 gst_props_entry_check_list_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2)
691 GList *entrylist = entry2->data.list_data.entries;
692 gboolean found = FALSE;
694 while (entrylist && !found) {
695 GstPropsEntry *entry = (GstPropsEntry *) entrylist->data;
697 found |= gst_props_entry_check_compatibility (entry1, entry);
699 entrylist = g_list_next (entrylist);
706 gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2)
708 GST_DEBUG (0,"compare: %s %s\n", g_quark_to_string (entry1->propid),
709 g_quark_to_string (entry2->propid));
710 switch (entry1->propstype) {
711 case GST_PROPS_LIST_ID_NUM:
713 GList *entrylist = entry1->data.list_data.entries;
714 gboolean valid = TRUE; // innocent until proven guilty
716 while (entrylist && valid) {
717 GstPropsEntry *entry = (GstPropsEntry *) entrylist->data;
719 valid &= gst_props_entry_check_compatibility (entry, entry2);
721 entrylist = g_list_next (entrylist);
726 case GST_PROPS_INT_RANGE_ID_NUM:
727 switch (entry2->propstype) {
729 case GST_PROPS_INT_RANGE_ID_NUM:
730 return (entry2->data.int_range_data.min <= entry1->data.int_range_data.min &&
731 entry2->data.int_range_data.max >= entry1->data.int_range_data.max);
732 case GST_PROPS_LIST_ID_NUM:
733 return gst_props_entry_check_list_compatibility (entry1, entry2);
738 case GST_PROPS_FOURCC_ID_NUM:
739 switch (entry2->propstype) {
741 case GST_PROPS_FOURCC_ID_NUM:
742 return (entry2->data.fourcc_data == entry1->data.fourcc_data);
744 case GST_PROPS_LIST_ID_NUM:
745 return gst_props_entry_check_list_compatibility (entry1, entry2);
750 case GST_PROPS_INT_ID_NUM:
751 switch (entry2->propstype) {
753 case GST_PROPS_INT_RANGE_ID_NUM:
754 return (entry2->data.int_range_data.min <= entry1->data.int_data &&
755 entry2->data.int_range_data.max >= entry1->data.int_data);
757 case GST_PROPS_INT_ID_NUM:
758 return (entry2->data.int_data == entry1->data.int_data);
760 case GST_PROPS_LIST_ID_NUM:
761 return gst_props_entry_check_list_compatibility (entry1, entry2);
766 case GST_PROPS_BOOL_ID_NUM:
767 switch (entry2->propstype) {
769 case GST_PROPS_BOOL_ID_NUM:
770 return (entry2->data.bool_data == entry1->data.bool_data);
771 case GST_PROPS_LIST_ID_NUM:
772 return gst_props_entry_check_list_compatibility (entry1, entry2);
776 case GST_PROPS_STRING_ID_NUM:
777 switch (entry2->propstype) {
779 case GST_PROPS_STRING_ID_NUM:
780 return (!strcmp (entry2->data.string_data.string, entry1->data.string_data.string));
781 case GST_PROPS_LIST_ID_NUM:
782 return gst_props_entry_check_list_compatibility (entry1, entry2);
794 * gst_props_check_compatibility:
795 * @fromprops: a property
796 * @toprops: a property
798 * Checks whether two capabilities are compatible.
800 * Returns: TRUE if compatible, FALSE otherwise
803 gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops)
809 gboolean compatible = TRUE;
811 g_return_val_if_fail (fromprops != NULL, FALSE);
812 g_return_val_if_fail (toprops != NULL, FALSE);
814 sourcelist = fromprops->properties;
815 sinklist = toprops->properties;
817 while (sourcelist && sinklist && compatible) {
818 GstPropsEntry *entry1;
819 GstPropsEntry *entry2;
821 entry1 = (GstPropsEntry *)sourcelist->data;
822 entry2 = (GstPropsEntry *)sinklist->data;
824 while (entry1->propid < entry2->propid) {
825 GST_DEBUG (0,"source is more specific in \"%s\"\n", g_quark_to_string (entry1->propid));
827 sourcelist = g_list_next (sourcelist);
828 if (sourcelist) entry1 = (GstPropsEntry *)sourcelist->data;
831 while (entry1->propid > entry2->propid) {
832 GST_DEBUG (0,"source has missing property \"%s\"\n", g_quark_to_string (entry2->propid));
834 sinklist = g_list_next (sinklist);
835 if (sinklist) entry2 = (GstPropsEntry *)sinklist->data;
839 if (!gst_props_entry_check_compatibility (entry1, entry2)) {
841 GST_DEBUG (0, "%s are not compatible\n:",
842 g_quark_to_string (entry1->propid));
843 gst_props_debug_entry (entry1);
844 gst_props_debug_entry (entry2);
848 sourcelist = g_list_next (sourcelist);
849 sinklist = g_list_next (sinklist);
851 if (sinklist && compatible) {
852 GstPropsEntry *entry2;
853 entry2 = (GstPropsEntry *)sinklist->data;
855 GST_DEBUG (0,"source has missing property \"%s\"\n", g_quark_to_string (entry2->propid));
866 gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
871 switch (entry->propstype) {
872 case GST_PROPS_INT_ID_NUM:
873 subtree = xmlNewChild (parent, NULL, "int", NULL);
874 xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
875 str = g_strdup_printf ("%d", entry->data.int_data);
876 xmlNewProp (subtree, "value", str);
879 case GST_PROPS_INT_RANGE_ID_NUM:
880 subtree = xmlNewChild (parent, NULL, "range", NULL);
881 xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
882 str = g_strdup_printf ("%d", entry->data.int_range_data.min);
883 xmlNewProp (subtree, "min", str);
885 str = g_strdup_printf ("%d", entry->data.int_range_data.max);
886 xmlNewProp (subtree, "max", str);
889 case GST_PROPS_FOURCC_ID_NUM:
890 str = g_strdup_printf ("%4.4s", (gchar *)&entry->data.fourcc_data);
891 xmlAddChild (parent, xmlNewComment (str));
893 subtree = xmlNewChild (parent, NULL, "fourcc", NULL);
894 xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
895 str = g_strdup_printf ("%08x", entry->data.fourcc_data);
896 xmlNewProp (subtree, "hexvalue", str);
899 case GST_PROPS_BOOL_ID_NUM:
900 subtree = xmlNewChild (parent, NULL, "boolean", NULL);
901 xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
902 xmlNewProp (subtree, "value", (entry->data.bool_data ? "true" : "false"));
904 case GST_PROPS_STRING_ID_NUM:
905 subtree = xmlNewChild (parent, NULL, "string", NULL);
906 xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
907 xmlNewProp (subtree, "value", entry->data.string_data.string);
917 * gst_props_save_thyself:
918 * @props: a property to save
919 * @parent: the parent XML tree
921 * Saves the property into an XML representation.
923 * Returns: the new XML tree
926 gst_props_save_thyself (GstProps *props, xmlNodePtr parent)
931 g_return_val_if_fail (props != NULL, NULL);
933 proplist = props->properties;
936 GstPropsEntry *entry = (GstPropsEntry *) proplist->data;
938 switch (entry->propstype) {
939 case GST_PROPS_LIST_ID_NUM:
940 subtree = xmlNewChild (parent, NULL, "list", NULL);
941 xmlNewProp (subtree, "name", g_quark_to_string (entry->propid));
942 g_list_foreach (entry->data.list_data.entries, (GFunc) gst_props_save_thyself_func, subtree);
944 gst_props_save_thyself_func (entry, parent);
947 proplist = g_list_next (proplist);
953 static GstPropsEntry*
954 gst_props_load_thyself_func (xmlNodePtr field)
956 GstPropsEntry *entry;
959 g_mutex_lock (_gst_props_entries_chunk_lock);
960 entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
961 g_mutex_unlock (_gst_props_entries_chunk_lock);
963 if (!strcmp(field->name, "int")) {
964 entry->propstype = GST_PROPS_INT_ID_NUM;
965 prop = xmlGetProp(field, "name");
966 entry->propid = g_quark_from_string (prop);
968 prop = xmlGetProp(field, "value");
969 sscanf (prop, "%d", &entry->data.int_data);
972 else if (!strcmp(field->name, "range")) {
973 entry->propstype = GST_PROPS_INT_RANGE_ID_NUM;
974 prop = xmlGetProp(field, "name");
975 entry->propid = g_quark_from_string (prop);
977 prop = xmlGetProp (field, "min");
978 sscanf (prop, "%d", &entry->data.int_range_data.min);
980 prop = xmlGetProp (field, "max");
981 sscanf (prop, "%d", &entry->data.int_range_data.max);
984 else if (!strcmp(field->name, "boolean")) {
985 entry->propstype = GST_PROPS_BOOL_ID_NUM;
986 prop = xmlGetProp(field, "name");
987 entry->propid = g_quark_from_string (prop);
989 prop = xmlGetProp (field, "value");
990 if (!strcmp (prop, "false")) entry->data.bool_data = 0;
991 else entry->data.bool_data = 1;
994 else if (!strcmp(field->name, "fourcc")) {
995 entry->propstype = GST_PROPS_FOURCC_ID_NUM;
996 prop = xmlGetProp(field, "name");
997 entry->propid = g_quark_from_string (prop);
999 prop = xmlGetProp (field, "hexvalue");
1000 sscanf (prop, "%08x", &entry->data.fourcc_data);
1003 else if (!strcmp(field->name, "string")) {
1004 entry->propstype = GST_PROPS_STRING_ID_NUM;
1005 prop = xmlGetProp(field, "name");
1006 entry->propid = g_quark_from_string (prop);
1008 entry->data.string_data.string = xmlGetProp (field, "value");
1011 g_mutex_lock (_gst_props_entries_chunk_lock);
1012 g_mem_chunk_free (_gst_props_entries_chunk, entry);
1013 g_mutex_unlock (_gst_props_entries_chunk_lock);
1021 * gst_props_load_thyself:
1022 * @parent: the XML tree to load from
1024 * Creates a new property out of an XML tree.
1026 * Returns: the new property
1029 gst_props_load_thyself (xmlNodePtr parent)
1032 xmlNodePtr field = parent->xmlChildrenNode;
1035 g_mutex_lock (_gst_props_chunk_lock);
1036 props = g_mem_chunk_alloc (_gst_props_chunk);
1037 g_mutex_unlock (_gst_props_chunk_lock);
1039 props->properties = NULL;
1040 props->refcount = 1;
1043 if (!strcmp (field->name, "list")) {
1044 GstPropsEntry *entry;
1045 xmlNodePtr subfield = field->xmlChildrenNode;
1047 g_mutex_lock (_gst_props_entries_chunk_lock);
1048 entry = g_mem_chunk_alloc (_gst_props_entries_chunk);
1049 g_mutex_unlock (_gst_props_entries_chunk_lock);
1051 entry->propstype = GST_PROPS_LIST_ID_NUM;
1052 entry->data.list_data.entries = NULL;
1053 prop = xmlGetProp (field, "name");
1054 entry->propid = g_quark_from_string (prop);
1058 GstPropsEntry *subentry = gst_props_load_thyself_func (subfield);
1061 entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, subentry);
1063 subfield = subfield->next;
1065 entry->data.list_data.entries = g_list_reverse (entry->data.list_data.entries);
1066 props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func);
1069 GstPropsEntry *entry;
1071 entry = gst_props_load_thyself_func (field);
1074 props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func);
1076 field = field->next;