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 * Strings must be in ASCII or UTF-8 encoding. No other encodings are allowed.
30 * Last reviewed on 2009-06-09 (0.10.23)
37 #include "gst_private.h"
38 #include "math-compat.h"
39 #include "gst-i18n-lib.h"
40 #include "gsttaglist.h"
43 #include "gstbuffer.h"
46 #include <gobject/gvaluecollector.h>
49 #define GST_TAG_IS_VALID(tag) (gst_tag_get_info (tag) != NULL)
51 /* FIXME 0.11: use GParamSpecs or something similar for tag registrations,
52 * possibly even gst_tag_register(). Especially value ranges might be
53 * useful for some tags. */
57 GType type; /* type the data is in */
59 gchar *nick; /* translated name */
60 gchar *blurb; /* translated description of type */
62 GstTagMergeFunc merge_func; /* functions to merge the values */
63 GstTagFlag flag; /* type of tag */
64 GQuark name_quark; /* quark for the name */
68 static GMutex *__tag_mutex;
70 /* tags hash table: maps tag name string => GstTagInfo */
71 static GHashTable *__tags;
73 #define TAG_LOCK g_mutex_lock (__tag_mutex)
74 #define TAG_UNLOCK g_mutex_unlock (__tag_mutex)
77 gst_tag_list_get_type (void)
79 static GType _gst_tag_list_type = 0;
81 if (G_UNLIKELY (_gst_tag_list_type == 0)) {
82 _gst_tag_list_type = g_boxed_type_register_static ("GstTagList",
83 (GBoxedCopyFunc) gst_tag_list_copy, (GBoxedFreeFunc) gst_tag_list_free);
86 g_value_register_transform_func (_gst_tag_list_type, G_TYPE_STRING,
87 _gst_structure_transform_to_string);
91 return _gst_tag_list_type;
95 _priv_gst_tag_initialize (void)
97 __tag_mutex = g_mutex_new ();
98 __tags = g_hash_table_new (g_str_hash, g_str_equal);
99 gst_tag_register (GST_TAG_TITLE, GST_TAG_FLAG_META,
101 _("title"), _("commonly used title"), gst_tag_merge_strings_with_comma);
102 gst_tag_register (GST_TAG_TITLE_SORTNAME, GST_TAG_FLAG_META,
104 _("title sortname"), _("commonly used title for sorting purposes"), NULL);
105 gst_tag_register (GST_TAG_ARTIST, GST_TAG_FLAG_META,
108 _("person(s) responsible for the recording"),
109 gst_tag_merge_strings_with_comma);
110 gst_tag_register (GST_TAG_ARTIST_SORTNAME, GST_TAG_FLAG_META,
112 _("artist sortname"),
113 _("person(s) responsible for the recording for sorting purposes"), NULL);
114 gst_tag_register (GST_TAG_ALBUM, GST_TAG_FLAG_META,
117 _("album containing this data"), gst_tag_merge_strings_with_comma);
118 gst_tag_register (GST_TAG_ALBUM_SORTNAME, GST_TAG_FLAG_META,
121 _("album containing this data for sorting purposes"), NULL);
122 gst_tag_register (GST_TAG_ALBUM_ARTIST, GST_TAG_FLAG_META,
125 _("The artist of the entire album, as it should be displayed"),
126 gst_tag_merge_strings_with_comma);
127 gst_tag_register (GST_TAG_ALBUM_ARTIST_SORTNAME, GST_TAG_FLAG_META,
129 _("album artist sortname"),
130 _("The artist of the entire album, as it should be sorted"), NULL);
131 gst_tag_register (GST_TAG_DATE, GST_TAG_FLAG_META, GST_TYPE_DATE,
132 _("date"), _("date the data was created (as a GDate structure)"), NULL);
133 gst_tag_register (GST_TAG_DATE_TIME, GST_TAG_FLAG_META, GST_TYPE_DATE_TIME,
135 _("date and time the data was created (as a GstDateTime structure)"),
137 gst_tag_register (GST_TAG_GENRE, GST_TAG_FLAG_META,
140 _("genre this data belongs to"), gst_tag_merge_strings_with_comma);
141 gst_tag_register (GST_TAG_COMMENT, GST_TAG_FLAG_META,
144 _("free text commenting the data"), gst_tag_merge_use_first);
145 gst_tag_register (GST_TAG_EXTENDED_COMMENT, GST_TAG_FLAG_META,
147 _("extended comment"),
148 _("free text commenting the data in key=value or key[en]=comment form"),
149 gst_tag_merge_use_first);
150 gst_tag_register (GST_TAG_TRACK_NUMBER, GST_TAG_FLAG_META,
153 _("track number inside a collection"), gst_tag_merge_use_first);
154 gst_tag_register (GST_TAG_TRACK_COUNT, GST_TAG_FLAG_META,
157 _("count of tracks inside collection this track belongs to"),
158 gst_tag_merge_use_first);
159 gst_tag_register (GST_TAG_ALBUM_VOLUME_NUMBER, GST_TAG_FLAG_META,
162 _("disc number inside a collection"), gst_tag_merge_use_first);
163 gst_tag_register (GST_TAG_ALBUM_VOLUME_COUNT, GST_TAG_FLAG_META,
166 _("count of discs inside collection this disc belongs to"),
167 gst_tag_merge_use_first);
168 gst_tag_register (GST_TAG_LOCATION, GST_TAG_FLAG_META,
170 _("location"), _("Origin of media as a URI (location, where the "
171 "original of the file or stream is hosted)"),
172 gst_tag_merge_strings_with_comma);
173 gst_tag_register (GST_TAG_HOMEPAGE, GST_TAG_FLAG_META,
176 _("Homepage for this media (i.e. artist or movie homepage)"),
177 gst_tag_merge_strings_with_comma);
178 gst_tag_register (GST_TAG_DESCRIPTION, GST_TAG_FLAG_META, G_TYPE_STRING,
179 _("description"), _("short text describing the content of the data"),
180 gst_tag_merge_strings_with_comma);
181 gst_tag_register (GST_TAG_VERSION, GST_TAG_FLAG_META, G_TYPE_STRING,
182 _("version"), _("version of this data"), NULL);
183 gst_tag_register (GST_TAG_ISRC, GST_TAG_FLAG_META, G_TYPE_STRING, _("ISRC"),
185 ("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
187 /* FIXME: organization (fix what? tpm) */
188 gst_tag_register (GST_TAG_ORGANIZATION, GST_TAG_FLAG_META, G_TYPE_STRING,
189 _("organization"), _("organization"), gst_tag_merge_strings_with_comma);
190 gst_tag_register (GST_TAG_COPYRIGHT, GST_TAG_FLAG_META,
191 G_TYPE_STRING, _("copyright"), _("copyright notice of the data"), NULL);
192 gst_tag_register (GST_TAG_COPYRIGHT_URI, GST_TAG_FLAG_META,
193 G_TYPE_STRING, _("copyright uri"),
194 _("URI to the copyright notice of the data"), NULL);
195 gst_tag_register (GST_TAG_ENCODED_BY, GST_TAG_FLAG_META, G_TYPE_STRING,
196 _("encoded by"), _("name of the encoding person or organization"),
197 gst_tag_merge_strings_with_comma);
198 gst_tag_register (GST_TAG_CONTACT, GST_TAG_FLAG_META,
200 _("contact"), _("contact information"), gst_tag_merge_strings_with_comma);
201 gst_tag_register (GST_TAG_LICENSE, GST_TAG_FLAG_META,
202 G_TYPE_STRING, _("license"), _("license of data"), NULL);
203 gst_tag_register (GST_TAG_LICENSE_URI, GST_TAG_FLAG_META,
204 G_TYPE_STRING, _("license uri"),
205 _("URI to the license of the data"), NULL);
206 gst_tag_register (GST_TAG_PERFORMER, GST_TAG_FLAG_META,
209 _("person(s) performing"), gst_tag_merge_strings_with_comma);
210 gst_tag_register (GST_TAG_COMPOSER, GST_TAG_FLAG_META,
213 _("person(s) who composed the recording"),
214 gst_tag_merge_strings_with_comma);
215 gst_tag_register (GST_TAG_DURATION, GST_TAG_FLAG_DECODED,
217 _("duration"), _("length in GStreamer time units (nanoseconds)"), NULL);
218 gst_tag_register (GST_TAG_CODEC, GST_TAG_FLAG_ENCODED,
221 _("codec the data is stored in"), gst_tag_merge_strings_with_comma);
222 gst_tag_register (GST_TAG_VIDEO_CODEC, GST_TAG_FLAG_ENCODED,
224 _("video codec"), _("codec the video data is stored in"), NULL);
225 gst_tag_register (GST_TAG_AUDIO_CODEC, GST_TAG_FLAG_ENCODED,
227 _("audio codec"), _("codec the audio data is stored in"), NULL);
228 gst_tag_register (GST_TAG_SUBTITLE_CODEC, GST_TAG_FLAG_ENCODED,
230 _("subtitle codec"), _("codec the subtitle data is stored in"), NULL);
231 gst_tag_register (GST_TAG_CONTAINER_FORMAT, GST_TAG_FLAG_ENCODED,
232 G_TYPE_STRING, _("container format"),
233 _("container format the data is stored in"), NULL);
234 gst_tag_register (GST_TAG_BITRATE, GST_TAG_FLAG_ENCODED,
235 G_TYPE_UINT, _("bitrate"), _("exact or average bitrate in bits/s"), NULL);
236 gst_tag_register (GST_TAG_NOMINAL_BITRATE, GST_TAG_FLAG_ENCODED,
237 G_TYPE_UINT, _("nominal bitrate"), _("nominal bitrate in bits/s"), NULL);
238 gst_tag_register (GST_TAG_MINIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
239 G_TYPE_UINT, _("minimum bitrate"), _("minimum bitrate in bits/s"), NULL);
240 gst_tag_register (GST_TAG_MAXIMUM_BITRATE, GST_TAG_FLAG_ENCODED,
241 G_TYPE_UINT, _("maximum bitrate"), _("maximum bitrate in bits/s"), NULL);
242 gst_tag_register (GST_TAG_ENCODER, GST_TAG_FLAG_ENCODED,
244 _("encoder"), _("encoder used to encode this stream"), NULL);
245 gst_tag_register (GST_TAG_ENCODER_VERSION, GST_TAG_FLAG_ENCODED,
247 _("encoder version"),
248 _("version of the encoder used to encode this stream"), NULL);
249 gst_tag_register (GST_TAG_SERIAL, GST_TAG_FLAG_ENCODED,
250 G_TYPE_UINT, _("serial"), _("serial number of track"), NULL);
251 gst_tag_register (GST_TAG_TRACK_GAIN, GST_TAG_FLAG_META,
252 G_TYPE_DOUBLE, _("replaygain track gain"), _("track gain in db"), NULL);
253 gst_tag_register (GST_TAG_TRACK_PEAK, GST_TAG_FLAG_META,
254 G_TYPE_DOUBLE, _("replaygain track peak"), _("peak of the track"), NULL);
255 gst_tag_register (GST_TAG_ALBUM_GAIN, GST_TAG_FLAG_META,
256 G_TYPE_DOUBLE, _("replaygain album gain"), _("album gain in db"), NULL);
257 gst_tag_register (GST_TAG_ALBUM_PEAK, GST_TAG_FLAG_META,
258 G_TYPE_DOUBLE, _("replaygain album peak"), _("peak of the album"), NULL);
259 gst_tag_register (GST_TAG_REFERENCE_LEVEL, GST_TAG_FLAG_META,
260 G_TYPE_DOUBLE, _("replaygain reference level"),
261 _("reference level of track and album gain values"), NULL);
262 gst_tag_register (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META, G_TYPE_STRING,
264 _("language code for this stream, conforming to ISO-639-1"), NULL);
265 gst_tag_register (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
266 _("image"), _("image related to this stream"), gst_tag_merge_use_first);
267 gst_tag_register (GST_TAG_PREVIEW_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
268 /* TRANSLATORS: 'preview image' = image that shows a preview of the full image */
269 _("preview image"), _("preview image related to this stream"), NULL);
270 gst_tag_register (GST_TAG_ATTACHMENT, GST_TAG_FLAG_META, GST_TYPE_BUFFER,
271 _("attachment"), _("file attached to this stream"),
272 gst_tag_merge_use_first);
273 gst_tag_register (GST_TAG_BEATS_PER_MINUTE, GST_TAG_FLAG_META, G_TYPE_DOUBLE,
274 _("beats per minute"), _("number of beats per minute in audio"), NULL);
275 gst_tag_register (GST_TAG_KEYWORDS, GST_TAG_FLAG_META, G_TYPE_STRING,
276 _("keywords"), _("comma separated keywords describing the content"),
277 gst_tag_merge_strings_with_comma);
278 gst_tag_register (GST_TAG_GEO_LOCATION_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
279 _("geo location name"), _("human readable descriptive location of where "
280 "the media has been recorded or produced"), NULL);
281 gst_tag_register (GST_TAG_GEO_LOCATION_LATITUDE, GST_TAG_FLAG_META,
282 G_TYPE_DOUBLE, _("geo location latitude"),
283 _("geo latitude location of where the media has been recorded or "
284 "produced in degrees according to WGS84 (zero at the equator, "
285 "negative values for southern latitudes)"), NULL);
286 gst_tag_register (GST_TAG_GEO_LOCATION_LONGITUDE, GST_TAG_FLAG_META,
287 G_TYPE_DOUBLE, _("geo location longitude"),
288 _("geo longitude location of where the media has been recorded or "
289 "produced in degrees according to WGS84 (zero at the prime meridian "
290 "in Greenwich/UK, negative values for western longitudes)"), NULL);
291 gst_tag_register (GST_TAG_GEO_LOCATION_ELEVATION, GST_TAG_FLAG_META,
292 G_TYPE_DOUBLE, _("geo location elevation"),
293 _("geo elevation of where the media has been recorded or produced in "
294 "meters according to WGS84 (zero is average sea level)"), NULL);
295 gst_tag_register (GST_TAG_GEO_LOCATION_COUNTRY, GST_TAG_FLAG_META,
296 G_TYPE_STRING, _("geo location country"),
297 _("country (english name) where the media has been recorded "
298 "or produced"), NULL);
299 gst_tag_register (GST_TAG_GEO_LOCATION_CITY, GST_TAG_FLAG_META,
300 G_TYPE_STRING, _("geo location city"),
301 _("city (english name) where the media has been recorded "
302 "or produced"), NULL);
303 gst_tag_register (GST_TAG_GEO_LOCATION_SUBLOCATION, GST_TAG_FLAG_META,
304 G_TYPE_STRING, _("geo location sublocation"),
305 _("a location whithin a city where the media has been produced "
306 "or created (e.g. the neighborhood)"), NULL);
307 gst_tag_register (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, GST_TAG_FLAG_META,
308 G_TYPE_DOUBLE, _("geo location horizontal error"),
309 _("expected error of the horizontal positioning measures (in meters)"),
311 gst_tag_register (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, GST_TAG_FLAG_META,
312 G_TYPE_DOUBLE, _("geo location movement speed"),
313 _("movement speed of the capturing device while performing the capture "
315 gst_tag_register (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, GST_TAG_FLAG_META,
316 G_TYPE_DOUBLE, _("geo location movement direction"),
317 _("indicates the movement direction of the device performing the capture"
318 " of a media. It is represented as degrees in floating point "
319 "representation, 0 means the geographic north, and increases "
321 gst_tag_register (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, GST_TAG_FLAG_META,
322 G_TYPE_DOUBLE, _("geo location capture direction"),
323 _("indicates the direction the device is pointing to when capturing "
324 " a media. It is represented as degrees in floating point "
325 " representation, 0 means the geographic north, and increases "
327 gst_tag_register (GST_TAG_SHOW_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
328 /* TRANSLATORS: 'show name' = 'TV/radio/podcast show name' here */
330 _("Name of the tv/podcast/series show the media is from"),
331 gst_tag_merge_strings_with_comma);
332 gst_tag_register (GST_TAG_SHOW_SORTNAME, GST_TAG_FLAG_META, G_TYPE_STRING,
333 /* TRANSLATORS: 'show sortname' = 'TV/radio/podcast show name as used for sorting purposes' here */
335 _("Name of the tv/podcast/series show the media is from, for sorting "
337 gst_tag_register (GST_TAG_SHOW_EPISODE_NUMBER, GST_TAG_FLAG_META, G_TYPE_UINT,
339 _("The episode number in the season the media is part of"),
340 gst_tag_merge_use_first);
341 gst_tag_register (GST_TAG_SHOW_SEASON_NUMBER, GST_TAG_FLAG_META, G_TYPE_UINT,
343 _("The season number of the show the media is part of"),
344 gst_tag_merge_use_first);
345 gst_tag_register (GST_TAG_LYRICS, GST_TAG_FLAG_META, G_TYPE_STRING,
346 _("lyrics"), _("The lyrics of the media, commonly used for songs"),
347 gst_tag_merge_strings_with_comma);
348 gst_tag_register (GST_TAG_COMPOSER_SORTNAME, GST_TAG_FLAG_META, G_TYPE_STRING,
349 _("composer sortname"),
350 _("person(s) who composed the recording, for sorting purposes"), NULL);
351 gst_tag_register (GST_TAG_GROUPING, GST_TAG_FLAG_META, G_TYPE_STRING,
353 _("Groups related media that spans multiple tracks, like the different "
354 "pieces of a concerto. It is a higher level than a track, "
355 "but lower than an album"), NULL);
356 gst_tag_register (GST_TAG_USER_RATING, GST_TAG_FLAG_META, G_TYPE_UINT,
358 _("Rating attributed by a user. The higher the rank, "
359 "the more the user likes this media"), NULL);
360 gst_tag_register (GST_TAG_DEVICE_MANUFACTURER, GST_TAG_FLAG_META,
361 G_TYPE_STRING, _("device manufacturer"),
362 _("Manufacturer of the device used to create this media"), NULL);
363 gst_tag_register (GST_TAG_DEVICE_MODEL, GST_TAG_FLAG_META, G_TYPE_STRING,
365 _("Model of the device used to create this media"), NULL);
366 gst_tag_register (GST_TAG_APPLICATION_NAME, GST_TAG_FLAG_META, G_TYPE_STRING,
367 _("application name"), _("Application used to create the media"), NULL);
368 gst_tag_register (GST_TAG_APPLICATION_DATA, GST_TAG_FLAG_META,
369 GST_TYPE_BUFFER, _("application data"),
370 _("Arbitrary application data to be serialized into the media"), NULL);
371 gst_tag_register (GST_TAG_IMAGE_ORIENTATION, GST_TAG_FLAG_META, G_TYPE_STRING,
372 _("image orientation"),
373 _("How the image should be rotated or flipped before display"), NULL);
377 * gst_tag_merge_use_first:
378 * @dest: (out caller-allocates): uninitialized GValue to store result in
379 * @src: GValue to copy from
381 * This is a convenience function for the func argument of gst_tag_register().
382 * It creates a copy of the first value from the list.
385 gst_tag_merge_use_first (GValue * dest, const GValue * src)
387 const GValue *ret = gst_value_list_get_value (src, 0);
389 g_value_init (dest, G_VALUE_TYPE (ret));
390 g_value_copy (ret, dest);
394 * gst_tag_merge_strings_with_comma:
395 * @dest: (out caller-allocates): uninitialized GValue to store result in
396 * @src: GValue to copy from
398 * This is a convenience function for the func argument of gst_tag_register().
399 * It concatenates all given strings using a comma. The tag must be registered
400 * as a G_TYPE_STRING or this function will fail.
403 gst_tag_merge_strings_with_comma (GValue * dest, const GValue * src)
408 count = gst_value_list_get_size (src);
409 str = g_string_new (g_value_get_string (gst_value_list_get_value (src, 0)));
410 for (i = 1; i < count; i++) {
411 /* separator between two strings */
412 g_string_append (str, _(", "));
413 g_string_append (str,
414 g_value_get_string (gst_value_list_get_value (src, i)));
417 g_value_init (dest, G_TYPE_STRING);
418 g_value_take_string (dest, str->str);
419 g_string_free (str, FALSE);
423 gst_tag_lookup (const gchar * tag_name)
428 ret = g_hash_table_lookup (__tags, (gpointer) tag_name);
436 * @name: the name or identifier string
437 * @flag: a flag describing the type of tag info
438 * @type: the type this data is in
439 * @nick: human-readable name
440 * @blurb: a human-readable description about this tag
441 * @func: function for merging multiple values of this tag, or NULL
443 * Registers a new tag type for the use with GStreamer's type system. If a type
444 * with that name is already registered, that one is used.
445 * The old registration may have used a different type however. So don't rely
446 * on your supplied values.
448 * Important: if you do not supply a merge function the implication will be
449 * that there can only be one single value for this tag in a tag list and
450 * any additional values will silenty be discarded when being added (unless
451 * #GST_TAG_MERGE_REPLACE, #GST_TAG_MERGE_REPLACE_ALL, or
452 * #GST_TAG_MERGE_PREPEND is used as merge mode, in which case the new
453 * value will replace the old one in the list).
455 * The merge function will be called from gst_tag_list_copy_value() when
456 * it is required that one or more values for a tag be condensed into
457 * one single value. This may happen from gst_tag_list_get_string(),
458 * gst_tag_list_get_int(), gst_tag_list_get_double() etc. What will happen
459 * exactly in that case depends on how the tag was registered and if a
460 * merge function was supplied and if so which one.
462 * Two default merge functions are provided: gst_tag_merge_use_first() and
463 * gst_tag_merge_strings_with_comma().
466 gst_tag_register (const gchar * name, GstTagFlag flag, GType type,
467 const gchar * nick, const gchar * blurb, GstTagMergeFunc func)
472 g_return_if_fail (name != NULL);
473 g_return_if_fail (nick != NULL);
474 g_return_if_fail (blurb != NULL);
475 g_return_if_fail (type != 0 && type != GST_TYPE_LIST);
477 info = gst_tag_lookup (name);
480 g_return_if_fail (info->type == type);
484 info = g_slice_new (GstTagInfo);
487 info->nick = g_strdup (nick);
488 info->blurb = g_strdup (blurb);
489 info->merge_func = func;
491 /* we make a copy for the hash table anyway, which will stay around, so
492 * can use that for the quark table too */
493 name_dup = g_strdup (name);
494 info->name_quark = g_quark_from_static_string (name_dup);
497 g_hash_table_insert (__tags, (gpointer) name_dup, info);
503 * @tag: name of the tag
505 * Checks if the given type is already registered.
507 * Returns: TRUE if the type is already registered
510 gst_tag_exists (const gchar * tag)
512 g_return_val_if_fail (tag != NULL, FALSE);
514 return gst_tag_lookup (tag) != NULL;
521 * Gets the #GType used for this tag.
523 * Returns: the #GType of this tag
526 gst_tag_get_type (const gchar * tag)
530 g_return_val_if_fail (tag != NULL, 0);
531 info = gst_tag_lookup (tag);
532 g_return_val_if_fail (info != NULL, 0);
541 * Returns the human-readable name of this tag, You must not change or free
544 * Returns: the human-readable name of this tag
547 gst_tag_get_nick (const gchar * tag)
551 g_return_val_if_fail (tag != NULL, NULL);
552 info = gst_tag_lookup (tag);
553 g_return_val_if_fail (info != NULL, NULL);
559 * gst_tag_get_description:
562 * Returns the human-readable description of this tag, You must not change or
565 * Returns: the human-readable description of this tag
568 gst_tag_get_description (const gchar * tag)
572 g_return_val_if_fail (tag != NULL, NULL);
573 info = gst_tag_lookup (tag);
574 g_return_val_if_fail (info != NULL, NULL);
583 * Gets the flag of @tag.
585 * Returns: the flag of this tag.
588 gst_tag_get_flag (const gchar * tag)
592 g_return_val_if_fail (tag != NULL, GST_TAG_FLAG_UNDEFINED);
593 info = gst_tag_lookup (tag);
594 g_return_val_if_fail (info != NULL, GST_TAG_FLAG_UNDEFINED);
603 * Checks if the given tag is fixed. A fixed tag can only contain one value.
604 * Unfixed tags can contain lists of values.
606 * Returns: TRUE, if the given tag is fixed.
609 gst_tag_is_fixed (const gchar * tag)
613 g_return_val_if_fail (tag != NULL, FALSE);
614 info = gst_tag_lookup (tag);
615 g_return_val_if_fail (info != NULL, FALSE);
617 return info->merge_func == NULL;
623 * Creates a new empty GstTagList.
625 * Free-function: gst_tag_list_free
627 * Returns: (transfer full): An empty tag list
630 gst_tag_list_new (void)
632 return GST_TAG_LIST (gst_structure_id_empty_new (GST_QUARK (TAGLIST)));
636 * gst_tag_list_new_full:
638 * @...: NULL-terminated list of values to set
640 * Creates a new taglist and appends the values for the given tags. It expects
641 * tag-value pairs like gst_tag_list_add(), and a NULL terminator after the
642 * last pair. The type of the values is implicit and is documented in the API
643 * reference, but can also be queried at runtime with gst_tag_get_type(). It
644 * is an error to pass a value of a type not matching the tag type into this
645 * function. The tag list will make copies of any arguments passed
646 * (e.g. strings, buffers).
648 * Free-function: gst_tag_list_free
650 * Returns: (transfer full): a new #GstTagList. Free with gst_tag_list_free()
651 * when no longer needed.
655 /* FIXME 0.11: rename gst_tag_list_new_full to _new and _new to _new_empty */
657 gst_tag_list_new_full (const gchar * tag, ...)
662 g_return_val_if_fail (tag != NULL, NULL);
664 list = gst_tag_list_new ();
665 va_start (args, tag);
666 gst_tag_list_add_valist (list, GST_TAG_MERGE_APPEND, tag, args);
673 * gst_tag_list_new_full_valist:
674 * @var_args: tag / value pairs to set
676 * Just like gst_tag_list_new_full(), only that it takes a va_list argument.
677 * Useful mostly for language bindings.
679 * Free-function: gst_tag_list_free
681 * Returns: (transfer full): a new #GstTagList. Free with gst_tag_list_free()
682 * when no longer needed.
687 gst_tag_list_new_full_valist (va_list var_args)
692 list = gst_tag_list_new ();
694 tag = va_arg (var_args, gchar *);
695 gst_tag_list_add_valist (list, GST_TAG_MERGE_APPEND, tag, var_args);
701 * gst_tag_list_is_empty:
702 * @list: A #GstTagList.
704 * Checks if the given taglist is empty.
706 * Returns: TRUE if the taglist is empty, otherwise FALSE.
711 gst_tag_list_is_empty (const GstTagList * list)
713 g_return_val_if_fail (list != NULL, FALSE);
714 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
716 return (gst_structure_n_fields ((GstStructure *) list) == 0);
720 gst_tag_list_fields_equal (const GValue * value1, const GValue * value2)
724 if (gst_value_compare (value1, value2) == GST_VALUE_EQUAL)
727 /* fields not equal: add some tolerance for doubles, otherwise bail out */
728 if (!G_VALUE_HOLDS_DOUBLE (value1) || !G_VALUE_HOLDS_DOUBLE (value2))
731 d1 = g_value_get_double (value1);
732 d2 = g_value_get_double (value2);
734 /* This will only work for 'normal' values and values around 0,
735 * which should be good enough for our purposes here
736 * FIXME: maybe add this to gst_value_compare_double() ? */
737 return (fabs (d1 - d2) < 0.0000001);
741 * gst_tag_list_is_equal:
742 * @list1: a #GstTagList.
743 * @list2: a #GstTagList.
745 * Checks if the two given taglists are equal.
747 * Returns: TRUE if the taglists are equal, otherwise FALSE
752 gst_tag_list_is_equal (const GstTagList * list1, const GstTagList * list2)
754 const GstStructure *s1, *s2;
755 gint num_fields1, num_fields2, i;
757 g_return_val_if_fail (GST_IS_TAG_LIST (list1), FALSE);
758 g_return_val_if_fail (GST_IS_TAG_LIST (list2), FALSE);
760 /* we don't just use gst_structure_is_equal() here so we can add some
761 * tolerance for doubles, though maybe we should just add that to
762 * gst_value_compare_double() as well? */
763 s1 = (const GstStructure *) list1;
764 s2 = (const GstStructure *) list2;
766 num_fields1 = gst_structure_n_fields (s1);
767 num_fields2 = gst_structure_n_fields (s2);
769 if (num_fields1 != num_fields2)
772 for (i = 0; i < num_fields1; i++) {
773 const GValue *value1, *value2;
774 const gchar *tag_name;
776 tag_name = gst_structure_nth_field_name (s1, i);
777 value1 = gst_structure_get_value (s1, tag_name);
778 value2 = gst_structure_get_value (s2, tag_name);
783 if (!gst_tag_list_fields_equal (value1, value2))
792 * @p: Object that might be a taglist
794 * Checks if the given pointer is a taglist.
796 * Returns: TRUE, if the given pointer is a taglist
799 gst_is_tag_list (gconstpointer p)
801 GstStructure *s = (GstStructure *) p;
803 g_return_val_if_fail (p != NULL, FALSE);
805 return (GST_IS_STRUCTURE (s) && s->name == GST_QUARK (TAGLIST));
811 GstTagMergeMode mode;
816 gst_tag_list_add_value_internal (GstStructure * list, GstTagMergeMode mode,
817 const gchar * tag, const GValue * value, GstTagInfo * info)
819 const GValue *value2;
823 info = gst_tag_lookup (tag);
824 if (G_UNLIKELY (info == NULL)) {
825 g_warning ("unknown tag '%s'", tag);
830 tag_quark = info->name_quark;
833 && (value2 = gst_structure_id_get_value (list, tag_quark)) != NULL) {
834 GValue dest = { 0, };
837 case GST_TAG_MERGE_REPLACE_ALL:
838 case GST_TAG_MERGE_REPLACE:
839 gst_structure_id_set_value (list, tag_quark, value);
841 case GST_TAG_MERGE_PREPEND:
842 gst_value_list_merge (&dest, value, value2);
843 gst_structure_id_set_value (list, tag_quark, &dest);
844 g_value_unset (&dest);
846 case GST_TAG_MERGE_APPEND:
847 gst_value_list_merge (&dest, value2, value);
848 gst_structure_id_set_value (list, tag_quark, &dest);
849 g_value_unset (&dest);
851 case GST_TAG_MERGE_KEEP:
852 case GST_TAG_MERGE_KEEP_ALL:
855 g_assert_not_reached ();
860 case GST_TAG_MERGE_APPEND:
861 case GST_TAG_MERGE_KEEP:
862 if (gst_structure_id_get_value (list, tag_quark) != NULL)
865 case GST_TAG_MERGE_REPLACE_ALL:
866 case GST_TAG_MERGE_REPLACE:
867 case GST_TAG_MERGE_PREPEND:
868 gst_structure_id_set_value (list, tag_quark, value);
870 case GST_TAG_MERGE_KEEP_ALL:
873 g_assert_not_reached ();
880 gst_tag_list_copy_foreach (GQuark tag_quark, const GValue * value,
883 GstTagCopyData *copy = (GstTagCopyData *) user_data;
886 tag = g_quark_to_string (tag_quark);
887 gst_tag_list_add_value_internal (copy->list, copy->mode, tag, value, NULL);
893 * gst_tag_list_insert:
894 * @into: list to merge into
895 * @from: list to merge from
896 * @mode: the mode to use
898 * Inserts the tags of the @from list into the first list using the given mode.
901 gst_tag_list_insert (GstTagList * into, const GstTagList * from,
902 GstTagMergeMode mode)
906 g_return_if_fail (GST_IS_TAG_LIST (into));
907 g_return_if_fail (GST_IS_TAG_LIST (from));
908 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
910 data.list = (GstStructure *) into;
912 if (mode == GST_TAG_MERGE_REPLACE_ALL) {
913 gst_structure_remove_all_fields (data.list);
915 gst_structure_foreach ((GstStructure *) from, gst_tag_list_copy_foreach,
921 * @list: list to copy
923 * Copies a given #GstTagList.
925 * Free-function: gst_tag_list_free
927 * Returns: (transfer full): copy of the given list
930 gst_tag_list_copy (const GstTagList * list)
932 g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
934 return GST_TAG_LIST (gst_structure_copy ((GstStructure *) list));
938 * gst_tag_list_merge:
939 * @list1: first list to merge
940 * @list2: second list to merge
941 * @mode: the mode to use
943 * Merges the two given lists into a new list. If one of the lists is NULL, a
944 * copy of the other is returned. If both lists are NULL, NULL is returned.
946 * Free-function: gst_tag_list_free
948 * Returns: (transfer full): the new list
951 gst_tag_list_merge (const GstTagList * list1, const GstTagList * list2,
952 GstTagMergeMode mode)
954 GstTagList *list1_cp;
955 const GstTagList *list2_cp;
957 g_return_val_if_fail (list1 == NULL || GST_IS_TAG_LIST (list1), NULL);
958 g_return_val_if_fail (list2 == NULL || GST_IS_TAG_LIST (list2), NULL);
959 g_return_val_if_fail (GST_TAG_MODE_IS_VALID (mode), NULL);
961 /* nothing to merge */
962 if (!list1 && !list2) {
966 /* create empty list, we need to do this to correctly handling merge modes */
967 list1_cp = (list1) ? gst_tag_list_copy (list1) : gst_tag_list_new ();
968 list2_cp = (list2) ? list2 : gst_tag_list_new ();
970 gst_tag_list_insert (list1_cp, list2_cp, mode);
973 gst_tag_list_free ((GstTagList *) list2_cp);
980 * @list: (in) (transfer full): the list to free
982 * Frees the given list and all associated values.
985 gst_tag_list_free (GstTagList * list)
987 g_return_if_fail (GST_IS_TAG_LIST (list));
988 gst_structure_free ((GstStructure *) list);
992 * gst_tag_list_get_tag_size:
994 * @tag: the tag to query
996 * Checks how many value are stored in this tag list for the given tag.
998 * Returns: The number of tags stored
1001 gst_tag_list_get_tag_size (const GstTagList * list, const gchar * tag)
1003 const GValue *value;
1005 g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
1007 value = gst_structure_get_value ((GstStructure *) list, tag);
1010 if (G_VALUE_TYPE (value) != GST_TYPE_LIST)
1013 return gst_value_list_get_size (value);
1018 * @list: list to set tags in
1019 * @mode: the mode to use
1021 * @...: NULL-terminated list of values to set
1023 * Sets the values for the given tags using the specified mode.
1026 gst_tag_list_add (GstTagList * list, GstTagMergeMode mode, const gchar * tag,
1031 g_return_if_fail (GST_IS_TAG_LIST (list));
1032 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
1033 g_return_if_fail (tag != NULL);
1035 va_start (args, tag);
1036 gst_tag_list_add_valist (list, mode, tag, args);
1041 * gst_tag_list_add_values:
1042 * @list: list to set tags in
1043 * @mode: the mode to use
1045 * @...: GValues to set
1047 * Sets the GValues for the given tags using the specified mode.
1050 gst_tag_list_add_values (GstTagList * list, GstTagMergeMode mode,
1051 const gchar * tag, ...)
1055 g_return_if_fail (GST_IS_TAG_LIST (list));
1056 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
1057 g_return_if_fail (tag != NULL);
1059 va_start (args, tag);
1060 gst_tag_list_add_valist_values (list, mode, tag, args);
1065 * gst_tag_list_add_valist:
1066 * @list: list to set tags in
1067 * @mode: the mode to use
1069 * @var_args: tag / value pairs to set
1071 * Sets the values for the given tags using the specified mode.
1074 gst_tag_list_add_valist (GstTagList * list, GstTagMergeMode mode,
1075 const gchar * tag, va_list var_args)
1078 gchar *error = NULL;
1080 g_return_if_fail (GST_IS_TAG_LIST (list));
1081 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
1082 g_return_if_fail (tag != NULL);
1084 if (mode == GST_TAG_MERGE_REPLACE_ALL) {
1085 gst_structure_remove_all_fields (list);
1088 while (tag != NULL) {
1089 GValue value = { 0, };
1091 info = gst_tag_lookup (tag);
1092 if (G_UNLIKELY (info == NULL)) {
1093 g_warning ("unknown tag '%s'", tag);
1096 G_VALUE_COLLECT_INIT (&value, info->type, var_args, 0, &error);
1098 g_warning ("%s: %s", G_STRLOC, error);
1100 /* we purposely leak the value here, it might not be
1101 * in a sane state if an error condition occoured
1105 gst_tag_list_add_value_internal (list, mode, tag, &value, info);
1106 g_value_unset (&value);
1107 tag = va_arg (var_args, gchar *);
1112 * gst_tag_list_add_valist_values:
1113 * @list: list to set tags in
1114 * @mode: the mode to use
1116 * @var_args: tag / GValue pairs to set
1118 * Sets the GValues for the given tags using the specified mode.
1121 gst_tag_list_add_valist_values (GstTagList * list, GstTagMergeMode mode,
1122 const gchar * tag, va_list var_args)
1124 g_return_if_fail (GST_IS_TAG_LIST (list));
1125 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
1126 g_return_if_fail (tag != NULL);
1128 if (mode == GST_TAG_MERGE_REPLACE_ALL) {
1129 gst_structure_remove_all_fields (list);
1132 while (tag != NULL) {
1135 info = gst_tag_lookup (tag);
1136 if (G_UNLIKELY (info == NULL)) {
1137 g_warning ("unknown tag '%s'", tag);
1140 gst_tag_list_add_value_internal (list, mode, tag, va_arg (var_args,
1142 tag = va_arg (var_args, gchar *);
1147 * gst_tag_list_add_value:
1148 * @list: list to set tags in
1149 * @mode: the mode to use
1151 * @value: GValue for this tag
1153 * Sets the GValue for a given tag using the specified mode.
1158 gst_tag_list_add_value (GstTagList * list, GstTagMergeMode mode,
1159 const gchar * tag, const GValue * value)
1161 g_return_if_fail (GST_IS_TAG_LIST (list));
1162 g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
1163 g_return_if_fail (tag != NULL);
1165 gst_tag_list_add_value_internal (list, mode, tag, value, NULL);
1169 * gst_tag_list_remove_tag:
1170 * @list: list to remove tag from
1171 * @tag: tag to remove
1173 * Removes the given tag from the taglist.
1176 gst_tag_list_remove_tag (GstTagList * list, const gchar * tag)
1178 g_return_if_fail (GST_IS_TAG_LIST (list));
1179 g_return_if_fail (tag != NULL);
1181 gst_structure_remove_field ((GstStructure *) list, tag);
1186 GstTagForeachFunc func;
1187 const GstTagList *tag_list;
1193 structure_foreach_wrapper (GQuark field_id, const GValue * value,
1196 TagForeachData *data = (TagForeachData *) user_data;
1198 data->func (data->tag_list, g_quark_to_string (field_id), data->data);
1203 * gst_tag_list_foreach:
1204 * @list: list to iterate over
1205 * @func: (scope call): function to be called for each tag
1206 * @user_data: (closure): user specified data
1208 * Calls the given function for each tag inside the tag list. Note that if there
1209 * is no tag, the function won't be called at all.
1212 gst_tag_list_foreach (const GstTagList * list, GstTagForeachFunc func,
1215 TagForeachData data;
1217 g_return_if_fail (GST_IS_TAG_LIST (list));
1218 g_return_if_fail (func != NULL);
1221 data.tag_list = list;
1222 data.data = user_data;
1223 gst_structure_foreach ((GstStructure *) list, structure_foreach_wrapper,
1228 * gst_tag_list_get_value_index:
1229 * @list: a #GstTagList
1230 * @tag: tag to read out
1231 * @index: number of entry to read out
1233 * Gets the value that is at the given index for the given tag in the given
1236 * Returns: (transfer none): The GValue for the specified entry or NULL if the
1237 * tag wasn't available or the tag doesn't have as many entries
1240 gst_tag_list_get_value_index (const GstTagList * list, const gchar * tag,
1243 const GValue *value;
1245 g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
1246 g_return_val_if_fail (tag != NULL, NULL);
1248 value = gst_structure_get_value ((GstStructure *) list, tag);
1252 if (GST_VALUE_HOLDS_LIST (value)) {
1253 if (index >= gst_value_list_get_size (value))
1255 return gst_value_list_get_value (value, index);
1264 * gst_tag_list_copy_value:
1265 * @dest: (out caller-allocates): uninitialized #GValue to copy into
1266 * @list: list to get the tag from
1267 * @tag: tag to read out
1269 * Copies the contents for the given tag into the value,
1270 * merging multiple values into one if multiple values are associated
1272 * You must g_value_unset() the value after use.
1274 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1278 gst_tag_list_copy_value (GValue * dest, const GstTagList * list,
1283 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1284 g_return_val_if_fail (tag != NULL, FALSE);
1285 g_return_val_if_fail (dest != NULL, FALSE);
1286 g_return_val_if_fail (G_VALUE_TYPE (dest) == 0, FALSE);
1288 src = gst_structure_get_value ((GstStructure *) list, tag);
1292 if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
1293 GstTagInfo *info = gst_tag_lookup (tag);
1298 /* must be there or lists aren't allowed */
1299 g_assert (info->merge_func);
1300 info->merge_func (dest, src);
1302 g_value_init (dest, G_VALUE_TYPE (src));
1303 g_value_copy (src, dest);
1308 /* FIXME 0.11: this whole merge function business is overdesigned, and the
1309 * _get_foo() API is misleading as well - how many application developers will
1310 * expect gst_tag_list_get_string (list, GST_TAG_ARTIST, &val) might return a
1311 * string with multiple comma-separated artists? _get_foo() should just be
1312 * a convenience wrapper around _get_foo_index (list, tag, 0, &val),
1313 * supplemented by a special _tag_list_get_string_merged() function if needed
1314 * (unless someone can actually think of real use cases where the merge
1315 * function is not 'use first' for non-strings and merge for strings) */
1317 /***** evil macros to get all the gst_tag_list_get_*() functions right *****/
1319 #define TAG_MERGE_FUNCS(name,type,ret) \
1321 gst_tag_list_get_ ## name (const GstTagList *list, const gchar *tag, \
1324 GValue v = { 0, }; \
1326 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
1327 g_return_val_if_fail (tag != NULL, FALSE); \
1328 g_return_val_if_fail (value != NULL, FALSE); \
1330 if (!gst_tag_list_copy_value (&v, list, tag)) \
1332 *value = COPY_FUNC (g_value_get_ ## name (&v)); \
1333 g_value_unset (&v); \
1338 gst_tag_list_get_ ## name ## _index (const GstTagList *list, \
1340 guint index, type *value) \
1344 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
1345 g_return_val_if_fail (tag != NULL, FALSE); \
1346 g_return_val_if_fail (value != NULL, FALSE); \
1348 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL) \
1350 *value = COPY_FUNC (g_value_get_ ## name (v)); \
1354 /* FIXME 0.11: maybe get rid of _get_char*(), _get_uchar*(), _get_long*(),
1355 * _get_ulong*() and _get_pointer*()? - they are not really useful/common
1356 * enough to warrant convenience accessor functions */
1358 #define COPY_FUNC /**/
1360 * gst_tag_list_get_char:
1361 * @list: a #GstTagList to get the tag from
1362 * @tag: tag to read out
1363 * @value: (out): location for the result
1365 * Copies the contents for the given tag into the value, merging multiple values
1366 * into one if multiple values are associated with the tag.
1368 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1372 * gst_tag_list_get_char_index:
1373 * @list: a #GstTagList to get the tag from
1374 * @tag: tag to read out
1375 * @index: number of entry to read out
1376 * @value: (out): location for the result
1378 * Gets the value that is at the given index for the given tag in the given
1381 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1384 TAG_MERGE_FUNCS (char, gchar, TRUE);
1386 * gst_tag_list_get_uchar:
1387 * @list: a #GstTagList to get the tag from
1388 * @tag: tag to read out
1389 * @value: (out): location for the result
1391 * Copies the contents for the given tag into the value, merging multiple values
1392 * into one if multiple values are associated with the tag.
1394 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1398 * gst_tag_list_get_uchar_index:
1399 * @list: a #GstTagList to get the tag from
1400 * @tag: tag to read out
1401 * @index: number of entry to read out
1402 * @value: (out): location for the result
1404 * Gets the value that is at the given index for the given tag in the given
1407 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1410 TAG_MERGE_FUNCS (uchar, guchar, TRUE);
1412 * gst_tag_list_get_boolean:
1413 * @list: a #GstTagList to get the tag from
1414 * @tag: tag to read out
1415 * @value: (out): location for the result
1417 * Copies the contents for the given tag into the value, merging multiple values
1418 * into one if multiple values are associated with the tag.
1420 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1424 * gst_tag_list_get_boolean_index:
1425 * @list: a #GstTagList to get the tag from
1426 * @tag: tag to read out
1427 * @index: number of entry to read out
1428 * @value: (out): location for the result
1430 * Gets the value that is at the given index for the given tag in the given
1433 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1436 TAG_MERGE_FUNCS (boolean, gboolean, TRUE);
1438 * gst_tag_list_get_int:
1439 * @list: a #GstTagList to get the tag from
1440 * @tag: tag to read out
1441 * @value: (out): location for the result
1443 * Copies the contents for the given tag into the value, merging multiple values
1444 * into one if multiple values are associated with the tag.
1446 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1450 * gst_tag_list_get_int_index:
1451 * @list: a #GstTagList to get the tag from
1452 * @tag: tag to read out
1453 * @index: number of entry to read out
1454 * @value: (out): location for the result
1456 * Gets the value that is at the given index for the given tag in the given
1459 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1462 TAG_MERGE_FUNCS (int, gint, TRUE);
1464 * gst_tag_list_get_uint:
1465 * @list: a #GstTagList to get the tag from
1466 * @tag: tag to read out
1467 * @value: (out): location for the result
1469 * Copies the contents for the given tag into the value, merging multiple values
1470 * into one if multiple values are associated with the tag.
1472 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1476 * gst_tag_list_get_uint_index:
1477 * @list: a #GstTagList to get the tag from
1478 * @tag: tag to read out
1479 * @index: number of entry to read out
1480 * @value: (out): location for the result
1482 * Gets the value that is at the given index for the given tag in the given
1485 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1488 TAG_MERGE_FUNCS (uint, guint, TRUE);
1490 * gst_tag_list_get_long:
1491 * @list: a #GstTagList to get the tag from
1492 * @tag: tag to read out
1493 * @value: (out): location for the result
1495 * Copies the contents for the given tag into the value, merging multiple values
1496 * into one if multiple values are associated with the tag.
1498 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1502 * gst_tag_list_get_long_index:
1503 * @list: a #GstTagList to get the tag from
1504 * @tag: tag to read out
1505 * @index: number of entry to read out
1506 * @value: (out): location for the result
1508 * Gets the value that is at the given index for the given tag in the given
1511 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1514 TAG_MERGE_FUNCS (long, glong, TRUE);
1516 * gst_tag_list_get_ulong:
1517 * @list: a #GstTagList to get the tag from
1518 * @tag: tag to read out
1519 * @value: (out): location for the result
1521 * Copies the contents for the given tag into the value, merging multiple values
1522 * into one if multiple values are associated with the tag.
1524 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1528 * gst_tag_list_get_ulong_index:
1529 * @list: a #GstTagList to get the tag from
1530 * @tag: tag to read out
1531 * @index: number of entry to read out
1532 * @value: (out): location for the result
1534 * Gets the value that is at the given index for the given tag in the given
1537 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1540 TAG_MERGE_FUNCS (ulong, gulong, TRUE);
1542 * gst_tag_list_get_int64:
1543 * @list: a #GstTagList to get the tag from
1544 * @tag: tag to read out
1545 * @value: (out): location for the result
1547 * Copies the contents for the given tag into the value, merging multiple values
1548 * into one if multiple values are associated with the tag.
1550 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1554 * gst_tag_list_get_int64_index:
1555 * @list: a #GstTagList to get the tag from
1556 * @tag: tag to read out
1557 * @index: number of entry to read out
1558 * @value: (out): location for the result
1560 * Gets the value that is at the given index for the given tag in the given
1563 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1566 TAG_MERGE_FUNCS (int64, gint64, TRUE);
1568 * gst_tag_list_get_uint64:
1569 * @list: a #GstTagList to get the tag from
1570 * @tag: tag to read out
1571 * @value: (out): location for the result
1573 * Copies the contents for the given tag into the value, merging multiple values
1574 * into one if multiple values are associated with the tag.
1576 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1580 * gst_tag_list_get_uint64_index:
1581 * @list: a #GstTagList to get the tag from
1582 * @tag: tag to read out
1583 * @index: number of entry to read out
1584 * @value: (out): location for the result
1586 * Gets the value that is at the given index for the given tag in the given
1589 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1592 TAG_MERGE_FUNCS (uint64, guint64, TRUE);
1594 * gst_tag_list_get_float:
1595 * @list: a #GstTagList to get the tag from
1596 * @tag: tag to read out
1597 * @value: (out): location for the result
1599 * Copies the contents for the given tag into the value, merging multiple values
1600 * into one if multiple values are associated with the tag.
1602 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1606 * gst_tag_list_get_float_index:
1607 * @list: a #GstTagList to get the tag from
1608 * @tag: tag to read out
1609 * @index: number of entry to read out
1610 * @value: (out): location for the result
1612 * Gets the value that is at the given index for the given tag in the given
1615 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1618 TAG_MERGE_FUNCS (float, gfloat, TRUE);
1620 * gst_tag_list_get_double:
1621 * @list: a #GstTagList to get the tag from
1622 * @tag: tag to read out
1623 * @value: (out): location for the result
1625 * Copies the contents for the given tag into the value, merging multiple values
1626 * into one if multiple values are associated with the tag.
1628 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1632 * gst_tag_list_get_double_index:
1633 * @list: a #GstTagList to get the tag from
1634 * @tag: tag to read out
1635 * @index: number of entry to read out
1636 * @value: (out): location for the result
1638 * Gets the value that is at the given index for the given tag in the given
1641 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1644 TAG_MERGE_FUNCS (double, gdouble, TRUE);
1646 * gst_tag_list_get_pointer:
1647 * @list: a #GstTagList to get the tag from
1648 * @tag: tag to read out
1649 * @value: (out) (transfer none): location for the result
1651 * Copies the contents for the given tag into the value, merging multiple values
1652 * into one if multiple values are associated with the tag.
1654 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1658 * gst_tag_list_get_pointer_index:
1659 * @list: a #GstTagList to get the tag from
1660 * @tag: tag to read out
1661 * @index: number of entry to read out
1662 * @value: (out) (transfer none): location for the result
1664 * Gets the value that is at the given index for the given tag in the given
1667 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1670 TAG_MERGE_FUNCS (pointer, gpointer, (*value != NULL));
1672 static inline gchar *
1673 _gst_strdup0 (const gchar * s)
1675 if (s == NULL || *s == '\0')
1678 return g_strdup (s);
1682 #define COPY_FUNC _gst_strdup0
1685 * gst_tag_list_get_string:
1686 * @list: a #GstTagList to get the tag from
1687 * @tag: tag to read out
1688 * @value: (out callee-allocates) (transfer full): location for the result
1690 * Copies the contents for the given tag into the value, possibly merging
1691 * multiple values into one if multiple values are associated with the tag.
1693 * Use gst_tag_list_get_string_index (list, tag, 0, value) if you want
1694 * to retrieve the first string associated with this tag unmodified.
1696 * The resulting string in @value will be in UTF-8 encoding and should be
1697 * freed by the caller using g_free when no longer needed. Since 0.10.24 the
1698 * returned string is also guaranteed to be non-NULL and non-empty.
1700 * Free-function: g_free
1702 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1706 * gst_tag_list_get_string_index:
1707 * @list: a #GstTagList to get the tag from
1708 * @tag: tag to read out
1709 * @index: number of entry to read out
1710 * @value: (out callee-allocates) (transfer full): location for the result
1712 * Gets the value that is at the given index for the given tag in the given
1715 * The resulting string in @value will be in UTF-8 encoding and should be
1716 * freed by the caller using g_free when no longer needed. Since 0.10.24 the
1717 * returned string is also guaranteed to be non-NULL and non-empty.
1719 * Free-function: g_free
1721 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1724 TAG_MERGE_FUNCS (string, gchar *, (*value != NULL));
1727 *FIXME 0.11: Instead of _peek (non-copy) and _get (copy), we could have
1728 * _get (non-copy) and _dup (copy) for strings, seems more
1732 * gst_tag_list_peek_string_index:
1733 * @list: a #GstTagList to get the tag from
1734 * @tag: tag to read out
1735 * @index: number of entry to read out
1736 * @value: (out) (transfer none): location for the result
1738 * Peeks at the value that is at the given index for the given tag in the given
1741 * The resulting string in @value will be in UTF-8 encoding and doesn't need
1742 * to be freed by the caller. The returned string is also guaranteed to
1743 * be non-NULL and non-empty.
1745 * Returns: TRUE, if a value was set, FALSE if the tag didn't exist in the
1749 gst_tag_list_peek_string_index (const GstTagList * list,
1750 const gchar * tag, guint index, const gchar ** value)
1754 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1755 g_return_val_if_fail (tag != NULL, FALSE);
1756 g_return_val_if_fail (value != NULL, FALSE);
1758 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
1760 *value = g_value_get_string (v);
1761 return *value != NULL && **value != '\0';
1765 * gst_tag_list_get_date:
1766 * @list: a #GstTagList to get the tag from
1767 * @tag: tag to read out
1768 * @value: (out callee-allocates) (transfer full): address of a GDate pointer
1769 * variable to store the result into
1771 * Copies the first date for the given tag in the taglist into the variable
1772 * pointed to by @value. Free the date with g_date_free() when it is no longer
1775 * Free-function: g_date_free
1777 * Returns: TRUE, if a date was copied, FALSE if the tag didn't exist in the
1778 * given list or if it was #NULL.
1781 gst_tag_list_get_date (const GstTagList * list, const gchar * tag,
1786 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1787 g_return_val_if_fail (tag != NULL, FALSE);
1788 g_return_val_if_fail (value != NULL, FALSE);
1790 if (!gst_tag_list_copy_value (&v, list, tag))
1792 *value = (GDate *) g_value_dup_boxed (&v);
1794 return (*value != NULL);
1798 * gst_tag_list_get_date_index:
1799 * @list: a #GstTagList to get the tag from
1800 * @tag: tag to read out
1801 * @index: number of entry to read out
1802 * @value: (out callee-allocates) (transfer full): location for the result
1804 * Gets the date that is at the given index for the given tag in the given
1805 * list and copies it into the variable pointed to by @value. Free the date
1806 * with g_date_free() when it is no longer needed.
1808 * Free-function: g_date_free
1810 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1811 * given list or if it was #NULL.
1814 gst_tag_list_get_date_index (const GstTagList * list,
1815 const gchar * tag, guint index, GDate ** value)
1819 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1820 g_return_val_if_fail (tag != NULL, FALSE);
1821 g_return_val_if_fail (value != NULL, FALSE);
1823 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
1825 *value = (GDate *) g_value_dup_boxed (v);
1826 return (*value != NULL);
1830 * gst_tag_list_get_date_time:
1831 * @list: a #GstTagList to get the tag from
1832 * @tag: tag to read out
1833 * @value: (out callee-allocates) (transfer full): address of a #GstDateTime
1834 * pointer variable to store the result into
1836 * Copies the first datetime for the given tag in the taglist into the variable
1837 * pointed to by @value. Unref the date with gst_date_time_unref() when
1838 * it is no longer needed.
1840 * Free-function: gst_date_time_unref
1842 * Returns: TRUE, if a datetime was copied, FALSE if the tag didn't exist in
1843 * thegiven list or if it was #NULL.
1848 gst_tag_list_get_date_time (const GstTagList * list, const gchar * tag,
1849 GstDateTime ** value)
1853 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1854 g_return_val_if_fail (tag != NULL, FALSE);
1855 g_return_val_if_fail (value != NULL, FALSE);
1857 if (!gst_tag_list_copy_value (&v, list, tag))
1860 g_return_val_if_fail (GST_VALUE_HOLDS_DATE_TIME (&v), FALSE);
1862 *value = (GstDateTime *) g_value_dup_boxed (&v);
1864 return (*value != NULL);
1868 * gst_tag_list_get_date_time_index:
1869 * @list: a #GstTagList to get the tag from
1870 * @tag: tag to read out
1871 * @index: number of entry to read out
1872 * @value: (out callee-allocates) (transfer full): location for the result
1874 * Gets the datetime that is at the given index for the given tag in the given
1875 * list and copies it into the variable pointed to by @value. Unref the datetime
1876 * with gst_date_time_unref() when it is no longer needed.
1878 * Free-function: gst_date_time_unref
1880 * Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
1881 * given list or if it was #NULL.
1886 gst_tag_list_get_date_time_index (const GstTagList * list,
1887 const gchar * tag, guint index, GstDateTime ** value)
1891 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1892 g_return_val_if_fail (tag != NULL, FALSE);
1893 g_return_val_if_fail (value != NULL, FALSE);
1895 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
1897 *value = (GstDateTime *) g_value_dup_boxed (v);
1898 return (*value != NULL);
1902 * gst_tag_list_get_buffer:
1903 * @list: a #GstTagList to get the tag from
1904 * @tag: tag to read out
1905 * @value: (out callee-allocates) (transfer full): address of a GstBuffer
1906 * pointer variable to store the result into
1908 * Copies the first buffer for the given tag in the taglist into the variable
1909 * pointed to by @value. Free the buffer with gst_buffer_unref() when it is
1912 * Free-function: gst_buffer_unref
1914 * Returns: TRUE, if a buffer was copied, FALSE if the tag didn't exist in the
1915 * given list or if it was #NULL.
1920 gst_tag_list_get_buffer (const GstTagList * list, const gchar * tag,
1925 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1926 g_return_val_if_fail (tag != NULL, FALSE);
1927 g_return_val_if_fail (value != NULL, FALSE);
1929 if (!gst_tag_list_copy_value (&v, list, tag))
1931 *value = g_value_dup_boxed (&v);
1933 return (*value != NULL);
1937 * gst_tag_list_get_buffer_index:
1938 * @list: a #GstTagList to get the tag from
1939 * @tag: tag to read out
1940 * @index: number of entry to read out
1941 * @value: (out callee-allocates) (transfer full): address of a GstBuffer
1942 * pointer variable to store the result into
1944 * Gets the buffer that is at the given index for the given tag in the given
1945 * list and copies it into the variable pointed to by @value. Free the buffer
1946 * with gst_buffer_unref() when it is no longer needed.
1948 * Free-function: gst_buffer_unref
1950 * Returns: TRUE, if a buffer was copied, FALSE if the tag didn't exist in the
1951 * given list or if it was #NULL.
1956 gst_tag_list_get_buffer_index (const GstTagList * list,
1957 const gchar * tag, guint index, GstBuffer ** value)
1961 g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
1962 g_return_val_if_fail (tag != NULL, FALSE);
1963 g_return_val_if_fail (value != NULL, FALSE);
1965 if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
1967 *value = g_value_dup_boxed (v);
1968 return (*value != NULL);