2 * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
4 * gsttaglist.c: tag support (aka metadata)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
24 * @short_description: List of tags and values used to describe media metadata
26 * List of tags and values used to describe media metadata.
28 * Last reviewed on 2005-11-23 (0.9.5)
35 #include "gst_private.h"
36 #include "gst-i18n-lib.h"
37 #include "gsttaglist.h"
40 #include "gstbuffer.h"
42 #include <gobject/gvaluecollector.h>
45 #define GST_TAG_IS_VALID(tag) (gst_tag_get_info (tag) != NULL)
49 GType type; /* type the data is in */
51 gchar *nick; /* translated name */
52 gchar *blurb; /* translated description of type */
54 GstTagMergeFunc merge_func; /* functions to merge the values */
55 GstTagFlag flag; /* type of tag */
59 #define TAGLIST "taglist"
60 static GQuark gst_tag_list_quark;
61 static GMutex *__tag_mutex;
62 static GHashTable *__tags;
64 #define TAG_LOCK g_mutex_lock (__tag_mutex)
65 #define TAG_UNLOCK g_mutex_unlock (__tag_mutex)
68 gst_tag_list_get_type (void)
70 static GType _gst_tag_list_type;
72 if (_gst_tag_list_type == 0) {
73 _gst_tag_list_type = g_boxed_type_register_static ("GstTagList",
74 (GBoxedCopyFunc) gst_tag_list_copy, (GBoxedFreeFunc) gst_tag_list_free);
77 g_value_register_transform_func (_gst_tag_list_type, G_TYPE_STRING,
78 _gst_structure_transform_to_string);
82 return _gst_tag_list_type;
86 _gst_tag_initialize (void)
88 gst_tag_list_quark = g_quark_from_static_string (TAGLIST);
89 __tag_mutex = g_mutex_new ();
90 __tags = g_hash_table_new (g_direct_hash, g_direct_equal);
91 gst_tag_register (GST_TAG_TITLE, GST_TAG_FLAG_META,
93 _("title"), _("commonly used title"), gst_tag_merge_strings_with_comma);
94 gst_tag_register (GST_TAG_ARTIST, GST_TAG_FLAG_META,
97 _("person(s) responsible for the recording"),
98 gst_tag_merge_strings_with_comma);
99 gst_tag_register (GST_TAG_ALBUM, GST_TAG_FLAG_META,
102 _("album containing this data"), gst_tag_merge_strings_with_comma);
103 gst_tag_register (GST_TAG_DATE, GST_TAG_FLAG_META, GST_TYPE_DATE,
104 _("date"), _("date the data was created (as a GDate structure)"), NULL);
105 gst_tag_register (GST_TAG_GENRE, GST_TAG_FLAG_META,
108 _("genre this data belongs to"), gst_tag_merge_strings_with_comma);
109 gst_tag_register (GST_TAG_COMMENT, GST_TAG_FLAG_META,
112 _("free text commenting the data"), gst_tag_merge_strings_with_comma);
113 gst_tag_register (GST_TAG_TRACK_NUMBER, GST_TAG_FLAG_META,
116 _("track number inside a collection"), gst_tag_merge_use_first);
117 gst_tag_register (GST_TAG_TRACK_COUNT, GST_TAG_FLAG_META,
120 _("count of tracks inside collection this track belongs to"),
121 gst_tag_merge_use_first);
122 gst_tag_register (GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_FLAG_META,
125 _("disc number inside a collection"), gst_tag_merge_use_first);
126 gst_tag_register (GST_TAG_ALBUM_VOLUME_COUNT, GST_TAG_FLAG_META,
129 _("count of discs inside collection this disc belongs to"),
130 gst_tag_merge_use_first);
131 gst_tag_register (GST_TAG_LOCATION, GST_TAG_FLAG_META,
134 _("original location of file as a URI"),
135 gst_tag_merge_strings_with_comma);
136 gst_tag_register (GST_TAG_DESCRIPTION, GST_TAG_FLAG_META,
139 _("short text describing the content of the data"),
140 gst_tag_merge_strings_with_comma);
141 gst_tag_register (GST_TAG_VERSION, GST_TAG_FLAG_META,
142 G_TYPE_STRING, _("version"), _("version of this data"), NULL);
143 gst_tag_register (GST_TAG_ISRC, GST_TAG_FLAG_META,
147 ("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
149 gst_tag_register (GST_TAG_ORGANIZATION, GST_TAG_FLAG_META, G_TYPE_STRING, _("organization"), _("organization"), /* FIXME */
150 gst_tag_merge_strings_with_comma);
151 gst_tag_register (GST_TAG_COPYRIGHT, GST_TAG_FLAG_META,
152 G_TYPE_STRING, _("copyright"), _("copyright notice of the data"), NULL);
153 gst_tag_register (GST_TAG_CONTACT, GST_TAG_FLAG_META,
155 _("contact"), _("contact information"), gst_tag_merge_strings_with_comma);
156 gst_tag_register (GST_TAG_LICENSE, GST_TAG_FLAG_META,
157 G_TYPE_STRING, _("license"), _("license of data"), NULL);
158 gst_tag_register (GST_TAG_PERFORMER, GST_TAG_FLAG_META,
161 _("person(s) performing"), gst_tag_merge_strings_with_comma);
162 gst_tag_register (GST_TAG_DURATION, GST_TAG_FLAG_DECODED,
164 _("duration"), _("length in GStreamer time units (nanoseconds)"), NULL);
165 gst_tag_register (GST_TAG_CODEC, GST_TAG_FLAG_ENCODED,
168 _("codec the data is stored in"), gst_tag_merge_strings_with_comma);
169 gst_tag_register (GST_TAG_VIDEO_CODEC, GST_TAG_FLAG_ENCODED,
171 _("video codec"), _("codec the video data is stored in"), NULL);
172 gst_tag_register (GST_TAG_AUDIO_CODEC, GST_TAG_FLAG_ENCODED,
174 _("audio codec"), _("codec the audio data is stored in"), NULL);
175 gst_tag_register (GST_TAG_BITRATE, GST_TAG_FLAG_ENCODED,
176 G_TYPE_UINT, _("bitrate"), _("exact or average bitrate in bits/s"), NULL);
177 gst_tag_register (GST_TAG_NOMINAL_BITRATE, GST_TAG_FLAG_ENCODED,
178 G_TYPE_UINT, _("nominal bitrate"), _("nominal bitrate in bits/s"), NULL);
179 gst_tag_register (GST_TAG_MINIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
180 G_TYPE_UINT, _("minimum bitrate"), _("minimum bitrate in bits/s"), NULL);
181 gst_tag_register (GST_TAG_MAXIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
182 G_TYPE_UINT, _("maximum bitrate"), _("maximum bitrate in bits/s"), NULL);
183 gst_tag_register (GST_TAG_ENCODER, GST_TAG_FLAG_ENCODED,
185 _("encoder"), _("encoder used to encode this stream"), NULL);
186 gst_tag_register (GST_TAG_ENCODER_VERSION, GST_TAG_FLAG_ENCODED,
188 _("encoder version"),
189 _("version of the encoder used to encode this stream"), NULL);
190 gst_tag_register (GST_TAG_SERIAL, GST_TAG_FLAG_ENCODED,
191 G_TYPE_UINT, _("serial"), _("serial number of track"), NULL);
192 gst_tag_register (GST_TAG_TRACK_GAIN, GST_TAG_FLAG_META,
193 G_TYPE_DOUBLE, _("replaygain track gain"), _("track gain in db"), NULL);
194 gst_tag_register (GST_TAG_TRACK_PEAK, GST_TAG_FLAG_META,
195 G_TYPE_DOUBLE, _("replaygain track peak"), _("peak of the track"), NULL);
196 gst_tag_register (GST_TAG_ALBUM_GAIN, GST_TAG_FLAG_META,
197 G_TYPE_DOUBLE, _("replaygain album gain"), _("album gain in db"), NULL);
198 gst_tag_register (GST_TAG_ALBUM_PEAK, GST_TAG_FLAG_META,
199 G_TYPE_DOUBLE, _("replaygain album peak"), _("peak of the album"), NULL);
200 gst_tag_register (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META, G_TYPE_STRING,
202 _("language code for this stream, conforming to ISO-639-1"), NULL);
203 gst_tag_register (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
204 _("image"), _("image related to this stream"), NULL);
205 gst_tag_register (GST_TAG_PREVIEW_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
206 _("preview image"), _("preview image related to this stream"), NULL);
210 * gst_tag_merge_use_first:
211 * @dest: uninitialized GValue to store result in
212 * @src: GValue to copy from
214 * This is a convenience function for the func argument of gst_tag_register().
215 * It creates a copy of the first value from the list.
218 gst_tag_merge_use_first (GValue * dest, const GValue * src)
220 const GValue *ret = gst_value_list_get_value (src, 0);
222 g_value_init (dest, G_VALUE_TYPE (ret));
223 g_value_copy (ret, dest);
227 * gst_tag_merge_strings_with_comma:
228 * @dest: uninitialized GValue to store result in
229 * @src: GValue to copy from
231 * This is a convenience function for the func argument of gst_tag_register().
232 * It concatenates all given strings using a comma. The tag must be registered
233 * as a G_TYPE_STRING or this function will fail.
236 gst_tag_merge_strings_with_comma (GValue * dest, const GValue * src)
241 count = gst_value_list_get_size (src);
242 str = g_string_new (g_value_get_string (gst_value_list_get_value (src, 0)));
243 for (i = 1; i < count; i++) {
244 /* seperator between two string */
245 str = g_string_append (str, _(", "));
247 g_string_append (str, g_value_get_string (gst_value_list_get_value (src,
251 g_value_init (dest, G_TYPE_STRING);
252 g_value_set_string_take_ownership (dest, str->str);
253 g_string_free (str, FALSE);
256 gst_tag_lookup (GQuark entry)
261 ret = g_hash_table_lookup (__tags, GUINT_TO_POINTER (entry));
269 * @name: the name or identifier string
270 * @flag: a flag describing the type of tag info
271 * @type: the type this data is in
272 * @nick: human-readable name
273 * @blurb: a human-readable description about this tag
274 * @func: function for merging multiple values of this tag
276 * Registers a new tag type for the use with GStreamer's type system. If a type
277 * with that name is already registered, that one is used.
278 * The old registration may have used a different type however. So don't rely
279 * on your supplied values.
282 gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
283 const gchar * nick, const gchar * blurb, GstTagMergeFunc func)
288 g_return_if_fail (name != NULL);
289 g_return_if_fail (nick != NULL);
290 g_return_if_fail (blurb != NULL);
291 g_return_if_fail (type != 0 && type != GST_TYPE_LIST);
293 key = g_quark_from_string (name);
294 info = gst_tag_lookup (key);
297 g_return_if_fail (info->type == type);
301 info = g_new (GstTagInfo, 1);
304 info->nick = g_strdup (nick);
305 info->blurb = g_strdup (blurb);
306 info->merge_func = func;
309 g_hash_table_insert (__tags, GUINT_TO_POINTER (key), info);
315 * @tag: name of the tag
317 * Checks if the given type is already registered.
319 * Returns: TRUE if the type is already registered
322 gst_tag_exists (const gchar * tag)
324 g_return_val_if_fail (tag != NULL, FALSE);
326 return gst_tag_lookup (g_quark_from_string (tag)) != NULL;
333 * Gets the #GType used for this tag.
335 * Returns: the #GType of this tag
338 gst_tag_get_type (const gchar * tag)
342 g_return_val_if_fail (tag != NULL, 0);
343 info = gst_tag_lookup (g_quark_from_string (tag));
344 g_return_val_if_fail (info != NULL, 0);
353 * Returns the human-readable name of this tag, You must not change or free
356 * Returns: the human-readable name of this tag
359 gst_tag_get_nick (const gchar * tag)
363 g_return_val_if_fail (tag != NULL, NULL);
364 info = gst_tag_lookup (g_quark_from_string (tag));
365 g_return_val_if_fail (info != NULL, NULL);
371 * gst_tag_get_description:
374 * Returns the human-readable description of this tag, You must not change or
377 * Returns: the human-readable description of this tag
380 gst_tag_get_description (const gchar * tag)
384 g_return_val_if_fail (tag != NULL, NULL);
385 info = gst_tag_lookup (g_quark_from_string (tag));
386 g_return_val_if_fail (info != NULL, NULL);
395 * Gets the flag of @tag.
397 * Returns the flag of this tag.
400 gst_tag_get_flag (const gchar * tag)
404 g_return_val_if_fail (tag != NULL, GST_TAG_FLAG_UNDEFINED);
405 info = gst_tag_lookup (g_quark_from_string (tag));
406 g_return_val_if_fail (info != NULL, GST_TAG_FLAG_UNDEFINED);
415 * Checks if the given tag is fixed. A fixed tag can only contain one value.
416 * Unfixed tags can contain lists of values.
418 * Returns: TRUE, if the given tag is fixed.
421 gst_tag_is_fixed (const gchar * tag)
425 g_return_val_if_fail (tag != NULL, FALSE);
426 info = gst_tag_lookup (g_quark_from_string (tag));
427 g_return_val_if_fail (info != NULL, FALSE);
429 return info->merge_func == NULL;
435 * Creates a new empty GstTagList.
437 * Returns: An empty tag list
440 gst_tag_list_new (void)
442 return GST_TAG_LIST (gst_structure_new (TAGLIST, NULL));
447 * @p: Object that might be a taglist
449 * Checks if the given pointer is a taglist.
451 * Returns: TRUE, if the given pointer is a taglist
454 gst_is_tag_list (gconstpointer p)
456 g_return_val_if_fail (p != NULL, FALSE);
458 return ((GstStructure *) p)->name == gst_tag_list_quark;
463 GstTagMergeMode mode;
467 gst_tag_list_add_value_internal (GstStructure * list, GstTagMergeMode mode,
468 GQuark tag, const GValue * value)
470 GstTagInfo *info = gst_tag_lookup (tag);
471 const GValue *value2;
473 g_assert (info != NULL);
476 && (value2 = gst_structure_id_get_value (list, tag)) != NULL) {
477 GValue dest = { 0, };
480 case GST_TAG_MERGE_REPLACE_ALL:
481 case GST_TAG_MERGE_REPLACE:
482 gst_structure_id_set_value (list, tag, value);
484 case GST_TAG_MERGE_PREPEND:
485 gst_value_list_concat (&dest, value, value2);
486 gst_structure_id_set_value (list, tag, &dest);
487 g_value_unset (&dest);
489 case GST_TAG_MERGE_APPEND:
490 gst_value_list_concat (&dest, value2, value);
491 gst_structure_id_set_value (list, tag, &dest);
492 g_value_unset (&dest);
494 case GST_TAG_MERGE_KEEP:
495 case GST_TAG_MERGE_KEEP_ALL:
498 g_assert_not_reached ();
503 case GST_TAG_MERGE_APPEND:
504 case GST_TAG_MERGE_KEEP:
505 if (gst_structure_id_get_value (list, tag) != NULL)
508 case GST_TAG_MERGE_REPLACE_ALL:
509 case GST_TAG_MERGE_REPLACE:
510 case GST_TAG_MERGE_PREPEND:
511 gst_structure_id_set_value (list, tag, value);
513 case GST_TAG_MERGE_KEEP_ALL:
516 g_assert_not_reached ();
522 gst_tag_list_copy_foreach (GQuark tag, const GValue * value, gpointer user_data)
524 GstTagCopyData *copy = (GstTagCopyData *) user_data;
526 gst_tag_list_add_value_internal (copy->list, copy->mode, tag, value);
532 * gst_tag_list_insert:
533 * @into: list to merge into
534 * @from: list to merge from
535 * @mode: the mode to use
537 * Inserts the tags of the second list into the first list using the given mode.
540 gst_tag_list_insert (GstTagList * into, const GstTagList * from,
541 GstTagMergeMode mode)
545 g_return_if_fail (GST_IS_TAG_LIST (into));
546 g_return_if_fail (GST_IS_TAG_LIST (from));
547 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
549 data.list = (GstStructure *) into;
551 if (mode == GST_TAG_MERGE_REPLACE_ALL) {
552 gst_structure_remove_all_fields (data.list);
554 gst_structure_foreach ((GstStructure *) from, gst_tag_list_copy_foreach,
560 * @list: list to copy
562 * Copies a given #GstTagList.
564 * Returns: copy of the given list
567 gst_tag_list_copy (const GstTagList * list)
569 g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
571 return GST_TAG_LIST (gst_structure_copy ((GstStructure *) list));
575 * gst_tag_list_merge:
576 * @list1: first list to merge
577 * @list2: second list to merge
578 * @mode: the mode to use
580 * Merges the two given lists into a new list. If one of the lists is NULL, a
581 * copy of the other is returned. If both lists are NULL, NULL is returned.
583 * Returns: the new list
586 gst_tag_list_merge (const GstTagList * list1, const GstTagList * list2,
587 GstTagMergeMode mode)
589 g_return_val_if_fail (list1 == NULL || GST_IS_TAG_LIST (list1), NULL);
590 g_return_val_if_fail (list2 == NULL || GST_IS_TAG_LIST (list2), NULL);
591 g_return_val_if_fail (GST_TAG_MODE_IS_VALID (mode), NULL);
593 if (!list1 && !list2) {
596 return gst_tag_list_copy (list2);
598 return gst_tag_list_copy (list1);
602 ret = gst_tag_list_copy (list1);
603 gst_tag_list_insert (ret, list2, mode);
610 * @list: the list to free
612 * Frees the given list and all associated values.
615 gst_tag_list_free (GstTagList * list)
617 g_return_if_fail (GST_IS_TAG_LIST (list));
618 gst_structure_free ((GstStructure *) list);
622 * gst_tag_list_get_tag_size:
624 * @tag: the tag to query
626 * Checks how many value are stored in this tag list for the given tag.
628 * Returns: The number of tags stored
631 gst_tag_list_get_tag_size (const GstTagList * list, const gchar * tag)
635 g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
637 value = gst_structure_get_value ((GstStructure *) list, tag);
640 if (G_VALUE_TYPE (value) != GST_TYPE_LIST)
643 return gst_value_list_get_size (value);
648 * @list: list to set tags in
649 * @mode: the mode to use
651 * @...: NULL-terminated list of values to set
653 * Sets the values for the given tags using the specified mode.
656 gst_tag_list_add (GstTagList * list, GstTagMergeMode mode, const gchar * tag,
661 g_return_if_fail (GST_IS_TAG_LIST (list));
662 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
663 g_return_if_fail (tag != NULL);
665 va_start (args, tag);
666 gst_tag_list_add_valist (list, mode, tag, args);
671 * gst_tag_list_add_values:
672 * @list: list to set tags in
673 * @mode: the mode to use
675 * @...: GValues to set
677 * Sets the GValues for the given tags using the specified mode.
680 gst_tag_list_add_values (GstTagList * list, GstTagMergeMode mode,
681 const gchar * tag, ...)
685 g_return_if_fail (GST_IS_TAG_LIST (list));
686 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
687 g_return_if_fail (tag != NULL);
689 va_start (args, tag);
690 gst_tag_list_add_valist_values (list, mode, tag, args);
695 * gst_tag_list_add_valist:
696 * @list: list to set tags in
697 * @mode: the mode to use
699 * @var_args: tag / value pairs to set
701 * Sets the values for the given tags using the specified mode.
704 gst_tag_list_add_valist (GstTagList * list, GstTagMergeMode mode,
705 const gchar * tag, va_list var_args)
711 g_return_if_fail (GST_IS_TAG_LIST (list));
712 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
713 g_return_if_fail (tag != NULL);
715 while (tag != NULL) {
716 GValue value = { 0, };
718 quark = g_quark_from_string (tag);
719 info = gst_tag_lookup (quark);
721 g_warning ("no GstTag for %s", tag);
722 g_return_if_fail (info != NULL);
723 g_value_init (&value, info->type);
724 G_VALUE_COLLECT (&value, var_args, 0, &error);
726 g_warning ("%s: %s", G_STRLOC, error);
728 /* we purposely leak the value here, it might not be
729 * in a sane state if an error condition occoured
733 gst_tag_list_add_value_internal (list, mode, quark, &value);
734 g_value_unset (&value);
735 tag = va_arg (var_args, gchar *);
740 * gst_tag_list_add_valist_values:
741 * @list: list to set tags in
742 * @mode: the mode to use
744 * @var_args: tag / GValue pairs to set
746 * Sets the GValues for the given tags using the specified mode.
749 gst_tag_list_add_valist_values (GstTagList * list, GstTagMergeMode mode,
750 const gchar * tag, va_list var_args)
755 g_return_if_fail (GST_IS_TAG_LIST (list));
756 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
757 g_return_if_fail (tag != NULL);
759 while (tag != NULL) {
760 quark = g_quark_from_string (tag);
761 info = gst_tag_lookup (quark);
762 g_return_if_fail (info != NULL);
763 gst_tag_list_add_value_internal (list, mode, quark, va_arg (var_args,
765 tag = va_arg (var_args, gchar *);
770 * gst_tag_list_remove_tag:
771 * @list: list to remove tag from
772 * @tag: tag to remove
774 * Removes the goven tag from the taglist.
777 gst_tag_list_remove_tag (GstTagList * list, const gchar * tag)
779 g_return_if_fail (GST_IS_TAG_LIST (list));
780 g_return_if_fail (tag != NULL);
782 gst_structure_remove_field ((GstStructure *) list, tag);
786 GstTagForeachFunc func;
787 const GstTagList *tag_list;
792 structure_foreach_wrapper (GQuark field_id, const GValue * value,
795 TagForeachData *data = (TagForeachData *) user_data;
797 data->func (data->tag_list, g_quark_to_string (field_id), data->data);
802 * gst_tag_list_foreach:
803 * @list: list to iterate over
804 * @func: function to be called for each tag
805 * @user_data: user specified data
807 * Calls the given function for each tag inside the tag list. Note that if there
808 * is no tag, the function won't be called at all.
811 gst_tag_list_foreach (const GstTagList * list, GstTagForeachFunc func,
816 g_return_if_fail (GST_IS_TAG_LIST (list));
817 g_return_if_fail (func != NULL);
820 data.tag_list = list;
821 data.data = user_data;
822 gst_structure_foreach ((GstStructure *) list, structure_foreach_wrapper,
827 * gst_tag_list_get_value_index:
828 * @list: a #GStTagList
829 * @tag: tag to read out
830 * @index: number of entry to read out
832 * Gets the value that is at the given index for the given tag in the given
835 * Returns: The GValue for the specified entry or NULL if the tag wasn't
836 * available or the tag doesn't have as many entries
838 G_CONST_RETURN GValue *
839 gst_tag_list_get_value_index (const GstTagList * list, const gchar * tag,
844 g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
845 g_return_val_if_fail (tag != NULL, NULL);
847 value = gst_structure_get_value ((GstStructure *) list, tag);
851 if (GST_VALUE_HOLDS_LIST (value)) {
852 if (index >= gst_value_list_get_size (value))
854 return gst_value_list_get_value (value, index);
863 * gst_tag_list_copy_value:
864 * @dest: uninitialized #GValue to copy into
865 * @list: list to get the tag from
866 * @tag: tag to read out
868 * Copies the contents for the given tag into the value,
869 * merging multiple values into one if multiple values are associated
871 * You must g_value_unset() the value after use.
873 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
877 gst_tag_list_copy_value (GValue * dest, const GstTagList * list,
882 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
883 g_return_val_if_fail (tag != NULL, FALSE);
884 g_return_val_if_fail (dest != NULL, FALSE);
885 g_return_val_if_fail (G_VALUE_TYPE (dest) == 0, FALSE);
887 src = gst_structure_get_value ((GstStructure *) list, tag);
891 if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
892 GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag));
894 /* must be there or lists aren't allowed */
895 g_assert (info->merge_func);
896 info->merge_func (dest, src);
898 g_value_init (dest, G_VALUE_TYPE (src));
899 g_value_copy (src, dest);
904 /***** evil macros to get all the gst_tag_list_get_*() functions right *****/
906 #define TAG_MERGE_FUNCS(name,type) \
908 gst_tag_list_get_ ## name (const GstTagList *list, const gchar *tag, \
913 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
914 g_return_val_if_fail (tag != NULL, FALSE); \
915 g_return_val_if_fail (value != NULL, FALSE); \
917 if (!gst_tag_list_copy_value (&v, list, tag)) \
919 *value = COPY_FUNC (g_value_get_ ## name (&v)); \
920 g_value_unset (&v); \
925 gst_tag_list_get_ ## name ## _index (const GstTagList *list, \
927 guint index, type *value) \
931 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
932 g_return_val_if_fail (tag != NULL, FALSE); \
933 g_return_val_if_fail (value != NULL, FALSE); \
935 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL) \
937 *value = COPY_FUNC (g_value_get_ ## name (v)); \
941 #define COPY_FUNC /**/
943 * gst_tag_list_get_char:
944 * @list: a #GStTagList to get the tag from
945 * @tag: tag to read out
946 * @value: location for the result
948 * Copies the contents for the given tag into the value, merging multiple values
949 * into one if multiple values are associated with the tag.
951 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
955 * gst_tag_list_get_char_index:
956 * @list: a #GStTagList to get the tag from
957 * @tag: tag to read out
958 * @index: number of entry to read out
959 * @value: location for the result
961 * Gets the value that is at the given index for the given tag in the given
964 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
967 TAG_MERGE_FUNCS (char, gchar)
969 * gst_tag_list_get_uchar:
970 * @list: a #GStTagList to get the tag from
971 * @tag: tag to read out
972 * @value: location for the result
974 * Copies the contents for the given tag into the value, merging multiple values
975 * into one if multiple values are associated with the tag.
977 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
981 * gst_tag_list_get_uchar_index:
982 * @list: a #GStTagList to get the tag from
983 * @tag: tag to read out
984 * @index: number of entry to read out
985 * @value: location for the result
987 * Gets the value that is at the given index for the given tag in the given
990 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
993 TAG_MERGE_FUNCS (uchar, guchar)
995 * gst_tag_list_get_boolean:
996 * @list: a #GStTagList to get the tag from
997 * @tag: tag to read out
998 * @value: location for the result
1000 * Copies the contents for the given tag into the value, merging multiple values
1001 * into one if multiple values are associated with the tag.
1003 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1007 * gst_tag_list_get_boolean_index:
1008 * @list: a #GStTagList to get the tag from
1009 * @tag: tag to read out
1010 * @index: number of entry to read out
1011 * @value: location for the result
1013 * Gets the value that is at the given index for the given tag in the given
1016 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1019 TAG_MERGE_FUNCS (boolean, gboolean)
1021 * gst_tag_list_get_int:
1022 * @list: a #GStTagList to get the tag from
1023 * @tag: tag to read out
1024 * @value: location for the result
1026 * Copies the contents for the given tag into the value, merging multiple values
1027 * into one if multiple values are associated with the tag.
1029 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1033 * gst_tag_list_get_int_index:
1034 * @list: a #GStTagList to get the tag from
1035 * @tag: tag to read out
1036 * @index: number of entry to read out
1037 * @value: location for the result
1039 * Gets the value that is at the given index for the given tag in the given
1042 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1045 TAG_MERGE_FUNCS (int, gint)
1047 * gst_tag_list_get_uint:
1048 * @list: a #GStTagList to get the tag from
1049 * @tag: tag to read out
1050 * @value: location for the result
1052 * Copies the contents for the given tag into the value, merging multiple values
1053 * into one if multiple values are associated with the tag.
1055 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1059 * gst_tag_list_get_uint_index:
1060 * @list: a #GStTagList to get the tag from
1061 * @tag: tag to read out
1062 * @index: number of entry to read out
1063 * @value: location for the result
1065 * Gets the value that is at the given index for the given tag in the given
1068 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1071 TAG_MERGE_FUNCS (uint, guint)
1073 * gst_tag_list_get_long:
1074 * @list: a #GStTagList to get the tag from
1075 * @tag: tag to read out
1076 * @value: location for the result
1078 * Copies the contents for the given tag into the value, merging multiple values
1079 * into one if multiple values are associated with the tag.
1081 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1085 * gst_tag_list_get_long_index:
1086 * @list: a #GStTagList to get the tag from
1087 * @tag: tag to read out
1088 * @index: number of entry to read out
1089 * @value: location for the result
1091 * Gets the value that is at the given index for the given tag in the given
1094 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1097 TAG_MERGE_FUNCS (long, glong)
1099 * gst_tag_list_get_ulong:
1100 * @list: a #GStTagList to get the tag from
1101 * @tag: tag to read out
1102 * @value: location for the result
1104 * Copies the contents for the given tag into the value, merging multiple values
1105 * into one if multiple values are associated with the tag.
1107 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1111 * gst_tag_list_get_ulong_index:
1112 * @list: a #GStTagList to get the tag from
1113 * @tag: tag to read out
1114 * @index: number of entry to read out
1115 * @value: location for the result
1117 * Gets the value that is at the given index for the given tag in the given
1120 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1123 TAG_MERGE_FUNCS (ulong, gulong)
1125 * gst_tag_list_get_int64:
1126 * @list: a #GStTagList to get the tag from
1127 * @tag: tag to read out
1128 * @value: location for the result
1130 * Copies the contents for the given tag into the value, merging multiple values
1131 * into one if multiple values are associated with the tag.
1133 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1137 * gst_tag_list_get_int64_index:
1138 * @list: a #GStTagList to get the tag from
1139 * @tag: tag to read out
1140 * @index: number of entry to read out
1141 * @value: location for the result
1143 * Gets the value that is at the given index for the given tag in the given
1146 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1149 TAG_MERGE_FUNCS (int64, gint64)
1151 * gst_tag_list_get_uint64:
1152 * @list: a #GStTagList to get the tag from
1153 * @tag: tag to read out
1154 * @value: location for the result
1156 * Copies the contents for the given tag into the value, merging multiple values
1157 * into one if multiple values are associated with the tag.
1159 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1163 * gst_tag_list_get_uint64_index:
1164 * @list: a #GStTagList to get the tag from
1165 * @tag: tag to read out
1166 * @index: number of entry to read out
1167 * @value: location for the result
1169 * Gets the value that is at the given index for the given tag in the given
1172 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1175 TAG_MERGE_FUNCS (uint64, guint64)
1177 * gst_tag_list_get_float:
1178 * @list: a #GStTagList to get the tag from
1179 * @tag: tag to read out
1180 * @value: location for the result
1182 * Copies the contents for the given tag into the value, merging multiple values
1183 * into one if multiple values are associated with the tag.
1185 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1189 * gst_tag_list_get_float_index:
1190 * @list: a #GStTagList to get the tag from
1191 * @tag: tag to read out
1192 * @index: number of entry to read out
1193 * @value: location for the result
1195 * Gets the value that is at the given index for the given tag in the given
1198 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1201 TAG_MERGE_FUNCS (float, gfloat)
1203 * gst_tag_list_get_double:
1204 * @list: a #GStTagList to get the tag from
1205 * @tag: tag to read out
1206 * @value: location for the result
1208 * Copies the contents for the given tag into the value, merging multiple values
1209 * into one if multiple values are associated with the tag.
1211 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1215 * gst_tag_list_get_double_index:
1216 * @list: a #GStTagList to get the tag from
1217 * @tag: tag to read out
1218 * @index: number of entry to read out
1219 * @value: location for the result
1221 * Gets the value that is at the given index for the given tag in the given
1224 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1227 TAG_MERGE_FUNCS (double, gdouble)
1229 * gst_tag_list_get_pointer:
1230 * @list: a #GStTagList to get the tag from
1231 * @tag: tag to read out
1232 * @value: location for the result
1234 * Copies the contents for the given tag into the value, merging multiple values
1235 * into one if multiple values are associated with the tag.
1237 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1241 * gst_tag_list_get_pointer_index:
1242 * @list: a #GStTagList to get the tag from
1243 * @tag: tag to read out
1244 * @index: number of entry to read out
1245 * @value: location for the result
1247 * Gets the value that is at the given index for the given tag in the given
1250 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1253 TAG_MERGE_FUNCS (pointer, gpointer)
1255 #define COPY_FUNC g_strdup
1257 * gst_tag_list_get_string:
1258 * @list: a #GStTagList to get the tag from
1259 * @tag: tag to read out
1260 * @value: location for the result
1262 * Copies the contents for the given tag into the value, merging multiple values
1263 * into one if multiple values are associated with the tag.
1265 * The resulting string in @value should be freed by the caller using g_free
1266 * when no longer needed
1268 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1272 * gst_tag_list_get_string_index:
1273 * @list: a #GStTagList to get the tag from
1274 * @tag: tag to read out
1275 * @index: number of entry to read out
1276 * @value: location for the result
1278 * Gets the value that is at the given index for the given tag in the given
1281 * The resulting string in @value should be freed by the caller using g_free
1282 * when no longer needed
1284 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1287 TAG_MERGE_FUNCS (string, gchar *)
1290 * gst_tag_list_get_date:
1291 * @list: a #GStTagList to get the tag from
1292 * @tag: tag to read out
1293 * @value: location for the result
1295 * Copies the contents for the given tag into the value, merging multiple values
1296 * into one if multiple values are associated with the tag.
1298 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1299 * given list or if it was #NULL.
1302 gst_tag_list_get_date (const GstTagList * list, const gchar * tag,
1307 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1308 g_return_val_if_fail (tag != NULL, FALSE);
1309 g_return_val_if_fail (value != NULL, FALSE);
1311 if (!gst_tag_list_copy_value (&v, list, tag))
1313 *value = (GDate *) g_value_dup_boxed (&v);
1315 return (*value != NULL);
1319 * gst_tag_list_get_date_index:
1320 * @list: a #GStTagList to get the tag from
1321 * @tag: tag to read out
1322 * @index: number of entry to read out
1323 * @value: location for the result
1325 * Gets the value that is at the given index for the given tag in the given
1328 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1329 * given list or if it was #NULL.
1332 gst_tag_list_get_date_index (const GstTagList * list,
1333 const gchar * tag, guint index, GDate ** value)
1337 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1338 g_return_val_if_fail (tag != NULL, FALSE);
1339 g_return_val_if_fail (value != NULL, FALSE);
1341 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
1343 *value = (GDate *) g_value_dup_boxed (v);
1344 return (*value != NULL);